More Cowbells (Take #3)
In the immortal words of Christopher Walken, "I've got a fever, and the only prescription is more cowbells." So here are one or two more that are included in the latest version of CongoCC.
As you no doubt know Congo has built-in ways to painlessly build an Abstract Syntax Tree (or AST" for rest of this blog entry). It is sometimes the case that you need to record references to the tokens and non-terminal productions matched during the parsing of a grammar production. This is easily accomplished using the facilities in CongoCC. You might do something like this, for example.
FooBar :
{
Token foo = null;
}
foo = "foo" {CURRENT_NODE.setFoo(foo);}
| "bar" #Bar {CURRENT_NODE.setBar((Bar)peekNode());}
| Baz {CURRENT_NODE.setBaz((Baz)peekNode());}
;
INJECT FooBar :
{
@Property Token foo;
@Property Bar bar;
@Property Baz baz;
}
Baz : "baz";
This example makes use of CongoCC's features of CURRENT_NODE
to refer to the current AST node being built by the parser and the (originally JJTree) #
annotation feature to specify the creation of an AST node wrapping a variable number of "in progress" child nodes (in this case all of them by default). But you can now do this in the following way with the same effect.
FooBar : @foo = "foo" | "bar" @bar = #Bar | @baz = Baz;
...
As you can see, the wordy, visibly cluttered action code has been replaced by the use of existing CongoCC syntax that allows assignment of a reference to any token or non-terminal node being built, even if the return type is void
, and to define properties (@Property
) within INJECT
ions into generated AST nodes. Additionally, using new experimental features of CongoCC, it includes the specification of an assignment (in this case an @Property
assignment) applied to a tree-node annotation (#Bar
)and a simplified syntax for applying that assignment to a property defined in the AST node within which the assignment is made (@foo
, @bar
, @baz
).
Now the new ability to assign the value of inline AST annotations and the @propertyName
syntax is available for all of CongoCC's target languages. Additionally, you don't have to define the properties in an INJECT
ion for the node, it can be automatically done for you. In the event you wish to automatically include the property(ies) you can do so by using a :=
following the name of the property. For example:
FooBar : @foo = "foo" | "bar" @bar := #Bar | @baz := Baz
...
In this case, the foo
property will not be injected into the FooBar
node, so it will have to be manually done via INJECT
, or its setter will have to be visible in a superclass of FooBar. The bar
and baz
properties will be automatically injected into the FooBar
node without any other action needed, however.
So, enjoy, turn up the volume to 11, and Don't Fear the Reaper!