本文介绍了如何在 Antlr4 中为具有零参数的函数编写语法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有像下面的词法分析器和解析器这样的带参数语法的函数:

I'm having function with arguments grammar like below lexer and parser:

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);

但在解析器中接受带参数的函数或带参数的函数作为函数(嵌套函数).我正在使用访问者模式进行验证.但是现在如果我传递没有参数的函数,它会抛出错误.如何在上述解析器中接受零参数的函数?

But in parser is accepting function with arguments or function with argument as function(nested function). I am using visitor pattern for validation. But now if I pass function with no arguments it is throwing error. How to accept function with zero argument in the above parser?

工作输入示例:

FUNCTION.toString(String)

不工作输入示例:

FUNCTION.getTimestamp()

推荐答案

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

首先,这里的 function | 真的很奇怪.从表面上看,这意味着您可以只使用一个函数调用作为参数或任意多个 argument 来调用函数.但是由于 argument 本身已经包含 function 作为替代,它只是多余的.因此,让我们通过删除该部分来简化规则:

First of all the function | here is really odd. At the face of it, it would mean that you can call a function with only a single function call as its argument or with arbitrarily many arguments. But since argument itself already contains function as an alternative, it's simply redundant. So let's simplify the rule by removing that part:

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

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

So why does this not match function calls without arguments? Because the argument before the comma is not optional. The ',' argument part has a * applied to it, so it can appear any number of times - including zero. But the first argument doesn't have any modifiers, so it needs to be there.

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

So how can we change that? Given that I just identified the problem as the first argument not being optional, one's first thought might be to just make the argument optional by adding a ? directly after it (i.e. argument? (',' argument)*), but that would also allow constructions such as FUNCTION.f(,X), which you presumably don't want to allow.

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

Instead you should apply ? to the whole list of arguments, like this:

(argument (',' argument)*)?

这样它就可以匹配一个参数后跟零个或多个‘逗号后跟参数’的实例"或什么都不匹配.

That way it can match either "an argument followed by zero or more instances of 'comma followed by argument'" or nothing.

这篇关于如何在 Antlr4 中为具有零参数的函数编写语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-13 20:06