// arith.cc // driver program for arithmetic evaluator #include "arith.h" // this module #include "glr.h" // GLR parser #include "ptreenode.h" // PTreeNode #include "ptreeact.h" // ParseTreeLexer, ParseTreeActions #include "trace.h" // traceAddSys #include // assert // ------------------ ArithLexer ------------------ /*static*/ void ArithLexer::nextToken(ArithLexer *ths) { // call underlying lexer; it will set 'sval' if necessary ths->type = yylex(); } LexerInterface::NextTokenFunc ArithLexer::getTokenFunc() const { return (NextTokenFunc)&ArithLexer::nextToken; } char const *toString(ArithTokenCodes code) { char const * const names[] = { "EOF", "number", "+", "-", "*", "/", "(", ")", }; assert((unsigned)code < sizeof(names) / sizeof(names[0])); return names[code]; } string ArithLexer::tokenDesc() const { if (type == TOK_NUMBER) { return stringc << "number(" << (int)sval << ")"; } else { return toString((ArithTokenCodes)type); } } string ArithLexer::tokenKindDesc(int kind) const { return toString((ArithTokenCodes)kind); } // --------------------- main ---------------------- ArithLexer lexer; int main(int argc) { // initialize lexer by grabbing first token lexer.nextToken(&lexer); // create parser; actions and tables not dealloc'd but who cares Arith *arith = new Arith; ParseTables *tables = arith->makeTables(); // uncomment this to get bison-like shift/reduce reports //traceAddSys("parse"); // get tracing info from environment variable TRACE traceAddFromEnvVar(); if (argc == 1) { // start parsing GLR glr(arith, tables); SemanticValue result; if (!glr.glrParse(lexer, result)) { printf("parse error\n"); return 2; } // print result printf("result: %d\n", (int)result); } else { // make it print a parse tree instead of evaluating the expression ParseTreeLexer ptlexer(&lexer, arith); ParseTreeActions ptact(arith, tables); GLR glr(&ptact, tables); SemanticValue result; if (!glr.glrParse(ptlexer, result)) { printf("parse error\n"); return 2; } // print the tree PTreeNode *ptn = (PTreeNode*)result; ptn->printTree(cout, PTreeNode::PF_EXPAND); } return 0; }