2017-04-21 23 views
0

我爲包含循環的腳本語言做了一個解釋器,使用javacc我已經定義了語法,但是我不能有辦法備份到一行來重複執行塊「for」。 如何備份令牌管理器,以便循環體可以重新解析,從而重新評估,一遍又一遍?我如何在javacc中實現循環(For)

void For(): {ArrayList<String> lst;Token n,v;int i=0;} { 

     "for" "(" n=<ID> ":" v=<ID> ")" "{" 
    (actions()";" )+ 
    "}" 


    } 

回答

0

如JavaCC的FAQ(http://www.engr.mun.ca/~theo/JavaCC-FAQ/javacc-faq-moz.htm#tth_sEc7.3)所解釋的,最好的方法是輸出某種形式的中間表示的,然後解釋該。一些常見的方法如下。

0

至於其他的答案說,這就是爲什麼人們通常只是建立在內存中的數據結構,其中組命令解析一次,然後可以只是重複執行。

但是如果你現在想做一個純粹的解釋器,需要記住原來是循環的標記的開始位置(即「for」標記)並且回退到令牌流。您可能還必須提前瀏覽開始和結束括號(「{」和「}」),以便知道循環的結束。

一旦你有了,你的「for」命令就會從一個實際的循環變成一個「if」語句的變體。如果條件爲真,則執行命令,如果條件爲假,則跳過所有內容,包括關閉「}」。當你點擊「}」時,你跳回到「for」的位置,重新檢查條件。

+0

提前掃描可以通過向每個bnf生產添加一個參數來告訴它是否執行。無論如何你都需要處理這些陳述。 這個與JavaCC中棘手的部分是做倒帶。接口只是不存在於生成的令牌管理器中。通過繼承生成的令牌管理器來添加所需的接口可能是可能的。 –

0

我們可以使用JavaCode生產類似下面,

提供的動作()生產需要每一行的照顧。 請將分號移至動作()生產。

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(); 
    } 
} 

希望這會有所幫助。