antlr3 - ANTLR Tree Walker should not output AST? -
i have made own language using antlr. grammar complete, want make tree walker verifies input. doesn't work. when (accidentally) used output=ast in tree walker compiles without error, doesn't accept input. (it says org.antlr.runtime.tree.commontree cannot cast tools.anode). think output=ast can not used in tree walker. however, won't compile then. gives
internal error: /.../src/awesomechecker.g : java.lang.illegalstateexception: java.lang.nullpointerexception org.deved.antlride.runtime.antlrerrorlistener$dynamictoken.invokemethod(antlrerrorlistener.java:59) org.deved.antlride.runtime.antlrerrorlistener$dynamictoken.getline(antlrerrorlistener.java:64) org.deved.antlride.runtime.antlrerrorlistener.report(antlrerrorlistener.java:131) org.deved.antlride.runtime.antlrerrorlistener.message(antlrerrorlistener.java:115) org.deved.antlride.runtime.antlrerrorlistener.warning(antlrerrorlistener.java:99) org.antlr.tool.errormanager.grammarwarning(errormanager.java:742) org.antlr.tool.errormanager.grammarwarning(errormanager.java:757) org.antlr.tool.grammar.parseandbuildast(grammar.java:655) org.antlr.tool.getrootgrammar(tool.java:626) org.antlr.tool.process(tool.java:459) org.deved.antlride.runtime.tool2.main(tool2.java:24)
and when try compile using command-line, says should add output=ast. first though compiler sees symbols can used in tree parser, can't find 'illegal' symbols.
can please me?
the grammar checker is:
//awesomechecker.g: antlr (context) checker voor awesome++ tree grammar awesomechecker; options { tokenvocab = awesome; //import tokens awesome.tokens astlabeltype = anode; //ast nodes of type anode } //alter code generation catch-clauses replaced action. //this disables antlr error handling: exceptions propagated upwards. @rulecatch { catch (recognitionexception re) { throw re; } } @header { import tools.*; import java.util.list; import java.util.arraylist; } @members { //symbol table voor de identifiers private symboltable st = new symboltable(); //voor de ast types private checker checker = new checker(); private void enter(anode id, boolean isvar) throws awesomeexception { try { identry ie = new identry(id, isvar); this.st.enter(id.gettext(), ie); } catch (symboltableexception e) { throw new awesomeexception(id, "al gedeclareerd"); } } } start : program ; program @init { this.st.openscope(); } : ^(program statement+) { this.st.closescope(); } ; statement : op=identifier e=assignment_statement { checker.checktypes($op, $e.start, op, checker.any_type); } | output_stat | input_stat | if_statement[false] | do_while_statement | declaration ; assignment_statement : (op=becomes^ e=expr)+ { op.setexprtype($e.start.getexprtype()); } ; declaration : ^(decl t=type c=const? id=identifier (e=expr)?) { boolean isvar = (c == null); int type = id.setexprtype($t.start.getexprtype()); if(e == null) { } else { checker.checktype($e.start, type); } this.enter(id, isvar); } ; type : t=boolean {$t.setexprtype(checker.bool_type);} | t=integer {$t.setexprtype(checker.int_type);} | t=char {$t.setexprtype(checker.char_type);} ; statements_block @init { this.st.openscope(); } : statement* {this.st.closescope();} ; expr : ^(op=compound (statement)* e=expr) { op.setexprtype($e.start.getexprtype()); } | ^(op = (plus | minus | multiply) e1=expr e2=expr) { checker.checktypes($e1.start, $e2.start, op, checker.int_type); op.setexprtype(checker.int_type); } | ^(op = (divide | modulus) e1=expr e2=expr) { checker.checktypes($e1.start, $e2.start, op, checker.int_type); if ($e2.text.equals("0")) { throw new awesomeexception($e2.start, "cannot divide zero"); } op.setexprtype(checker.int_type); } | ^(op = (smaller | smallerequal | greaterequal | greater) e1=expr e2=expr) { checker.checktypes($e1.start, $e2.start, op, checker.int_type); op.setexprtype(checker.bool_type); } | ^(op = (equal | notequal) e1=expr e2=expr) { checker.checktypes($e1.start, $e2.start, op, checker.any_type); op.setexprtype(checker.bool_type); } | ^(op = (and | or) e1=expr e2=expr) { checker.checktypes($e1.start, $e2.start, op, checker.bool_type); op.setexprtype(checker.bool_type); } | ^(op = unaryexpr (plus | minus) e1=expr) { checker.checktype($e1.start, checker.int_type); op.setexprtype(checker.int_type); } | ^(op = unaryexpr notequal e1=expr) { checker.checktype($e1.start, checker.bool_type); op.setexprtype(checker.bool_type); } ; input_stat : ^(op=input v=varlist) { int type = $v.start.getexprtype(); op.setexprtype(type); } ; output_stat : ^(op=output v=varlist) { int type = $v.start.getexprtype(); op.setexprtype(type); } ; if_statement[boolean isexpr] : ^(op=if cond=expr (statements_block|op1=operand) (else (statements_block|op2=operand))?) { checker.checktype($cond.start, checker.bool_type); if(isexpr) { int type = checker.checktypes($op1.start, $op2.start, op, $op1.start.getexprtype()); op.setexprtype(type); } else { op.setexprtype(checker.void_type); } } ; do_while_statement : ^(op=do statements_block while cond=expr) { checker.checktype($cond.start, checker.bool_type); op.setexprtype(checker.void_type); } ; varlist : expr (comma expr)* ; operand : identifier | literal | expr ; literal : number | charliteral | boolliteral ; boolliteral : true | false ;
the grammar.g is:
grammar awesome; options { k=1; // ll(1) - not use ll(*) language=java; // target language java (= default) output=ast; // build ast } tokens { colon = ':' ; comma = ',' ; semicolon = ';' ; lparen = '(' ; rparen = ')' ; lbracket = '{' ; rbracket = '}' ; // keyword ast decl = 'decl' ; unaryexpr = 'unexpr'; compound = 'compound'; assignment = 'assignment'; // operators becomes = '=' ; plus = '+' ; minus = '-' ; multiply = '*' ; divide = '/' ; modulus = '%' ; exclamation = '!' ; // comparators , = 'and' ; or = 'or' ; smaller = '<' ; smallerequal = '<=' ; greater = '>' ; greaterequal = '>=' ; equal = '==' ; notequal = '!=' ; // keywords program = 'program' ; return = 'return' ; var = 'var' ; const = 'const' ; input = 'input' ; output = 'output' ; if = 'if' ; = 'then' ; else = 'else' ; = 'do' ; while = 'while' ; // types integer = 'int' ; boolean = 'bool' ; char = 'char' ; string = 'string'; true = 'true'; false = 'false'; } // parser rules start : program ; program : (statement)+ eof -> ^(program statement+) ; statement : identifier assignment_statement semicolon! | output_stat semicolon! | input_stat semicolon! | if_statement | do_while_statement | declaration semicolon! ; declaration : type const? identifier (becomes expr)? -> ^(decl type const? identifier (becomes expr)?) ; type : boolean | integer | char | string ; statements_block : lbracket statement* rbracket ; assignment_statement : (becomes^ expr)+ ; expr : expr_or | expr_compound | if_statement ; expr_unary : operand | plus operand -> ^(unaryexpr plus operand) | minus operand -> ^(unaryexpr minus operand) | exclamation operand -> ^(unaryexpr exclamation operand) ; expr_multiply : expr_unary ((multiply | divide | modulus)^ expr_unary)* ; expr_plus : expr_multiply ((plus | minus)^ expr_multiply)* ; expr_compare : expr_plus ((smaller | smallerequal | greaterequal | greater | equal | notequal)^ expr_plus)* ; expr_and : expr_compare (and^ expr_compare)* ; expr_or : expr_and (or^ expr_and)* ; expr_compound : lbracket (statement)* return expr semicolon rbracket -> ^(compound (statement)* expr) ; do_while_statement : do^ statements_block while expr ; if_statement : if^ expr (statements_block|operand) (else (statements_block|operand))? ; input_stat : input^ lparen! varlist rparen! ; output_stat : output^ lparen! varlist rparen! ; varlist : expr (comma expr)* ; operand : identifier | literal | lparen! expr rparen! ; literal : number | charliteral | boolliteral ; boolliteral : true | false ; // lexer rules identifier : letter (letter | digit)* ; charliteral : '\'' letter '\'' ; number : digit+ ; comment : '[' .* ']' { $channel=hidden; } ; ws : (' ' | '\t' | '\f' | '\r' | '\n')+ { $channel=hidden; } ; fragment digit : ('0'..'9') ; fragment lower : ('a'..'z') ; fragment upper : ('a'..'z') ; fragment letter : lower | upper ; // eof
edit: found that
assignment_statement : (op=becomes^ e=expr)+
was error, should be
assignment_statement : (op=becomes e=expr)+
it compiles without errors! :d thank help!
i found that
assignment_statement : (op=becomes^ e=expr)+
was error, should be
assignment_statement : (op=becomes e=expr)+
i did not change in options of grammar files.
it compiles without errors! :d thank help!
Comments
Post a Comment