java - Visitor/Listener code for a while loop in ANTLR 4 -


so far have searched whole "the definitive antlr 4 reference" book many sites answer question , still can't find on topic.

i using antlr 4 create sub-set of c language basic functionality. have no idea how implement simple while loop in visitor class. far got in grammar:

grammar expr;  prog:   stat+ ;  stat:   expr newline                # printexpr     |   id '=' expr newline         # assign     |   loop newline                # whileloop     |   relational newline          # relat     |   newline                     # blank      ;  expr:   expr op=('*'|'/') expr      # muldiv     |   expr op=('+'|'-') expr      # addsub     |   int                         # int     |   id                          # id     |   '(' expr ')'                # parens     ;  relational:     expr op=(greater|less) expr     # greaterequal           ;  loop:   'while' '('relational')' newline? '{'stat*'}'   #while     ;  greater : '>' ; less : '<' ; mul :   '*' ; // assigns token name '*' used above in grammar div :   '/' ; add :   '+' ; sub :   '-' ; id  :   [a-za-z]+ ;      // match identifiers int :   [0-9]+ ;         // match integers newline:'\r'? '\n' ;     // return newlines parser (is end-statement signal) ws  :   [ \t]+ -> skip ; // toss out whitespace 

this way have multiple statements inside while loop. visitor class looks this:

public class evalvisitor extends exprbasevisitor<integer> {  /** "memory" our calculator; variable/value pairs go here */ map<string, integer> memory;  public evalvisitor() {     memory = new hashmap<string, integer>(); }  /** id '=' expr newline */ @override public integer visitassign(exprparser.assigncontext ctx) {           string id = ctx.id().gettext();  // id left-hand side of '='     int value = super.visit(ctx.expr());   // compute value of expression on right             memory.put(id, value);           // store in our memory     return value; }  /** expr newline */ @override public integer visitprintexpr(exprparser.printexprcontext ctx) {     integer value = super.visit(ctx.expr()); // evaluate expr child     system.out.println(value);         // print result     return 0;                          // return dummy value }  /** int */ @override public integer visitint(exprparser.intcontext ctx) {     return integer.valueof(ctx.int().gettext()); }  /** id */ @override public integer visitid(exprparser.idcontext ctx) {     string id = ctx.id().gettext();     if ( memory.containskey(id) ) return memory.get(id);             return 0; }  /** expr op=('*'|'/') expr */ @override public integer visitmuldiv(exprparser.muldivcontext ctx) {     int left = super.visit(ctx.expr(0));  // value of left subexpression     int right = super.visit(ctx.expr(1)); // value of right subexpression     if ( ctx.op.gettype() == exprparser.mul ) return left * right;     return left / right; // must div }  /** expr op=('+'|'-') expr */ @override public integer visitaddsub(exprparser.addsubcontext ctx) {     int left = super.visit(ctx.expr(0));  // value of left subexpression     int right = super.visit(ctx.expr(1)); // value of right subexpression             if ( ctx.op.gettype() == exprparser.add ) return left + right;     return left - right; // must sub  }  /** '(' expr ')' */ @override public integer visitparens(exprparser.parenscontext ctx) {     return super.visit(ctx.expr()); // return child expr's value }  @override public boolean visitgreaterequal(greaterequalcontext ctx) {     int left = super.visit(ctx.expr(0));     int right = super.visit(ctx.expr(1));      if(ctx.op.gettype() == exprparser.greater) {         return left > right;     }     else {         return left < right;     }  }  @override public integer visitwhileloop(whileloopcontext ctx) {      if(visit(ctx.getrulecontext())) {      }      return super.visitwhileloop(ctx); } 

}

most of code in visitor class took book because starting using antlr 4. find hard believe that, aside grammar while loop, there no mention of how implement visitors/listeners or actions simple while loop in book written terence parr. can me writing visitor/listener java code while loop?

i find hard believe that, aside grammar while loop, there no mention of how implement visitors/listeners or actions simple while loop in book written terence parr.

that because antlr reference antlr, parsing, not stage after parsing.

you can't this:

@override public boolean visitgreaterequal(greaterequalcontext ctx) {     ... 

you've declared visitor return integers, that's every rule should return. either make custom wrapper value encapsulates language's values (numbers, string, booleans), or return 0 when relation expression false:

@override public integer visitgreaterequal(exprparser.greaterequalcontext ctx) {     int left = this.visit(ctx.expr(0));     int right = this.visit(ctx.expr(1));      if (ctx.op.gettype() == exprparser.greater) {         return left > right ? 1 : 0; // 0 false (all other values true)     }     else {         return left < right ? 1 : 0;     } } 

then can write while follows:

@override public integer visitwhile(exprparser.whilecontext ctx) {      // evaluate relational expression , continue while     // loop long true (does not equal zero).     while (this.visit(ctx.relational()) != 0) {          // evaluate statements inside while loop.         (exprparser.statcontext stat : ctx.stat()) {             this.visit(stat);         }     }      // 0 false, maybe return null instead     // sort of void value (or make proper value class).     return 0; } 

note code above fail when nesting while statements because inner while return 0 causing outer while stop looping. in such cases, you'd better off creating custom value class , introduce sort of value.void instance not cause loop stop.

running following main method:

public static void main(string[] args) throws exception {      string expression = "n = 1\n" +             "while (n < 10) {\n" +             "  n\n" +             "  n = n + 1\n" +             "}\n";     exprlexer lexer = new exprlexer(new antlrinputstream(expression));     exprparser parser = new exprparser(new commontokenstream(lexer));     new evalvisitor().visit(parser.prog()); } 

would print:

1 2 3 4 5 6 7 8 9

also have @ demo language uses antlr4 , if , while statements, custom value object: https://github.com/bkiers/mu


Comments

Popular posts from this blog

javascript - jquery or ashx not working -

opencv - DataType<cv::detail::deriv_type>::depth what is it used for -

python 3.x - Mapping specific letters onto a list of words -