Mar*_*ijn 4 antlr lexer antlr3
以下非常简单的示例语法不像我预期的那样(根本没有).
Declaration : 'VAR';
Letter: ('A'..'Z');
message : Declaration Letter+;
Run Code Online (Sandbox Code Playgroud)
我所期望的结果是,任何字母序列都会作为单个字母而形成,并且序列"VAR"将被作为单个标记.
当我查看ANTLRWorks interperter时,我看到以下结果:
VARA解析message -> "VAR", "A"(预期)VARVA不解析(MismatchedTokenException(-1!= 5).词法分析器命中第二个VA并尝试标记Declaration.预期:message -> "VAR", "V", "A"VARVPP解析message -> "VAR", "V", "P", "P"(预期)VARVALL解析message -> "VAR", "VALL".我想帮助理解这种行为,并建议我如何解决这个问题.
特别:
VA为"声明",如果后跟一个字母?V?开头的所有字符串来执行此操作?让我们来看看你的所有4个例子:

一切都好.
"VAR"(显然)被标记为VAR,但是词法分析器"看到" "VA"并期望一个"R",而不是那里.它会发出以下错误:
line 1:5 mismatched character '<EOF>' expecting 'R'
line 1:5 required (...)+ loop did not match anything at input '<EOF>'
Run Code Online (Sandbox Code Playgroud)
并且丢弃"VA"生成的单个令牌,正如您在运行ANTLRWorks的调试器时所看到的(忽略解析中的异常,它们实际上并不存在:) :):

你必须意识到的是,词法分析者永远不会放弃它已经匹配的东西.因此,如果词法分析器看到 "VA"并且不能匹配"R"它,那么它将查看可匹配的其他词法分析器规则"VA".但是Letter不匹配(它只匹配单个字母!)如果你Letter改为匹配多个单个字符,ANTLR将能够回退到该规则.而不是在它匹配单个字母:词法分析器不会放弃"A"从"VA"让Letter规则匹配.没办法:这就是ANTLR的词法分析器的工作原理.
这通常不是问题,因为IDENTIFIER当关键字无法匹配时,词法分析器可能会依赖某种规则.

好吧:"VAR"变成了一个VAR,然后词法分析器尝试匹配"A"后面"V"但不会发生这种情况,所以词法分析器会回到Letter单一规则上"V".之后"PP"都被标记为Letters.
"VAR"再次成为一个VAR.然后"L"in "VAL"导致词法分析器产生以下错误消息:
line 1:5 mismatched character 'L' expecting 'R'
Run Code Online (Sandbox Code Playgroud)
然后最后"L"成为Letter:

我猜(或希望)现在回答了前3个问题,这留下了你的最终答案:
我应该如何改变这种语法来解析我的预期方式?
通过强制词法分析器首先在字符流中"VAR"向前看,如果确实存在,如果没有,只需匹配一个"V"并更改匹配的令牌的类型Letter,如下所示:
Declaration
: ('VAR')=> 'VAR'
| 'V' {$type=Letter;}
;
Run Code Online (Sandbox Code Playgroud)
正如我之前提到的那样,请参阅此相关问答:ANTLR词法分析器根本无法预测
| 归档时间: |
|
| 查看次数: |
174 次 |
| 最近记录: |