最初的 Headers 问题是:为什么我的词法分析器规则不起作用,直到我将其更改为解析器规则?以下内容与此问题有关 . 然后我找到了新的信息并更改了 Headers 问题 . 请看我的评论!
我的Antlr语法(只有“空格”规则,它的使用很重要):
grammar MyTest;
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\u2014\u201e\u2022/><§&{}#*~+\\];
Spaces: Space (Space Space?)?;
Sign: Prefix | Suffix | Special ;
LatinNumber
: 'I' ('I' 'I'?)?
| 'I'? 'V' ('I' ('I' 'I'?)?)?
| 'I'? 'X' ('I' ('I' 'I'?)?)? 'V'? ('I' ('I' 'I'?)?)? ;
YearNumber
: '(' '1' '9' Digit Digit ')'
| '[' '1' '9' Digit Digit ']'
| '1' '9' Digit Digit;
OtherNumber
: [1-9] Digit* ;
Numbers
: LatinNumber | YearNumber | OtherNumber;
NormalNumbers
: Prefix? Numbers Suffix?;
Word: Prefix? Char Char+ Suffix?;
line: Break Spaces? ((Word | NormalNumbers) Spaces?)+ ;
myTest: line ;
示例输入:
Something-和Somethingmore位于达拉斯的某个地方,2012年 . 99.2013(2014)维基百科的一些文本和内容示例伊利诺伊百年纪念半美元是1918年美国薄荷局拍摄的纪念性五十美分作品 . 正面描绘亚伯拉罕·林肯,由酋长设计Engraver George T. Morgan;基于伊利诺伊州印章的反面图像由他的助手兼继任者约翰·R·辛诺克完成 . https://en.wikipedia.org/wiki/Illinois_Centennial_half_dollar
控制台输出
line 2:10 extraneous input ' ' expecting {<EOF>, NormalNumbers, Word}
ParseTree:
(myTest (line \n Something- and))
Improved ParseTree:
'- myTest
|- TOKEN[type: 3, text: \n]
|- TOKEN[type: 16, text: Something-]
|- TOKEN[type: 1, text: ]
'- TOKEN[type: 16, text: and]
所以输出声明在我的输入的第一个“Something-”之后就出现了问题,即空格即将来临 - 在我的语法中称为Space . 因为我的输入来自ocr源,所以可以有多个空格,但另一方面我需要识别空格,因为它们对文本结构有意义 . 出于这个原因,在我的语法中我定义了
Spaces: Space (Space Space?)?;
但这会抛出上面的错误 - 空格不被识别 . 所以当我用语法中的解析器规则(小写!)替换它时
spaces: Space (Space Space?)?;
而且在这里
line: Break spaces? ((Word | NormalNumbers) spaces?)+ ;
错误似乎得到解决(后续错误出现 - 不是这个问题的一部分) .
So why is the error solved then in this concrete case when using a parser rule instead of a lexer rule? And in general - when to use a lexer rule and when a parser rule?
感谢你们!
1 回答
单个空格被识别为
Space
而不是Spaces
,因为它匹配两个词法规则并且Space
在语法文件中首先出现 . (您可以看到令牌类型1被识别;Spaces
将是我的计数类型9 . )Antlr使用常见的词法策略,其中识别的词汇标记对应于最长可能的匹配,如果两个模式匹配相同的最长匹配,则按文件中的顺序排序可能性 . 当您将
Spaces
放在文件中时,它会赢得平局规则 . 如果你使它成为解析器规则而不是词法规则,那么它将在Space
的明确词法规则之后应用 .你真的只想要允许最多3个空格吗?否则,您可以放弃
Space
并将Spaces
定义为" "*
.