问题
I made an interpreter for a script language containing a loop for, using javacc I have defined the grammar but I can't have a way to back up to line to repeat the execution of the block "for". how back up the token manager so that loop-bodies can be re-parsed, and thus reevaluated, over and over again ?.
void For(): {ArrayList<String> lst;Token n,v;int i=0;} {
"for" "(" n=<ID> ":" v=<ID> ")" "{"
(actions()";" )+
"}"
}
回答1:
As explained in the JavaCC FAQ (http://www.engr.mun.ca/~theo/JavaCC-FAQ/javacc-faq-moz.htm#tth_sEc7.3), the best approach is to output some form of intermediate representation and then interpret that. Some common approaches follow.
One way is to output a tree from the parser. Then interpret the tree. The interpreter could use the Interpreter design pattern. https://en.wikipedia.org/wiki/Interpreter_pattern
A second way is to translate to the machine code for a virtual machine. An example of this approach can be seen in the Turtle Talk interpreter at http://www.engr.mun.ca/~theo/Courses/sd/5895-downloads/turtle-talk.zip .
A third way is to translate to another high-level programming language which can then be compiled and executed.
回答2:
As other answers have said, this is why usually people just build a data structure in memory, where the group of commands is parsed once and can then just be executed repeatedly.
But if you want to do a pure interpreter for now, what is needed is to remember the start position of the token that turned out to be the loop (i.e. the "for" token) and rewind to that position in the token stream. You might also have to scan ahead for the opening and closing brackets ("{" and "}") so that you know the end of the loop.
Once you have that, your "for" command changes from an actual loop into a variant of the "if" statement. If the condition is true, you execute the commands, if the condition is false, you jump over everything, including the closing "}". And when you hit the "}", you jump back to the position of the "for" to check the condition all over again.
回答3:
We can use the JavaCode Production like below,
provided the action() production takes care of each line. Please Move semicolon to the actions() Production.
TOKEN : {
<LCURLY : "{" >
<RCURLY : "}" >
}
void For(): {ArrayList<String> lst;Token n,v;int i=0;} {
"for" "(" n=<ID> ":" v=<ID> ")" <LCURLY>
loopBody ();
<RCURLY>
}
JAVACODE
void loopBody () {
Token t = getNextToken();
while (t.kind != RCURLY) {
actions();
t = getNextToken();
}
}
Hope This will help.
来源:https://stackoverflow.com/questions/43546050/how-do-i-implement-loops-for-in-javacc