1
我對使用Javacc創建語言語法頗爲陌生,我需要找到一種方法來允許用戶重新定義代碼中的令牌定義。使用Javacc重新定義詞法記號
例如,行
REDEFINE IF FOO
應該改變的 「IF」 從
< IF: "IF" >
要
< IF: "FOO" >
的定義。如果這是不可能的,會是什麼解決這個問題的最好方法?
我對使用Javacc創建語言語法頗爲陌生,我需要找到一種方法來允許用戶重新定義代碼中的令牌定義。使用Javacc重新定義詞法記號
例如,行
REDEFINE IF FOO
應該改變的 「IF」 從
< IF: "IF" >
要
< IF: "FOO" >
的定義。如果這是不可能的,會是什麼解決這個問題的最好方法?
我認爲你可以用令牌動作來改變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)。
感謝回覆西奧多。在整個解析器中引用keywordMap時(以及對於標記定義),我遇到了問題 - 未解決的編譯問題:keywordMap無法解析或不是字段。 –
更新:我解決了我剛纔評論的這個問題,仍然有另一個問題,但嘗試修復它。生病repsond不久 –
非常感謝你這個解決方案工作得很好,做了一些小調整:) –