1

我的语法有以下问题:

我要解析的输入字符串如下:

ruledef COMPLEX1 
    ftp command args = abc
    ftp command args = ftp
    ftp command args = cde
exit

我使用的语法:

grammar main;

/*Lexical*/
NUM : [0-9]+;
STRING : [0-9a-zA-Z]+;
WS : [ \t\r\n]+ -> skip; // Whitespace definition: skip spaces, tabs and newlines

ruledefrule: 'ruledef' STRING (ruledef_ftpcommandargsrule )* 'exit';
ruledef_ftpcommandargsrule: 'ftp' 'command' 'args' '=' STRING ;

当我通过 antlr 运行它时,我收到一个错误:

line 3:23 missing STRING at 'ftp'

更重要的是,输入中使用的任何单词,例如“命令”或“参数”都会导致同样的问题。

ftp command args = ftp
ftp command args = args
ftp command args = command

有谁知道如何处理这类问题?

4

2 回答 2

0

您的问题是语法中的字符串文字,例如'ruledef'and'exit'隐含地具有自己的标记类型,并且在其他所有内容之前匹配,包括 before STRING。因此,在其可能值集中STRING不包含'ruledef''exit''ftp''command'和。'args'就好像您已经隐式编写了以下语法:

grammar main;

/* Lexical */
RULEDEF : 'ruledef' ;
EXIT : 'exit' ;
FTP : 'ftp' ;
COMMAND : 'command' ;
ARGS : 'args' ;
NUM : [0-9]+ ;
STRING : [0-9a-zA-Z]+ ;
WS : [ \t\r\n]+ -> skip ; // Whitespace definition: skip spaces, tabs and newlines

ruledefrule : RULEDEF STRING ruledef_ftpcommandargsrule* EXIT ;
ruledef_ftpcommandargsrule : FTP COMMAND ARGS '=' STRING ;

上面的语法不支持您提到的输入,因为'ruledef', 'exit', 'ftp','command''args'都被标记捕获,而不是STRING它们与ruledef_ftpcommandargsrule. 解决这个问题的方法是制定另一个规则,我们称之为string,它可以是STRING, 'ruledef', 'exit', 'ftp', 'command', 或'args'。然后使用该规则代替STRING任何需要行为的地方:

grammar main;

/* Lexical */
NUM : [0-9]+ ;
STRING : [0-9a-zA-Z]+ ;
WS : [ \t\r\n]+ -> skip ; // Whitespace definition: skip spaces, tabs and newlines

ruledefrule : 'ruledef' string ruledef_ftpcommandargsrule* 'exit' ;
ruledef_ftpcommandargsrule : 'ftp' 'command' 'args' '=' string ;
string : STRING | 'ruledef' | 'exit' | 'ftp' | 'command' | 'args' ;

如果您希望我澄清任何事情,请告诉我。

于 2018-11-29T22:21:05.023 回答
-2

更改词汇规则的顺序NUMSTRING.

他们的优先级是由他们的顺序决定的,所以先到先得。

玩得开心 ANTLR,它是一个不错的工具。

于 2013-10-18T12:44:53.117 回答