我的目标是保存这样一个注释,该注释以任何单词开头,以“ end”单词结尾,
ANYWORD bla bla bla 结束
我有这个语法:
lexer grammar JunkLexer;
WS : [ \r\t\n]+ -> skip ;
LQUOTE : 'start' -> more, mode(START) ;
mode START;
STRING : 'end' -> mode(DEFAULT_MODE) ; // token we want parser to see
TEXT : . -> more ; // collect more text for string
但我不知道为什么,词法分析器会生成语法中不存在的标记:
当我检出词法分析器令牌时,是相同的:
WS=1
STRING=2
LQUOTE=3
'start'=3
'end'=2
提前谢谢
答案 0 :(得分:2)
当您使用单个字符串文字定义词法分析器规则时,该字符串文字将成为规则的替代名称。因此,当您在词法分析器语法中定义FOO: 'foo';
时,可以在解析器语法中互换使用FOO
和'foo'
。即使您将字符串拆分为解析器和词法分析器语法,这也允许您在语法中使用字符串文字。因此,即使您必须在词法分析器中编写PLUS: '+';
,您仍然可以在语法中编写exp '+' exp
而不是exp PLUS exp
。字符串文字名称也是显示令牌时使用的名称,因为它易于阅读。
在PLUS
示例中当然是有意义的,但在您的示例中却没有任何意义,因为由于more
,您的STRING
规则实际上并不仅仅是匹配end
,但匹配整个字符串。因此,在解析器语法中编写'end'
来匹配一个完整的begin-end部分将完全令人困惑(尽管它可以工作),并且它被用作令牌名称也是事实。但是ANTLR并没有意识到,因为它没有意识到只能通过调用STRING
的规则才能达到more
。
请注意,您仍然可以使用STRING
来引用标记,因此这实际上不会以任何方式破坏您的语法。但是,这将导致错误消息混乱(当它应为“ STRING”时为“ missing'end'”)。
要解决此问题,您可以将STRING
规则更改为不仅包含单个字符串文字:
STRING: 'e' 'n' 'd';
除了'end'
将不再是STRING
的别名并且将不再用作令牌的显示名称之外,这在所有方面都是等效的。