Antlr - 未使用的解析器规则导致错误,具体取决于定义 - 为什么?

时间:2018-01-18 11:18:36

标签: java parsing antlr antlr4 lexer

我收到了一个我不理解的错误,而且它是关于" testRule"下面...

grammar MyTest;

myTest: line+ EOF;

testRule: '\n\n' ; //this produces an error - WHY?
//testRule: '\n\n\n\n' ; //no error
//testRule: Break Break ; //no error

line: Break? Break Spaces? ((Word | NormalNumbers) Spaces?)+;


//lexer rules

Word: (Prefix? Space? Char Char+ Space? Suffix?) | (Char Suffix?);

NormalNumbers: Prefix? Numbers Suffix?;
Numbers: YearNumber | OtherNumber;

YearNumber
    : '(' '1' '9' Digit Digit ')'
    | '[' '1' '9' Digit Digit ']'
    | '1' '9' Digit Digit; 

OtherNumber: [1-9] Digit* ;

Sign: Prefix | Suffix | Special ;
Spaces: Space (Space Space?)?;

Space:      ' ';
Tab:        '\t';
Break:      '\n';
Digit:      [0-9];
Char:       [A-Z\u00C4\u00D6\u00DCa-z\u00E4\u00F6\u00FC\u00DF];
Prefix:     '"' | '\'' | '(' | '[';
Suffix:     '\u00AF' | '\u002d' | '.' | ',' | ':' | ';' | '!' | '?' | '"' | '\'' | ')' | ']';
Special:    [\u005e\u00ac/&{}*~];

运行时产生的错误说:

line 2:40 extraneous input '\n\n' expecting {<EOF>, Word, NormalNumbers, '
'}

我的(测试)输入:

  

东西 - 还有位置

     

位于某处

     

达拉斯,2012年

     

在。 99.2013(2014)

     

来自维基百科的一些bla blub文本和内容示例伊利诺伊州   百年纪念半美元是纪念性的五十美元作品   1918年美国造币局。正面,   描绘亚伯拉罕林肯,由首席雕刻师乔治T.设计   摩根;基于伊利诺伊州印章的反面图像是由   他的助手兼继任者John R. Sinnock。

无论如何,未使用的规则(testRule)如何干扰其余规则?如何显示错误消息? 谢谢你的提示!

1 个答案:

答案 0 :(得分:2)

问题是您通过在解析器规则中使用\n\n来间接声明匹配'\n\n'的词法分析器规则。

这&#34; new&#34;词法分析器规则在所有其他词法分析器规则之前指定(因为它们在源代码中的'...' - 构造之后指定),这导致首先查询它。

因此输入\n\n不会产生两个Break - 令牌,而是一个与间接指定的词法分析器规则对应的单个令牌。

由于解析器只关心令牌类型而不关心它的内容,它会告诉你它不知道如何处理它(因为它期待一个或两个{{1令牌,但有一个&#34;其他&#34;令牌)。因此它抱怨。

这就是为什么你应该永远不在真正小的(测试)语法之外使用那些间接词法分析器规则的原因。始终创建一个单独的词法分析器规则,这样您将始终可以看到语法中将包含哪些令牌类型。