Antlr - 是否有任何正式的解释,为什么首先定义的词法分析器规则对后面定义的解析器规则不可见?

时间:2018-01-16 15:57:57

标签: parsing whitespace antlr antlr4 lexer

最初的标题问题是:为什么我的词法分析器规则不起作用,直到我将其更改为解析器规则?以下内容与此问题有关。然后我找到了新的信息并更改了标题问题。请看我的评论!

我的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 ;

示例输入:

  

东西 - 还有位置

     

位于某处

     

达拉斯,2012年

     

在。 99.2013(2014)

     

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

     

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?)+ ;

错误似乎已经解决(出现后续错误 - 不是此问题的一部分)。

那么为什么在使用解析器规则而不是词法分析器规则时,在这个具体情况下解决了错误? 一般来说 - 何时使用词法分析器规则和解析器规则?

谢谢你们,伙计们!

1 个答案:

答案 0 :(得分:0)

单个空格被识别为Space而不是Spaces,因为它匹配两个词法规则,而Space首先出现在语法文件中。 (您可以看到令牌类型1被识别; Spaces将被我的计数类型为9。)

Antlr使用常见的&#34;最大的咀嚼&#34;词法策略,其中识别的词汇标记对应于最长可能的匹配,如果两个模式匹配相同的最长匹配,则按文件中的顺序排序可能性。当您将Spaces放在文件中时,它会赢得平局规则。如果你使它成为解析器规则而不是词法规则,那么它将在Space的明确词法规则之后应用。

你真的只想要允许最多3个空格吗?否则,您可以放弃Space并将Spaces定义为" "*