这个问题隐藏在另一个问题的更新部分,现在专门问它。
我正在使用antlr3.4。
我有一个简单的语法试图解析两种类型的文本,该行以“#include”开头,其他。这是我的语法:
cmds
: cmd+
;
cmd
: include_cmd | other_cmd
;
include_cmd
: INCLUDE DOUBLE_QUOTE FILE_NAME DOUBLE_QUOTE
;
other_cmd
: (~INCLUDE)+
;
INCLUDE
: '#include'
;
DOUBLE_QUOTE
: '"'
;
FILE_NAME
: ('a'..'z' | 'A'..'Z' | '0'..'9' | '_')+
;
New_Line
: ('\r' | '\n')+
;
WS
: ('\t' | ' ')+ {$channel = HIDDEN;}
;
但我得到了这样的警告:
Decision can match input such as "{DOUBLE_QUOTE..FILE_NAME, New_Line..WS}" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
我想这是因为双引号可以匹配other_cmd规则和DOUBLE_QUOTE规则,但我想知道这里,一个是解析器规则,另一个是词法分析器规则,这个警告是否有意义?
有任何帮助可以清除此警告吗?
一个附带问题 - 警告信息只是说替代1,2,但我不清楚什么是1,什么是2,有没有办法让antlr提供更直接的选择?
答案 0 :(得分:1)
我想这是因为双引号可以匹配other_cmd规则和DOUBLE_QUOTE规则,...
不,这不是问题,因为include_cmd
以other_cmd
无法匹配的内容开头。
决策可以使用多种替代方式匹配输入,例如“{DOUBLE_QUOTE..FILE_NAME,New_Line..WS}”:1,2
警告意味着解析器可以通过多种方式匹配foo"
(a FILE_NAME
后跟DOUBLE_QUOTE
)等输入:
ANTLR将选择贪婪的解析,但由于可能不合适,因此会生成警告。如果您明确告诉解析器贪婪地匹配,则不再发出警告:
other_cmd
: (options {greedy=true;} : ~INCLUDE)+
;
一个附带问题 - 警告信息只是说替代1,2,但我不清楚什么是1,什么是2,有没有办法让antlr提供更直接的选择?
不,不是我所知道的。这个警告确实相当神秘。替代方案通常表示解析器可以遵循的分支:
parser_rule
: alternative_1
| alternative_2
| alternative_3
;
但在你的情况下,似乎ANTLR正在讨论令牌范围作为替代方案:DOUBLE_QUOTE..FILE_NAME
是另一种选择而New_Line..WS
是第二种。