Antlr Lexer标记化
以下极为简单的示例语法并不像我所期望的那样(完全) 因此,我所期望的是,任何字母序列都将作为单个字母进行lex,而序列“VAR”将作为单个标记进行lex 当我查看ANTLRWorks interperter时,我看到以下结果:Antlr Lexer标记化,antlr,antlr3,lexer,Antlr,Antlr3,Lexer,以下极为简单的示例语法并不像我所期望的那样(完全) 因此,我所期望的是,任何字母序列都将作为单个字母进行lex,而序列“VAR”将作为单个标记进行lex 当我查看ANTLRWorks interperter时,我看到以下结果: VARA解析为消息->“VAR”,“A”(预期) VARVA不解析(不匹配的TokenException(-1!=5)。lexer点击第二个VA,并尝试标记声明。预期:消息->“VAR”、“V”、“A” VARVPP解析为消息->“VAR”、“V”、“P”、“P”(预期
解析为VARA
(预期)消息->“VAR”,“A”
不解析(不匹配的TokenException(-1!=5)。lexer点击第二个VARVA
,并尝试标记VA
。预期:声明
消息->“VAR”、“V”、“A”
解析为VARVPP
(预期)消息->“VAR”、“V”、“P”、“P”
解析为VARVALL
消息->“VAR”,“VALL”
- 如果后面跟一个字母,为什么lexer会尝试将所有以
开头的字符串标记到声明中VA
- 为什么lexer不尝试对所有以
开头的字符串执行此操作V
- 如果还有一个额外的字符,lexer为什么不尝试这样做呢
- 我应该如何更改此语法以按预期的方式进行分析
VAR
,它就会尝试匹配到目前为止得到的-VA
,并且没有匹配标记,因为字母不能匹配两个字符,只有一个
对于解决方案,一个简单的方法是将其更改为单个令牌:
Message : 'VAR' ('A'..'Z')+;
message : Message;
不过,它不会为每个字母提供不同的标记。让我们看一下您的4个示例: 1“瓦拉” 好的 2“瓦瓦”
“VAR”
被(显然)标记为VAR
,但随后lexer“看到”“VA”
,并期望出现一个“R”
,但不在那里。它发出以下错误:
line 1:5 mismatched character '<EOF>' expecting 'R'
line 1:5 required (...)+ loop did not match anything at input '<EOF>'
然后最后一个“L”
变成一个字母
:
我想(或希望)前3个问题现在已经回答了,剩下最后的答案: 我应该如何更改此语法以按预期的方式进行分析 如果前面确实有
“VAR”
,则强制lexer首先在字符流中向前看,如果前面没有,则只需匹配单个“V”
,并将匹配标记的类型更改为字母,如下所示:
Declaration
: ('VAR')=> 'VAR'
| 'V' {$type=Letter;}
;
正如我在回答之前所提到的,请看这个相关的问答:啊,我现在明白你的意思了。是的,你是对的:你的建议确实适用于OP发布的4个例子。但我想OP真正的问题是如何使输入像“VA”
,然后是“R”以外的内容
标记为字母
s,而不是(失败的)VAR
标记。再次为所有混淆表示抱歉。
line 1:5 mismatched character 'L' expecting 'R'
Declaration
: ('VAR')=> 'VAR'
| 'V' {$type=Letter;}
;