我在语法方面有以下问题:
我要解析的输入字符串如下:
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 : [ trn]+ -> 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'
输入中使用的任何单词(例如"命令"或"args")都会导致相同的问题。
ftp command args = ftp
ftp command args = args
ftp command args = command
有谁知道如何处理这类问题?
您的问题是语法中的字符串文字(例如 'ruledef'
和 'exit'
)隐式具有自己的标记类型,并且在其他所有内容之前(包括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 : [ trn]+ -> 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 : [ trn]+ -> 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' ;
如果您希望我澄清任何事情,请告诉我。
更改词汇规则的顺序NUM
和STRING
。
优先顺序是由他们的顺序决定的,所以先到先得。
享受ANTLR的乐趣,这是一个很好的工具。