请参阅以下网址提供的源代码:https://gist.github.com/1684022.
我定义了两个令牌:
ID : ('a'..'z' | 'A'..'Z') ('0'..'9' | 'a'..'z' | 'A'..'Z' | ' ')*;
PITCH
: (('A'|'a') '#'?)
| (('B'|'b') '#'?)
| (('C'|'c') '#'?);
Run Code Online (Sandbox Code Playgroud)
显然,字母"A"将是一种模糊性.
我进一步定义:
note : PITCH;
name : ID;
main : name ':' note '\n'?
Run Code Online (Sandbox Code Playgroud)
现在,如果我输入"A:A"作为解析器的输入,我总是会收到错误.解析器需要PITCH或ID,具体取决于是先定义ID还是PITCH:
mismatched input 'A' expecting ID
Run Code Online (Sandbox Code Playgroud)
解决这个问题的正确方法是什么,以便按预期工作?
如上所述,虽然直观地解释了解析应该如何工作,但ANTLR并没有做"正确的事".也就是说,即使main规则说a name/ ID应该首先出现,但是词法分析者似乎对此一无所知并将"A"标识为a,PITCH因为它遵循"最长匹配"/"首先出现"规则而不是更合理"什么规则说"规则.
通过匹配ID和PITCH,然后像dasblinkenlight所说的那样重新组合它们是假冒/破解它的唯一解决方案吗?
以下是我将重新考虑这个语法以使其工作的方法:
ID : (('a'..'z' | 'A'..'Z') ('0'..'9' | 'a'..'z' | 'A'..'Z' | ' ')+)
| ('d'..'z' | 'D'..'Z');
PITCH : 'a'..'c' | 'A'..'C';
SHARP : '#';
note : PITCH SHARP?;
name : ID | PITCH;
main : name ':' note '\n'? EOF
Run Code Online (Sandbox Code Playgroud)
这将长名称与单字符间距名称分开,后者在解析器中"重新统一".此外,"sharp"令牌也有自己的名称,并在解析器中被识别为可选令牌.
| 归档时间: |
|
| 查看次数: |
1697 次 |
| 最近记录: |