2016-04-14 59 views
0

我想能够使用“NULL”既是参数(价值),并在我的语法一个函数名。看到这个减少的例子:ANTLR:解析NULL作为函数的名称和参数

grammar test; 

expr 
    : value # valueExpr 
    | FUNCTION_NAME '(' (expr (',' expr)*)* ')' # functionExpr 
    ; 


value 
    : INT 
    | 'NULL' 
    ; 

FUNCTION_NAME 
    : [a-zA-Z] [a-zA-Z0-9]* 
    ; 


INT: [0-9]+; 

现在,试图解析:解析树失败

NULL(1) 

的结果,因为它解析为NULL值,而不是一个函数名。

理想情况下,我甚至应该能够解析NULL(NULL) ..

你能告诉我,如果这是可能的,如果是,如何做到这一点?

回答

0

'NULL'串在你的语法定义了一个隐含的标记类型,它是相当于沿着这增加一些:

NULL: 'NULL'; 

在的词法规则的开始。当令牌与多个词法分析器规则匹配时,会使用第一个,因此在您的语法中,隐式规则会优先,并且您会得到类型为'NULL'的令牌。

简单的解决办法是引入了函数名解析器规则,这样的事情:

function_name: FUNCTION_NAME | 'NULL'; 

,然后用它在你的expr规则。但是这看起来很脆弱,如果NULL不是您的语法中的关键字。还有其他的解决方案,但我不确定该怎么建议,因为我不知道你希望你的语法如何扩展。

但另一种解决办法是重新命名FUNCTION_NAMENAME,摆脱'NAME'令牌类型,并重写expr这样的:

expr 
    : value # valueExpr 
    | NAME '(' (expr (',' expr)*)* ')' # functionExpr 
    | {_input.LT(1).getText().equals("NULL")}? NAME # nullExpr 
    ; 

语义断言这里照顾名称比较。