用Javacc重新定义词法标记

时间:2017-05-04 03:11:29

标签: token javacc

我很擅长使用Javacc创建语言语法,我需要找到一种方法来允许用户在代码中重新定义令牌的定义。

例如,行

REDEFINE IF FOO

应改变" IF"的定义从

  < IF: "IF" >

  < IF: "FOO" >

如果无法做到这一点,解决这个问题的最佳方法是什么?

1 个答案:

答案 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)。