java - 如何在 Antlr4 中为零参数函数编写语法

标签 java antlr antlr4

我的函数具有参数语法,如下面的词法分析器和解析器:

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 本身已经包含 function 作为替代方案,因此它是多余的。因此,让我们通过删除该部分来简化规则:

function : FUNCTION '.' NAME '(' (argument (',' argument)*) ')';

那么为什么这与不带参数的函数调用不匹配呢?因为逗号之前的argument不是可选的。 ',' 参数 部分应用了 *,因此它可以出现任意次数 - 包括零次。但第一个参数没有任何修饰符,因此它需要存在。

那么我们该如何改变呢?鉴于我刚刚将问题确定为第一个参数不是可选的,人们的第一个想法可能是通过直接在其后面添加 ? 来使 argument 成为可选(即 argument? (',' argument)*),但这也将允许诸如 FUNCTION.f(,X) 之类的构造,您可能不希望允许这种构造。

相反,您应该将 ? 应用于整个参数列表,如下所示:

(argument (',' argument)*)?

这样它就可以匹配“一个参数后跟零个或多个‘逗号后跟参数’的实例”,或者什么也不匹配。

关于java - 如何在 Antlr4 中为零参数函数编写语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59011569/

相关文章:

java - Android如何从TextView获取String到String

java - Spring @Configuration 中的 Spring 原型(prototype) bean 引用

java - 使用正则表达式阻止 jtextfield 中的 SQL 注入(inject)条目

parsing - 噪声数据流上的 ANTLR

javascript - 使用 ANTLR 解析 JavaScript 正则表达式

java - 在词法分析器规则中使用标记类型进行正向前瞻

antlr - 如何修复antlr4中预期的无关输入 ' '

java - 覆盖错误android studio

parsing - 更改 antlr lexer 解析器以支持 "and"和 "or"关键字

java - 有没有其他方法可以预览 ANTLR 生成的解析树?