我很擅长使用Javacc创建语言语法,我需要找到一种方法来允许用户在代码中重新定义令牌的定义。
例如,行
REDEFINE IF FOO
应改变" IF"的定义从
< IF: "IF" >
要
< IF: "FOO" >
如果无法做到这一点,解决这个问题的最佳方法是什么?
答案 0 :(得分:1)
我认为您可以通过更改令牌的种类字段的令牌操作来实现。
如下所示。 [未经测试的代码如下。如果您使用它,请更正此答案中的任何错误。]
创建哈希映射的令牌管理器声明:
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 ;}
| ...
}
有关尝试从解析器更改词法分析器行为的警告,请参阅常见问题解答(4.14)。长话短说:避免前瞻。
另一种方法是简单地使用一种令牌类型,比如ID
,并处理解析器中的所有内容。请参阅“使用语义预测替换关键字”的常见问题4.19。这里前瞻不会是一个问题,因为解析器中的语义动作在语法预测期间不会被执行(FAQ 4.10)。