Showing posts with label antlr. Show all posts
Showing posts with label antlr. Show all posts

Friday, January 07, 2011

For Loop Compiled

Made a pass today at updating the tree grammar for the Ctrl to include a description of the for loop AST structure. The structure of the tree was pretty much copied verbatim from the parser grammar, with a few minor tweaks. ANTLR uses the same notation for both types of grammars so tree structures are easily ported between the two.

During tree traversal, while visiting a node in the tree, the tree walker executes an "action". In our tree walker, an action is a transformation step that goes from AST to an instance of a Java object from our Ctrl model. The action essentially takes node values from the AST and copies them into a RuleStatement. This is what Ctrl compilation comes down to. A few getters and setters were missing, so I added these as well as toString() implementations to all of the Java classes in the model supporting the for loop.

I took a screenshot of my debugging session. The breakpoint in the screenshot is set in my TestRig. Whenever the grammars are touched, I run the TestRig. It is a suite of tests that compiles a wide range of statements in the Ctrl, from simple one-liners, to complex multi-line if-then-else statements.



We are in good shape so far. The screenshot shows a compiled RuleStatement object that contains an initialized ForStatement, in the "Variables" view of the debugger.

Wednesday, January 05, 2011

For Loop Redux

Added several new elements to the ANTLR grammar for the Ctrl today. With these additions, the ANTLR-generated parser recognizes a for loop from the following basic syntax:
for (int i = 0; i < 10; i++) {
  ...
}
We need a for loop in our language to allow blocks of code to be executed repeatedly for some iteration within the context of a rule. This basic loop declares a counter to control the number of iterations and to expose the counter's value to the code inside the loop. As with for loops in other programming languages, the Ctrl loop has a loop-test declaration, i < 10, which may be any type of conditional expression that evaluates to a boolean value to stop the loop when the expression evaluates to false.

A few simple tests against the new grammar rules that recognize this basic loop are good so far.

Out of curiosity, I looked up the Wikipedia entry for for loop. The article includes a flowchart diagram of a for loop's behavior at run time:



During my syntax tests today, and to my delight, I discovered that the parser recognizes another for loop or an entirely different statement where D appears in the diagram above, that is, it recognizes a full statement nested inside the body of the loop. For example, the parser also reads statements like this without any fuss:
for (int i = 0; i < 10; i++) {
  if (color == 'blue') {
    for (int p = 0; p < 20; p++) { 
       ... // and so on
    }
  }
}
This means that if statements inside for loops and for loops inside if statements are syntactically valid constructs in Ctrl which was entirely unintentional side effect of the grammar changes.

Even though nested statements are not yet in the immediate requirements that I'm addressing with these changes, I think they provide the Ctrl with great expressive power so I'm definitely going to leave this feature in the grammar.

The other noteworthy observation about the changes in the grammar is that the abstract syntax trees built by the ANTLR-generated parser are composed from succinct little subtrees that come out of applying the new grammar rules to a statement. The example above is translated by the parser into a tree with a two-dimensional structure shown below. The tree was drawn for me courtesy of ANTLRWorks and shows how the statement breaks down syntactically:



Tomorrow's task will be to add rules to the ANTLR TreeWalker to traverse and to translate a tree like this into an instance of a RuleStatement in the Content Type Rule Language Java model, which is what the Ctrl compiles to.