ANTLR - Writing a tree grammar for an AST
I have an AST outputted for some Lua code by my grammar file, which currently does parsing and lexing for me. I want to add a tree grammar to this, but since i'm using C# i'm not sure how to do it. What's the basic process for generating tree grammar 开发者_如何学运维code when you already have a parser and lexer written?
UPDATE: I have the following grammar file:
tree grammar LuaGrammar;
options {
backtrack=true;
language=CSharp2;
//output=AST;
tokenVocab=Lua;
filter=true;
ASTLabelType=CommonTree;
}
@lexer::namespace{/*my namespace*/}
@parser::namespace{/*my namespace*/}
dummyRule
: ^('=' x=. y=.) {};
placed in the same directory as my main grammar file, which generates fine. However, when trying to compile this i get the following errors:
[02:54:06] error(143): C:\Users\RCIX\Desktop\AguaLua\Project\trunk\AguaLua\AguaLua\ANTLR Data\LuaGrammar.g:12:18: unknown or invalid action scope for tree grammar: lexer
[02:54:06] error(143): C:\Users\RCIX\Desktop\AguaLua\Project\trunk\AguaLua\AguaLua\ANTLR Data\LuaGrammar.g:13:19: unknown or invalid action scope for tree grammar: parser
Am i on the right track or totally off?
Well going back to my usual example of a calculator grammar:)
This is how you would declare your Tree Walker class
class CalcTreeShaker extends TreeParser;
expr returns [float r]
{
float a,b;
r=0;
}
: #(PLUS a=expr b=expr) {r = a+b;}
| #(STAR a=expr b=expr) {r = a*b;}
| i:INT {r = Convert.ToSingle(i.getText());}
;
Here we have a tree rule called expr
. Tree walkers are very similar to parser grammars.
The big difference is that while a parser grammar has to match exactly a tree grammar only has to match a portion of the tree.
In the expr
rule we can see it matches any tree that has the tokens PLUS
or STAR
or INT
.
We can see we are matching trees because we are using Antlr's Tree syntax #(...)
.
The PLUS
and STAR
tree's also match 2 expr rules. Each expr rule is assigned to a name so we can use it to evaluate the expression. Similar to parser grammars we can put C# code into blocks defiend by {...}
.
Also note that in this example we show how to return a value from a TreeWalker rule, we use the syntax return [...]
.
To call the tree walker you create it and then call it's top level rule. I"ll copy this from the Antlr example:)
// Get the ast from your parser.
CommonAST t = (CommonAST)parser.getAST();
// Create the Tree Shaker
CalcTreeWalker walker = new CalcTreeWalker();
CalcParser.initializeASTFactory(walker.getASTFactory());
// pass the ast to the walker and call the top level rule.
float r = walker.expr(t);
I have not encountered this error but there are 2 things I would try.
1) remove the @lexer and @parser namespace lines.
2) If they are necessary then move them until after the Tokens {...} section of your grammar, ie just before the rules.
精彩评论