Parsing Predecesors
In some programming languages, there are constructs that attach additional information to existing AST (Abstract Syntax Tree) nodes instead of creating new ones. For example, in Java, annotations can be used to add extra information to classes and methods. Similarly, modifiers indicate to the compiler how a method or class can be accessed.
In this guide you will learn how to parse a java like annotation. An example implementation of this language feature can be found in the FuncSample.
The Syntax
We wanna implement annotations like in java so we want to parse something like this:
We have to cover two cases. An annotation with and without arguments. You see annotations look like normal function calls or names but with @ as predecessor. Many language constructs can be implemented by composing old language constructs or reusing them.
The implementation
To implement this functionality we can write our own parselet by implementing the IPrefixParselet interface.
AnnotatedNode is a subclass of AstNode with an extra Property Annotations. All nodes that can be annotated have to inherit from it instead of AstNode.
Don't forget to register our new parselet to the parser:
Explanation
Parse something like a name or function call
Parse a expression we wanna annotate
Add the call as annotation to the ast node
Return the annotated expression
We do not explicitly handle multiple annotations, but why does it still work? This is because an annotation itself is treated as an expression, and instead of returning a new type of AST node, we simply reuse the existing one. So, when we parse the example, we look for an annotation. If the following expression is also an annotation, it gets added to the same node.
Last updated