ANTLR 3解析-字符不匹配。。。期望
我是ANTLR的一名新手,我环顾了一下四周,想解决我的问题。不幸的是没有任何成功 我简化了语法来描述问题(在实际示例中使用了token标记): 当我尝试解析单词“a.bcd z”时,一切都很好,但当我尝试使用单词“a.tbyfa z”时,它显示了错误 line 1:4 mismatched character 'b' expecting 'e' line 1:5 missing DOT at 'yfa' 第1行:4个不匹配的字符“b”应为“e” 第1行:5“yfa”处缺少点 在我看来,问题在于“.”后面的字符串以“t”开头,t也可以是标记“.test”。我尝试了backtrack=true,但也没有成功。ANTLR 3解析-字符不匹配。。。期望,antlr,antlr3,Antlr,Antlr3,我是ANTLR的一名新手,我环顾了一下四周,想解决我的问题。不幸的是没有任何成功 我简化了语法来描述问题(在实际示例中使用了token标记): 当我尝试解析单词“a.bcd z”时,一切都很好,但当我尝试使用单词“a.tbyfa z”时,它显示了错误 line 1:4 mismatched character 'b' expecting 'e' line 1:5 missing DOT at 'yfa' 第1行:4个不匹配的字符“b”应为“e” 第1行:5“yfa”处缺少点 在我看来,问题在于“
如何解决该问题?
提前感谢。在这种情况下,ANTLR的lexer无法回溯到替代方案。一旦lexer看到
“.t”
,它会尝试匹配标记
标记,但没有成功,因此lexer会尝试匹配以“.t”
开头的其他标记,但没有这样的标记。并且lexer将不会再次回溯字符以匹配点
。这就是问题所在
一个可能的解决方案是这样做:
grammar Test;
rule : 'a' DOT WORD 'z';
WORD : ('a'..'z')+;
DOT : '.' (('test')=> 'test' {$type=TAG;})?;
SPACE : (' '|'\t'|'\n'|'\r')+ {$channel = HIDDEN;};
fragment TAG : /* empty rule: only used to change the 'type' */;
('test')=>
是一个语法谓词,它迫使词法分析器向前看,看看前面是否真的有“test”
。如果这是真的,“test”
被匹配,并且令牌的类型被更改为标记
。由于'test'
是可选的,因此该规则始终只能依赖于点
标记。“.test”是一个关键字。“.test”中的点与点标记的含义不同。我现在有另一个问题。我如何处理更多的“.xyz”形式的令牌,比如“.test”和“.test2”。点:'.'('test2')=>'test2'{$type=TAG2;}}|('test')=>'test'{$type=TAG1;})?;。。。好的,很酷,但是如果我想在解析器中使用TAG1和TAG2作为标记,这将是一个问题(没有片段的TAG1和TAG2)。有没有办法解决这个问题?没有,您可以在解析器规则中使用这些空片段规则。这是一个有点黑客,但这是它的工作方式:)抱歉再次询问,但在玩的时候,我有一个新的问题。。。以下字符串“a.test z”不起作用。有没有办法告诉解析器她应该使用点字而不是标记?@user1286372,没有,解析器独立于lexer工作<“代码>”。测试“将始终成为一个标记
,而不是点
和字
。您必须在解析器规则中说明这一点:规则:'a'(点字标记)'z'代码>
grammar Test;
rule : 'a' DOT WORD 'z';
WORD : ('a'..'z')+;
DOT : '.' (('test')=> 'test' {$type=TAG;})?;
SPACE : (' '|'\t'|'\n'|'\r')+ {$channel = HIDDEN;};
fragment TAG : /* empty rule: only used to change the 'type' */;