views:

744

answers:

2

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?

+1  A: 

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);
chollida
That is very helpful but at this point i'm trying to get a valid file which i can persuade ANTLR to compile into some code, maybe i'm missing something...
RCIX
+1  A: 

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.

chollida
Ok, but you can edit in your new information :) I probably need to find the equivalent statement for tree grammar rules...
RCIX
1) fixed it, i'll muddle along from here :)
RCIX