2017-05-04 44 views
1

我對使用Javacc創建語言語法頗爲陌生,我需要找到一種方法來允許用戶重新定義代碼中的令牌定義。使用Javacc重新定義詞法記號

例如,行

REDEFINE IF FOO 

應該改變的 「IF」 從

< IF: "IF" > 

< IF: "FOO" > 

的定義。如果這是不可能的,會是什麼解決這個問題的最好方法?

回答

1

我認爲你可以用令牌動作來改變token的種類字段。

像下面這樣。 [未經測試的代碼如下。如果你使用它,請糾正這個答案的任何錯誤]

做一個哈希表的令牌經理聲明:

TOKEN_MGR_DECLS: { 
    public java.util.HashMap<String,Integer> keywordMap = new java.util.HashMap<String,Integer>() ; 
    { keywordMap.put("IF", ...Constants.IF); } 
} 

做一個定義標識符。

TOKEN : { <ID : (["a"-"z","A"-"Z"])(["a"-"z","A"-"Z","0"-"9"])* > 
       { if(keywordMap.containsKey(matchedToken.image)) { 
        matchedToken.kind = keywordMap.get(matchedToken.image) ; } 
       } 
     } 

確定關鍵詞的定義。這些需要在ID的定義之後出現。真的,這些只是在這裏,以創建種類。他們將無法訪問,可能會導致警告。

TOKEN : { <IF : "A"> | ... } 

在您需要定義解析器重新

void redefine() : 
{ 
    Token oldToken; 
    Token newToken; 
} 
{ 
    <REDEFINE> oldToken=redefinableToken() newToken=redefinableToken() 
    { 
     if(...TokenManager.keywordMap.containsKey(oldToken.image)) { 
      ...TokenManager.keywordMap.remove(oldToken.image) ; 
      ...TokenManager.keywordMap.add(newToken.image, oldToken.kind) ; } 
     else { 
      report an error } 
    } 
} 

Token redefinableToken() : 
{ Token t ; } 
{ 
    t=<ID> {return t ;} 
| t=<IF> {return t ;} 
| ... 
} 

見警告FAQ(4.14)關於設法改變從解析器詞法分析器的行爲。長話短說:避免向前看。


另一種方法是隻需一個令牌樣,說ID,並處理解析器的一切。請參閱關於「用語義預測替換關鍵字」的FAQ 4.19。在這種情況下,前瞻將不會成爲問題,因爲解析器中的語義動作在語法預測期間不會執行(FAQ 4.10)。

+0

感謝回覆西奧多。在整個解析器中引用keywordMap時(以及對於標記定義),我遇到了問題 - 未解決的編譯問題:keywordMap無法解析或不是字段。 –

+0

更新:我解決了我剛纔評論的這個問題,仍然有另一個問題,但嘗試修復它。生病repsond不久 –

+0

非常感謝你這個解決方案工作得很好,做了一些小調整:) –