How to write grammer in Antlr4 for function with zero argument

十年热恋 提交于 2019-12-09 19:44:53

问题


I'm having function with arguments grammer 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.

Example For Working input:

FUNCTION.toString(String)

Example For Not Working input:

FUNCTION.getTimestamp()

回答1:


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

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

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.

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.



来源:https://stackoverflow.com/questions/59011569/how-to-write-grammer-in-antlr4-for-function-with-zero-argument

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!