我知道这个问题以前或多或少都有过同样的问题,但没有一个答案对我有用:
grammar Problem;
top: (IDENT | INT)*;
IDENT: (ALPHA|'_') (ALPHA|DIGIT|'_')*;
INT: DEC_INT | HEX_INT;
DEC_INT: (ZERO | (NZERO_DIGIT DIGIT*));
HEX_INT: ZERO X HEX+;
ZERO: '0';
NZERO_DIGIT: '1'..'9';
DIGIT: '0'..'9';
ALPHA: [a-zA-Z];
HEX: [0-9a-fA-F];
X: [xX];
WS: [ \t\r\n]+ -> skip;
当我将此输入提供给解析器时:
0xFF ZZ123
后跟换行符和ctrl-D,它被解析为:
(top 0xFF ZZ123)
这是预期的行为。
但是,当我将此输入提供给解析器时:
0xFFZZ123
后跟换行符和ctrl-D,它被解析为:
(top 0xFF ZZ123)
这完全没有意图。我希望这会触发词法分析器错误,将其视为拼写错误的HEX_INT。
如果我禁用空格跳过,我仍然会得到相同的词法分析器行为(将一组字符解析为两个标记),但是由于现在向解析器报告了WS标记,因此出现以下错误:
0XFFZZ123
line 1:9 extraneous input '\n' expecting {<EOF>, IDENT, INT}
(top 0XFF ZZ123 \n)
另外我不能再输入空格分隔的标记了(正常,因为top没有提到WS):
0XFF ZZ123
line 1:4 extraneous input ' ' expecting {<EOF>, IDENT, INT}
(top 0XFF ZZ123)
我试图通过禁用空格跳过并将顶级规则更改为:
来修复语法top: WS* (IDENT | INT) (WS+ (IDENT|INT))* WS*;
但是,如果我将以下流输入解析器,
0xFF ZZ123 0XFFZZ123
我收到此错误:
line 1:20 extraneous input 'ZZ123' expecting {<EOF>, WS}
(top 0xFF ZZ123 0xFF ZZ123 \n)
你仍然可以看到最后一个输入标记已经被分割为OxFF和ZZ123,而我真的会在这里触发一个lexing错误,而不是必须明确处理解析器中的空格。
那么我必须使用哪些技巧组合来获得所需的行为?
答案 0 :(得分:1)
您可以编写一个接受错误令牌(如0XFFZZ123)的令牌,并将其置于WS之前。例如:
grammar SandBox;
top: (IDENT | INT)*;
IDENT: (ALPHA|'_') (ALPHA|DIGIT|'_')*;
INT: DEC_INT | HEX_INT;
DEC_INT: (ZERO | (NZERO_DIGIT DIGIT*));
HEX_INT: ZERO X HEX+;
ZERO: '0';
NZERO_DIGIT: '1'..'9';
DIGIT: '0'..'9';
ALPHA: [a-zA-Z];
HEX: [0-9a-fA-F];
X: [xX];
ERROR_TOKEN: (~[ \t\r\n])+;
WS: [ \t\r\n]+ -> skip;
以下是发生的事情。如果你输入0xFF ZZ123,那么INT和IDENT因为它们的位置而获胜。如果输入0XFFZZ123,则ERROR_TOKEN因长度(长度优先于位置)而获胜。由于ERROR_TOKEN不是&#34; top&#34;的一部分,因此会引发错误。
我希望这能解决问题。