如何在 Antlr4 中为零参数函数编写语法
How to write grammar in Antlr4 for function with zero arguments
我正在使用如下词法分析器和解析器的参数语法函数:
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
来调用一个函数。但是由于 argument
本身已经包含 function
作为替代,它只是多余的。因此,让我们通过删除该部分来简化规则:
function : FUNCTION '.' NAME '(' (argument (',' argument)*) ')';
那为什么这不匹配没有参数的函数调用呢?因为逗号前的 argument
不是可选的。 ',' argument
部分应用了 *
,因此它可以出现任意次数 - 包括零次。但是第一个 argument
没有任何修饰符,所以它需要在那里。
那么我们该如何改变呢?鉴于我只是将问题确定为第一个参数不是可选的,人们的第一个想法可能是通过直接在其后添加 ?
(即 argument? (',' argument)*
)来使 argument
可选,但这也将允许诸如 FUNCTION.f(,X)
之类的结构,您可能不想允许这种结构。
相反,您应该将 ?
应用于整个参数列表,如下所示:
(argument (',' argument)*)?
这样它既可以匹配 "an argument followed by zero or more instances of 'comma followed by argument'" 也可以不匹配。
我正在使用如下词法分析器和解析器的参数语法函数:
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
来调用一个函数。但是由于 argument
本身已经包含 function
作为替代,它只是多余的。因此,让我们通过删除该部分来简化规则:
function : FUNCTION '.' NAME '(' (argument (',' argument)*) ')';
那为什么这不匹配没有参数的函数调用呢?因为逗号前的 argument
不是可选的。 ',' argument
部分应用了 *
,因此它可以出现任意次数 - 包括零次。但是第一个 argument
没有任何修饰符,所以它需要在那里。
那么我们该如何改变呢?鉴于我只是将问题确定为第一个参数不是可选的,人们的第一个想法可能是通过直接在其后添加 ?
(即 argument? (',' argument)*
)来使 argument
可选,但这也将允许诸如 FUNCTION.f(,X)
之类的结构,您可能不想允许这种结构。
相反,您应该将 ?
应用于整个参数列表,如下所示:
(argument (',' argument)*)?
这样它既可以匹配 "an argument followed by zero or more instances of 'comma followed by argument'" 也可以不匹配。