[antlr-interest] Implementing "break" statement in antlr-based interpreter

Michael Cooper tillerman35 at yahoo.com
Tue Oct 23 12:46:32 PDT 2012


Say you have your basic "for" or "while" loop, e.g.

for(i=0; i<10; i++) {
  print i
}


In the "pie" example, the author has a while loop that uses a "defer" parameter to indicate that the interpreter will do the job of evaluating the expr that determines if the loop proceeds.


   |   'while' expr[true] slist[true]
        {if (!defer) interp.whileloop($expr.start, $slist.start);}

I would like to be able to break out of a "for" or "while" loop, as is done in many programming languages, e.g.

//Read rows from a cursor and print out the contents of field 1 until it says "break"
while cursor.hasrows() {
  cursor.getrow()
  if cursor.getfield[1] = "stop" then break  //<-- When field one says "break" we should exit the "while" loop.
  print cursor.getfield[1]
}

What I think I need to do is add a boolean to my interpreter that indicates that a break statement has been encountered, and then test for that condition = true in each rule action.

so in my "statement" rule, I would add an alternative:

| 'break' { if(!defer && !interp.breakfound) interp.break = true; }

and then add the "&& !interp.breakfound)" into every rule.  That way, the parser would not execute any interpreter functions until the breakfound condition was re-set.

I would also need to save the break condition prior to entering break-able constructs (loops and functions are the only ones I can think of) so that I could restore it after the end of the construct.  That way the break statement only exits the loop it executes in.

e.g. in class Interpreter:

public whileloop(Token expr_start, Token slist_start) {
  boolean saved_breakfound = this.breakfound;
    ...Handle the loop stuff here...
  this.breakfound = saved_breakfound;
}

Does this make sense?  Is there a better way that I'm missing?  I imagine the same idea could be used to implement a "return(value)" statement in a function as well.  The only difference would be that a return statement would exit the function no matter how deep it was into loops.  For that, I'd need some kind of tri-state indicator, with values like 0 => continue, 1=> break out of loop, 2 => return from function.

Any thoughts?

Thanks!


More information about the antlr-interest mailing list