Before getting started with your syntax definition, you set up a test suite for syntax analysis. Develop the test suite in tandem with the development of your syntax definition. The test suite consists of positive and negative test cases. We will not grade this test suite, but you should develop one to get confidence in the quality of your syntax definition. When you are asking for help from the course staff, we will first ask what tests you have written to demonstrate the problem.
In the chocopy.syntax.test
project, develop a test suite for syntax analysis.
The test suite should provide
Program
sortIn Spoofax, a test suite consists of one or more .spt
files.
Consider the following example file:
module example
language chocopy
start symbol Program
test FUN composite [[func(1+1, 3*2)]] parse succeeds
test FUN only comma [[func(,)]] parse fails
The first lines specify
the name of the test module
,
the language
under test,
and the start symbol
used for a test.
In this example
module, we like to test sort INT
of the ChocoPy
language.
The last two lines specify a positive and a negative test case. Each test case consists of a name, a code fragment in double square brackets, and a condition which determines what kind of test should be performed (parsing) and what the expected outcome is (success or failure).
You get instant feedback while editing a test suite. Since you have not yet implemented the ChocoPy editor, all your positive test cases fail. You will work on this during the next lab. To read more on SPT, visit the documentation.
To write your own test cases, you need to understand ChocoPy’s syntax. You can find the definitive ChocoPy syntax definition in the Reference Manual.
You can now start writing your own test cases.
Start with the lexical syntax and think about valid and invalid identifiers. Try to focus on corner cases such as
The content for the tests for lexical symbols should not be surrounded by layout.
Next, you should walk through the whole syntax definition. Keep thinking of valid and invalid code fragments. Identify interesting corner cases and turn them into positive and negative test cases.
Try to keep your test cases small. Each test case should focus on a single aspect. For example, a negative test case should only contain one error. The name of a test case should reflect the aspect it addresses.
You can organise test cases which focus on similar aspects in test modules. Again, the name of a test module should reflect these aspects. Finally, you can organise test suites in folders.
When writing tests that target the differences between Python and ChocoPy, only consider the syntactic differences. For example, identifiers in Java are limited to a certain size. This should not be checked by your tests as this limitation is not specified in the context-free grammar of Java.
Next, you need to focus on disambiguation. Come up with positive test cases which specify the correct ASTs for nested expressions. As an alternative, you can also specify two fragments in concrete syntax, which should result in the same AST:
test left associative addition [[21 + 14 + 14]] parse to [[(21 + 14) + 14]]
You can find a table listing the associativity and priorities of operators in the reference manual. Do not focus only on binary expressions.
You do not have to test for constructs that are non-associative. In lab 2, with the java
parse table generation enabled, non-assoc
leads to semantic errors rather than syntactic errors during parse time. Since our language does not have analysis at that point, we cannot test the semantic errors and thus they are also not required for this lab.
Finally, you can focus on layout. Think about places where whitespace is not optional but mandatory and define corresponding positive and negative test cases. Finish with test cases for single-line comments. Single-line comments cannot only end with a newline character, but also at the end of file.