Makefile100644 1040 1001 2611 6742212140 10707 0ustar everyone CC = cl LD = link DEBUG = -Zi # Compile try/except EXCEPT = -EHsc CFLAGS = $(EXCEPT) -DWIN32 -Tp OBJ = obj EXE = .exe INCLUDE = -I "e:\antlr\cpp" -I "d:\Program Files\Microsoft Visual Studio\Vc98\include" LD_DEBUG = /debug ANTLR_LIB = /defaultlib:"e:\antlr\cpp\antlr.lib" LINK_FLAGS = $(LD_DEBUG) $(ANTLR_LIB) FLAGS = $(INCLUDE) $(DEBUG) $(CFLAGS) # # To customize, fill in EXENAME, GRAMMAR, PARSER and LEXER # EXENAME = expr GRAMMAR = expr PARSER = MyExpr LEXER = MyExpr PARSE_OBJ = $(LEXER)Lexer.$(OBJ) $(PARSER)Parser.$(OBJ) print_tree.$(OBJ) main.$(OBJ) all: $(EXENAME)$(EXE) clean: rm -f $(PARSE_OBJ) $(EXENAME)$(EXE) $(PARSER)Parser.cpp $(PARSER)Parser.hpp $(LEXER)Lexer.cpp $(LEXER)Lexer.hpp $(LEXER)TokenTypes.hpp $(LEXER)TokenTypes.txt $(EXENAME)$(EXE): $(PARSE_OBJ) $(LD) $(LINK_FLAGS) /out:$@ $(PARSE_OBJ) $(LEXER)Lexer.cpp $(LEXER)Lexer.hpp $(PARSER)Parser.cpp $(PARSER)Parser.hpp: $(GRAMMAR).g jview antlr.Tool $(GRAMMAR).g $(LEXER)Lexer.$(OBJ): $(LEXER)Lexer.cpp $(LEXER)Lexer.hpp $(CC) -c $(FLAGS) $(LEXER)Lexer.cpp $(PARSER)Parser.$(OBJ): $(PARSER)Parser.cpp $(PARSER)Parser.hpp $(CC) -c $(FLAGS) $(PARSER)Parser.cpp print_tree.$(OBJ): print_tree.cpp print_tree.hpp $(CC) -c $(FLAGS) print_tree.cpp main.$(OBJ): main.cpp $(PARSER)Parser.hpp $(LEXER)Lexer.hpp $(CC) -c $(FLAGS) main.cpp expr.g100644 1040 1001 5535 6735540500 10413 0ustar everyone // // An experimental expression grammer by // Ian Kaplan // options { language="Cpp"; } class MyExprParser extends Parser; options { k = 2; exportVocab=MyExpr; buildAST = true; // defaultErrorHandler = true; // Don't generate parser error handlers } exprlist : ( assignment_statement )* EOF! ; assignment_statement : assignment SEMICOLON! ; assignment : (IDENT ASSIGN^ )? expr ; primary_expr : IDENT | constant | (LPAREN! expr RPAREN! ) ; boolneg_expr : ( "not" )* primary_expr ; sign_expr : (MINUS)? boolneg_expr ; mul_expr : sign_expr (( TIMES^ | DIVIDE^ | MOD^ ) sign_expr)* ; add_expr : mul_expr (( PLUS^ | MINUS^ ) mul_expr)* ; shift_expr : add_expr ( shiftop add_expr )* ; rel_expr : shift_expr (relop shift_expr)* ; eq_expr : rel_expr (eqop rel_expr)* ; lmul_expr : eq_expr ( "and" eq_expr )* ; expr : lmul_expr ("or" lmul_expr)* ; constant : (ICON | CHCON) ; relop : ( LTHAN | GTHAN | GEQ | LEQ ) ; eqop : ( EQ | NEQ ) ; shiftop : ( SHIFT_LEFT | SHIFT_RIGHT ) ; class MyExprLexer extends Lexer; options { k = 2; exportVocab=MyExpr; } WS_ : (' ' | '\t' | '\n' | '\r') { _ttype = Token::SKIP; } ; IDENT options { paraphrase = "identifier"; } : ('a'..'z' | 'A'..'Z' | '_' ) ( ('a'..'z' | 'A'..'Z' | '_') | ('0'..'9' ))* ; ICON options { paraphrase = "integer constant"; } : '0'..'9' ('0'..'9')* ; CHCON options { paraphrase = "character constant"; } : "'" '\0'..'\255' "'" ; COMMA options { paraphrase = ","; } : ',' ; SEMICOLON options { paraphrase = ";"; } : ';' ; LPAREN options { paraphrase = "("; } : '(' ; RPAREN options { paraphrase = ")"; } : ')' ; LCURL options { paraphrase = "{"; } : '{' ; RCURL options { paraphrase = "}"; } : '}' ; PLUS options { paraphrase = "+"; } : '+' ; MINUS options { paraphrase = "-"; } : '-' ; TIMES options { paraphrase = "*"; } : '*' ; DIVIDE options { paraphrase = "/"; } : '/' ; MOD options { paraphrase = "%"; } : '%' ; ASSIGN options { paraphrase = "="; } : '=' ; EQ options { paraphrase = "=="; } : "==" ; NEQ options { paraphrase = "!="; } : "!=" ; LTHAN options { paraphrase = "<"; } : '<' ; GTHAN options { paraphrase = ">"; } : '>' ; LEQ options { paraphrase = "<="; } : "<=" ; GEQ options { paraphrase = ">="; } : ">=" ; SHIFT_LEFT options { paraphrase = "<<"; } : "<<" ; SHIFT_RIGHT options { paraphrase = ">>"; } : ">>" ; main.cpp100644 1040 1001 2456 6742210351 10710 0ustar everyone #include #include #include #include "MyExprLexer.hpp" #include "MyExprParser.hpp" #include "print_tree.hpp" void indent(int indent_level) { if (indent_level > 0) { const size_t BUFSIZE = 127; char buf[ BUFSIZE+1 ]; int i; for (i = 0; i < indent_level && i < BUFSIZE; i++) { buf[i] = ' '; } buf[i] = '\0'; printf("%s", buf ); } } // pr_indent void trav_tree( RefAST top, int ind ) { if (top != NULL) { std::string str; indent( ind ); str = top->getText(); std::cout << str << "\n"; if (top->getFirstChild() != NULL) { printf("kid: "); trav_tree( top->getFirstChild(), ind+2 ); } if (top->getNextSibling()) { printf("sib: "); trav_tree( top->getNextSibling(), ind ); } } } int main() { printf("Ursine expression parser, version 1.0\n"); try { MyExprLexer lexer(std::cin); MyExprParser parser(lexer); parser.exprlist(); print_tree pr; if (parser.getAST() != NULL) { printf("AST print:\n"); pr.pr_tree( parser.getAST() ); printf("tree traverse:\n"); trav_tree( parser.getAST(), 0 ); } } catch(std::exception& e) { std::cerr << "exception: " << e.what() << std::endl; } return 0; } print_tree.cpp100644 1040 1001 4030 6742211363 12131 0ustar everyone #include #include #include "MyExprParser.hpp" #include "print_tree.hpp" /* * pr_name * Print the character string associated with an ANTLR tree node. */ void print_tree::pr_name( RefAST node ) { std::string str; str = node->getText(); printf("%s ", str.c_str()); } // pr_name /* * pr_indent * Print indentation for a node. */ void print_tree::pr_indent(void) { const size_t BUFSIZE = 127; char buf[ BUFSIZE+1 ]; int i; for (i = 0; i < indent_level && i < BUFSIZE; i++) { buf[i] = ' '; } buf[i] = '\0'; printf("%s", buf ); } // pr_indent void print_tree::pr_open_angle(void) { if ( indent_level ) printf("\n"); pr_indent(); printf("<"); indent_level += INDENT; } // pr_open_angle /* * pr_close_angle * Print the ">" bracket to show the close of a tree production. */ void print_tree::pr_close_angle(Boolean first) { assert( indent_level > 0 ); indent_level -= INDENT; if (!first) { printf("\n"); pr_indent(); } printf(">"); } // pr_close_angle /* * pr_leaves * Print the leaves of an AST node */ void print_tree::pr_leaves( RefAST top ) { RefAST t; For_each_kid(t, top) { if (is_nonleaf( t )) pr_top( t ); else pr_name( t ); } } // pr_leaves /* * pr_top * Recursively print a tree (or a sub-tree) from the top down. */ void print_tree::pr_top( RefAST top ) { RefAST tmp; Boolean first = TRUE; pr_open_angle(); pr_name( top ); if (is_nonleaf( top )) { For_each_kid( tmp, top ) { if (is_nonleaf( tmp )) first = FALSE; } pr_leaves( top ); } pr_close_angle( first ); } // pr_top /* * pr_tree * Main entry point for tree print. */ void print_tree::pr_tree( RefAST top ) { RefAST t; for (t = top; t != NULL; t = t->getNextSibling()) { indent_level = 0; pr_top( t ); printf("\n"); } } // pr_tree print_tree.hpp100644 1040 1001 1513 6742210717 12143 0ustar everyone #ifndef _PRINT_TREE_HPP_ #define _PRINT_TREE_HPP_ /* print_tree Print an ANTLR abstract syntax tree in operator prefix form. */ typedef enum { FALSE = 0, TRUE = 1 } Boolean; #define For_each_kid(t,top) for(t=( (top && is_nonleaf(top)) ? top->getFirstChild() : (RefAST)NULL ); t; t = t->getNextSibling() ) class print_tree { private: typedef enum { INDENT = 2 } bogus; int indent_level; private: void pr_name( RefAST node ); void pr_indent(); void pr_top( RefAST top ); void pr_open_angle(void); void pr_close_angle(Boolean first); void pr_leaves( RefAST top ); Boolean is_nonleaf( RefAST node ) { Boolean rslt; rslt = (Boolean)(node->getFirstChild() != NULL); return rslt; } public: void pr_tree( const RefAST top ); }; // print_tree #endif test_expr100644 1040 1001 46 6735537235 11170 0ustar everyone a = b + c * d; p = r * s + t * u;