代码之家  ›  专栏  ›  技术社区  ›  smwikipedia

ANTLR如何决定应用哪个lexer规则?最长匹配lexer规则获胜?

  •  3
  • smwikipedia  · 技术社区  · 8 年前

    输入内容:

    enter image description here

    grammar test;
    
    p : EOF;
    
    Char : [a-z];
    
    fragment Tab : '\t';
    fragment Space : ' ';
    T1 : (Tab|Space)+ ->skip;
    
    T2 : '#' T1+ Char+;
    

    匹配结果如下:

    [@0,0:6='#   abc',<T2>,1:0]    <<<<<<<< PLACE 1
    [@1,7:6='<EOF>',<EOF>,1:7]
    line 1:0 extraneous input '#   abc' expecting <EOF>
    

    地点1 T2 .

    在语法文件中 T2 lexer规则失效 T1 lexer规则。所以我想 T1 应首先应用规则。那么为什么在 # abc 是否未跳过?

    3 回复  |  直到 8 年前
        1
  •  6
  •   Community Mohan Dere    5 年前

    按以下顺序适用三条规则:

    1. 最长的比赛先赢。
    2. # 在你的语法中)下一步。
    3. 最后,在平局的情况下(按匹配长度),匹配规则中最早列出的规则获胜。

    ANTLR 4 Lexer通常具有最长的匹配获胜行为,而不考虑备选方案在语法中出现的顺序。如果两个lexer规则匹配相同的最长输入序列,则只有比较这些规则的相对顺序才能确定如何分配令牌类型。

    一旦lexer达到非贪婪的可选或闭包,规则内的行为就会改变。从那一刻起直到规则结束,该规则内的所有备选方案都将被视为有序的,具有最低备选方案的路径将获胜。由于我们在底层ATN表示中排序备选方案的方式,这种看似奇怪的行为实际上是非贪婪处理的原因。当lexer处于该模式并到达块(ESC |)时,排序约束要求它在可能的情况下使用ESC。

    “隐式令牌”规则来自 here

        2
  •  1
  •   David J. user3890638    5 年前

    …我将引用ANTLR4的 Wildcard Operator and Nongreedy Subrules 文档

    1. 主要目标是匹配识别最多输入字符的lexer规则。
    INT : [0-9]+ ;
    DOT : '.' ; // match period
    FLOAT : [0-9]+ '.' ; // match FLOAT upon '34.' not INT then DOT
    
    1. 如果有多个lexer规则匹配同一输入序列,则优先级将转到语法文件中首先出现的规则。
    DOC : '/**' .*? '*/' ; // both rules match /** foo */, resolve to DOC
    CMT : '/*' .*? '*/' ;
    
    /** Match anything except \n inside of double angle brackets */
    STRING : '<<' ~'\n'*? '>>' ; // Input '<<foo>>>>' matches STRING then END
    END    : '>>' ;
    
    1. 在通过词汇规则中的非reedy子规则后,从那时起所有的决策都是“第一场比赛获胜”

    例如,文字 ab 规则右侧(语法片段) .*? ('a'|'ab') ab公司 .这个怪癖源于一个不灵活的设计决策,在这里太复杂了。

    我鼓励你也复习 TomServo's answer ,它更多地讨论了隐式令牌规则。

    the lexer rules docs .)

        3
  •  0
  •   smwikipedia    8 年前

    我认为这是因为ANTLR首先看到 # T2 规则幸运的是, 比赛。如果ANTLR看到 首先,它将沿着 T1

    推荐文章