[antlr-interest] Problems with treeParser in V2 with c++ target
Joachim Mårtensson
joachimm at etek.chalmers.se
Mon May 7 12:55:44 PDT 2007
Hello,
I am trying to learn how to use Antlr with C++ as a target, and I thought
I should try out something relatively easy. Basically I thought I should
extend the calc example in the cpp folder to work like the expression
parser in the Antlr (beta) book, however I am running into problems.
$./out "(4+5*8);"
( + 4 ( * 5 8 ) )
<AST>: unexpected AST node: 4
expr:0value is 0 <- my debug output
I find this hard to figure out, I am guessing that I am setting up the
ParseTree in the wrong way or something but I cannot figure out how.
Thanks in advance
Joachim
my treeGrammar file looks like this.
header
{
#include <map>;
#include <string>;
#include <iostream>;
}
options {
language="Cpp";
}
class CalcTreeWalker extends TreeParser;
{
public:
std::map<std::string, double> idMem;
}
prog returns [double ret]
{
ret = 0.0;
double total = 0;
}
: (total = stat {ret += total;})+ ;
stat returns [double st]
{
st = 0;
}
: #(ASSIGN c:ID st = expr) { idMem[c->getText()]= st;}
| st = expr { std::cout << "expr:"<< st;} ;
expr returns [double r]
{
double a,b;
r=0;
}
: #(PLUS a=expr b=expr) {r = a+b;}
| #(MINUS a=expr b=expr) {r = a-b;}
| #(STAR a=expr b=expr) {r = a*b;}
| i:INT {r = atof(i->getText().c_str());}
| k:ID {if (idMem.count(k->getText()) > 0) r = idMem[k->getText()];
else r = 0;}
;
-------------
and the Parser and Lexer looks like this.
-------------
options {
language="Cpp";
}
class CalcParser extends Parser;
options {
//genHashLines = true; // include line number information
buildAST = true; // uses CommonAST by default
k = 2;
}
prog: (stat)+ ;
stat: expr SEMI!
| ID ASSIGN^ expr SEMI! ;
expr
: mexpr ((PLUS^|MINUS^) mexpr)*
;
mexpr
: atom (STAR^ atom)*
;
atom: INT
| ID
| LPAREN! expr RPAREN!
;
class CalcLexer extends Lexer;
WS_ : (' '
| '\t'
| '\n'
| '\r')
{ _ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; }
;
LPAREN: '('
;
RPAREN: ')'
;
LBRACKET: '[' ;
RBRACKET: ']' ;
ASSIGN: '=' ;
STAR: '*'
;
ID
: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
;
STRING_LITERAL : '"' (~'"')* '"' ;
MINUS: '-' ;
PLUS: '+'
;
SEMI: ';'
;
protected
DIGIT
: '0'..'9'
;
INT : (DIGIT)+
;
-------------------
I use the following code to set up the parser and tree. (almost identical
to the Main file in the cpp/calc example folder)
-------------------
/* Calculate an expression read from stdin or from the arguments passed to
* the program (using stringstream's)
*/
#include <iostream>
#include <sstream>
#include <map>;
#include "antlr/AST.hpp"
#include "CalcLexer.hpp"
#include "CalcParser.hpp"
#include "CalcTreeWalker.hpp"
int main( int argc, char* argv[] )
{
ANTLR_USING_NAMESPACE(std)
ANTLR_USING_NAMESPACE(antlr)
try
{
ostringstream expr;
istringstream input_string;
istream *input = &cin;
const char *filename = "<cin>";
if( argc > 1 )
{
// write the argv strings to a ostringstream...
for( int i = 1; i < argc; i++ )
{
if( i > 1 && i != (argc-1))
expr << ' ';
expr << argv[i];
}
input_string.str(expr.str());
input = &input_string;
filename = "<arguments>";
}
CalcLexer lexer(*input);
lexer.setFilename(filename);
CalcParser parser(lexer);
parser.setFilename(filename);
ASTFactory ast_factory;
parser.initializeASTFactory(ast_factory);
parser.setASTFactory(&ast_factory);
// Parse the input expression
parser.prog();
RefAST t = parser.getAST();
if( t )
{
// Print the resulting tree out in LISP notation
cout << t->toStringTree() << endl;
CalcTreeWalker walker;
// Traverse the tree created by the parser
walker.initializeASTFactory(ast_factory);
walker.setASTFactory(&ast_factory);
double r = walker.prog(t);
for(map<string, double>::const_iterator it =
walker.idMem.begin(); it != walker.idMem.end(); ++it)
{
cout << "first: " << it->first << "second:\t" <<
it->second << endl;
}
cout << "value is " << r << endl;
}
else
cout << "No tree produced" << endl;
}
catch(ANTLRException& e)
{
cerr << "Parse exception: " << e.toString() << endl;
return -1;
}
catch(exception& e)
{
cerr << "exception: " << e.what() << endl;
return -1;
}
return 0;
}
More information about the antlr-interest
mailing list