CTD files describe the expected composition of test data files using a small grammar. One line of input consisting of two small integers separated by space is specified like this:
| CTD | Accept | Reject | Reject | Reject | Reject | Reject | Reject | Reject |
|---|---|---|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
Note the first two rejected examples; these may be hard to see.
If we use “␠” and “” to show the normally invisble space and newline characters then these two examples would be 4␠␠6 and ␠4␠6, respectively.
Both are rejected by the CTD script, as are 4␠6␠ and 4␠6␠.
On the other hand, CTD-files themselves are whitespace-agnostic, so the above is the same as
INT(1, 10) SPACE INT(1, 10) NEWLINE
but different from requiring exactly two spaces between the integers:
INT(1, 10) SPACE SPACE INT(1, 10) NEWLINE
The above script accepts 4␠␠6 but rejects 4␠6.
INT(min, max, name) takes an optional third argument that assigns the matched integer to a variable name.
Variable names consist of lower case alphanumeric characters a0, or integer-indexed array entries like a[2].
You can also use variable and expressions for the first two arguments of INT:
INT(1, 9, a) SPACE INT(a + 1, 10) NEWLINE # specify 1 <= a < b <= 10
# starts a comment.
Keywords like INT(min, max) and SPACE match characters in the input.
Others express constraints. To specify that the two integers must be different, use ASSERT:
| CTD | Accept | Reject |
|---|---|---|
|
|
|
You can write ASSERT (x < y) or even ASSERT (x < y || x > y && x == 3).
Number representations are picky about redundant initial 0s and signs.
| CTD | Accept | Accept | Reject | Reject | Reject |
|---|---|---|---|---|---|
INT(-10,10) |
10 |
-10 |
010 |
10.0 |
+10 |
| CTD | Acc | Acc | Acc | Acc | Acc | Acc | Rej | Rej | Rej |
|---|---|---|---|---|---|---|---|---|---|
FLOAT(5.5, 10) |
10 |
10.0 |
5.50 |
1e1 |
1e+1 |
1E1 |
10. |
5.4 |
+1e1 |
Use FLOAT(min, max, FIXED) to insist on fixed-point notation (i.e., disallowing scientific notation like 1e1).
FLOATP(min, max, mindecimals, maxdecimals) specifies the number of decimals.
An exact string is matched as
STRING("hello") NEWLINE
More generally, strings are matched with regular expressions:
REGEX("yes|no") NEWLINE
Matches can be assigned to variables, which can occur in assertions; STRLEN gives the length of a named string.
| CTD | Accept | Reject | Reject |
|---|---|---|---|
|
|
|
|
Strings can be compared lexicographically:
| CTD | Accept | Accept | Reject |
|---|---|---|---|
|
|
|
|
Check either an integer or the word impossible:
| CTD | Accept | Accept | Reject |
|---|---|---|---|
|
|
|
|
The else-branch is optional, we could also do
IF (MATCH("i")) # conditions in brackets
STRING("impossible")
END
IF (MATCH("123456789")) # match any of the characters
INT(1,100)
END
NEWLINE
The input consists of
- one line with an integer
$n$ ($1 \leq n \leq 100$ ), the number of lines -
$n$ lines, each consisting of two different integers$x$ ,$y$
| CTD | Accept | Reject |
|---|---|---|
|
|
|
An optional second argument to REP defines a separation character between matches. To specify
- one line with an integer n (
$1 \leq n \leq 100$ ), the number of measurements - one line with
$n$ measurements, each between 10 and 20 inclusive:
| CTD | Accept | Reject |
|---|---|---|
|
|
|
Variables can form arrays, and arrays allow membership and uniqueness tests.
Here we check that the first number appears among following five numbers.
The REPI ... END part matches a line 5 integers and assigns p[0], ..., p[4] to them.
Together these variables form an array variable called p.
INARRAY then performs the membeship test.
| CTD | Accept | Reject |
|---|---|---|
|
|
|
Use UNIQUE to ensure that all elements in an array are different. Here we check for two permutations.
| CTD | Accept | Reject | Reject |
|---|---|---|---|
|
|
|
|
The UNIQUE constraint checks that the entries of its argument are unique.
UNIQUE can take several arrays. With UNIQUE
| CTD | Accept | Reject |
|---|---|---|
|
|
|