我希望能够使用'NULL'作为我的参数(值 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 :(得分:0)
语法中的'NULL'
字符串定义了隐式令牌类型,它等同于在此处添加内容:
NULL: 'NULL';
词法分析器规则的开头。当一个令牌匹配几个词法分析器规则时,会使用第一个词法规则,因此在您的语法中,隐式规则获得优先权,并且您获得类型为'NULL'
的令牌。
一个简单的解决方案是为函数名引入解析器规则,如下所示:
function_name: FUNCTION_NAME | 'NULL';
然后在expr
规则中使用它。但是,如果NULL
不是您语法中的关键词,那么这似乎很脆弱。还有其他解决方案,但我不太清楚应该提出什么建议,因为我不知道你的语法如何扩展。
但另一种解决方案可能是将FUNCTION_NAME
重命名为NAME
,摆脱'NAME'
令牌类型,然后重写expr
:
expr
: value # valueExpr
| NAME '(' (expr (',' expr)* )* ')' # functionExpr
| {_input.LT(1).getText().equals("NULL")}? NAME # nullExpr
;
语义谓词在这里处理名称比较。