Hello,
Yes this is a very long time that I did not post anything... I recently had to make an interpreter (in swift) of quite simple expression. I thought of reusing it in some C# programs. My first thought were immediately to ANTLR (which I used in Java few years ago). My second thought was to use Lemon, in C, it would have worked with swift because of Objective-C but I could not have used it in C# (please no interop).
I really advise the plugin in Intellij, it was so easy to use: right click on the rule you want to test...
expr: '(' e=expr ')' # paren
| name=KEYWORD '(' expr (',' expr)* ')' # fun
| left=expr op=('*' | '/') right=expr # mul
| left=expr op=('+' | '-') right=expr # add
| VARIABLE # variable
| DECIMAL # decimal
| INT # int
| STRING # string
| # empty
;
fragment LETTER: [a-zA-Z];
fragment DIGIT: [0-9];
VARIABLE: '[' LETTER+(LETTER | DIGIT)* '.' LETTER+(LETTER | DIGIT)* ']';
STRING : '"' ~('"')* '"';
INT : DIGIT+;
DECIMAL : DIGIT*'.'DIGIT+;
KEYWORD : LETTER+(LETTER | DIGIT)*;
and the program to parse a string would be (in kotlin):
val expression = "=coucou(12,23,34,56)"
val stream: CharStream = CharStreams.fromString(expression)
val lexer = MobiExprLexer(stream)
val tokenStream: TokenStream = CommonTokenStream(lexer)
val parser = MyExprParser(tokenStream)
val tree: ParseTree = parser.prog()
val result: Int = MyInterpreter().visit(tree)
println(result)
An interesting thing is that we use a visitor to interpret the AST
and here below how we can retrieve all parameters of a function:
here the rule as reminder: | name=KEYWORD '(' expr (',' expr)* ')' # fun
class MyInterpreter : MyExprBaseVisitor<Int>() {
override fun visitFun(ctx: FunContext): Int {
// expr() will be a list of all expr nodes, meaning all parameters
val params = ctx.expr().map { visit(it) }
// once we visit each of them, we now have the values to interpret the function
...
}
}
For those who were wondering, I now think that it is better to discouple the grammar from the implementation, it is allowing the grammar to be reused in multiple languages.
I personally also enjoyed doing some kotlin again :-)
Hope it was useful for you.
See you