我的函数具有参数语法,如下面的词法分析器和解析器:
MyFunctionsLexer.g4
lexer grammar MyFunctionsLexer;
FUNCTION: 'FUNCTION';
NAME: [A-Za-z0-9]+;
DOT: '.';
COMMA: ',';
L_BRACKET: '(';
R_BRACKET: ')';
WS : [ \t\r\n]+ -> skip;
MyFunctionsParser.g4
parser grammar MyFunctionsParser;
options { tokenVocab=MyFunctionsLexer; }
functions : function* EOF;
function : FUNCTION '.' NAME '(' (function | argument (',' argument)*) ')';
argument: (NAME | function);
但在解析器中接受带参数的函数或带参数的函数作为函数(嵌套函数)。我正在使用访客模式进行验证。但现在如果我传递不带参数的函数,它就会抛出错误。如何在上面的解析器中接受带有零参数的函数?
工作输入示例:
FUNCTION.toString(String)
无效输入示例:
FUNCTION.getTimestamp()
function : FUNCTION '.' NAME '(' (function | argument (',' argument)*) ')';
首先function |
这真的很奇怪。从表面上看,这意味着您可以仅使用单个函数调用作为其参数或使用任意多个函数来调用函数argument
s。但是由于argument
本身已经包含function
相反,它只是多余的。因此,让我们通过删除该部分来简化规则:
function : FUNCTION '.' NAME '(' (argument (',' argument)*) ')';
那么为什么这与不带参数的函数调用不匹配呢?因为argument
逗号之前的不是可选的。这',' argument
部分有一个*
应用于它,因此它可以出现任意次数 - 包括零次。但第一个argument
没有任何修饰符,所以它需要在那里。
那么我们怎样才能改变这一点呢?鉴于我刚刚将问题确定为第一个参数不是可选的,人们的第一个想法可能是只使argument
可选,通过添加?
直接在它之后(即argument? (',' argument)*
),但这也将允许诸如FUNCTION.f(,X)
,您可能不想允许。
相反,你应该申请?
整个参数列表,如下所示:
(argument (',' argument)*)?
这样它就可以匹配“一个参数后跟零个或多个‘逗号后跟参数’的实例”,或者什么也不匹配。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)