I am trying to use the ANTLR3 C Target to understand AST, but I am encountering some difficulties.
I have a simple SQL-like grammar file:
grammar sql; options { language = C; output=AST; ASTLabelType=pANTLR3_BASE_TREE; } sql : VERB fields; fields : FIELD (',' FIELD)*; VERB : 'SELECT' | 'UPDATE' | 'INSERT'; FIELD : CHAR+; fragment CHAR : 'a'..'z';
and it works as expected at ANTLRWorks.
In my C code, I have:
const char pInput[] = "SELECT one,two,three"; pANTLR3_INPUT_STREAM pNewStrm = antlr3NewAsciiStringInPlaceStream((pANTLR3_UINT8) pInput,sizeof(pInput),NULL); psqlLexer lex = sqlLexerNew (pNewStrm); pANTLR3_COMMON_TOKEN_STREAM tstream = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lex)); psqlParser ps = sqlParserNew( tstream ); sqlParser_sql_return ret = ps->sql(ps); pANTLR3_BASE_TREE pTree = ret.tree; cout << "Tree: " << pTree->toStringTree(pTree)->chars << endl; ParseSubTree(0,pTree);
This displays a flat tree structure when you use ->getChildCount and ->children->get for recursion through the tree.
void ParseSubTree(int level,pANTLR3_BASE_TREE pTree) { ANTLR3_UINT32 childcount = pTree->getChildCount(pTree); for (int i=0;i<childcount;i++) { pANTLR3_BASE_TREE pChild = (pANTLR3_BASE_TREE) pTree->children->get(pTree->children,i); for (int j=0;j<level;j++) { std::cout << " - "; } std::cout << pChild->getText(pChild)->chars << std::endl; int f=pChild->getChildCount(pChild); if (f>0) { ParseSubTree(level+1,pChild); } } }
Program output: Tree: SELECT one, two, three SELECT one, two, three
Now, if I modify the grammar file:
sql : VERB ^fields;
.. The call to ParseSubTree displays only the child nodes of the fields.
Program output: Tree: (SELECT one, two, three) one, two, three
My question is: why in the second case, Antlr just gives child nodes? (actually skipping the SELECT token) I would be very grateful if someone could give me any instructions to understand the tree returned by Antlr.
Useful information: AntlrWorks 1.4.2, Antlr C Target 3.3, MSVC 10