ANTLR尝试在更长的令牌中匹配令牌

时间:2012-08-10 12:59:05

标签: antlr3

我是ANTLR的新手,并在ANTLRWorks1.4.3中尝试遵循语法。

command
:   'go' SPACE+ 'to' SPACE+ destination
;

destination
:   (UPPER | LOWER) (UPPER | LOWER | DIGIT)*
;

SPACE
:   ' '
;

UPPER
:   'A'..'Z'
;

LOWER
:   'a'..'z'
;

DIGIT
:   '0'..'9'
;

这似乎工作正常,除非'目的地'包含关键字'go'和'to'的前两个字符。 例如,如果我给出以下命令:

go to Glasgo

节点树显示如下:

enter image description here

我期待它将填充词与目标匹配。

我甚至尝试更改关键字,例如'travel'而不是'go'。在这种情况下,如果目的地中有'tr',ANTLR会抱怨。

知道为什么会这样吗?以及如何解决这个问题?

提前致谢。

1 个答案:

答案 0 :(得分:1)

ANTLR词法分析器和解析器是严格分开的。您的输入首先被标记化,然后解析器规则对所述标记进行操作。

在您的情况下,输入go to Glasgo被标记为以下X标记:

  1. 'go'
  2. ' '(SPACE)
  3. 'to'
  4. 'G'(UPPER)
  5. 'l'(LOWER)
  6. 'a'(LOWER)
  7. 's'(LOWER)
  8. 'go'
  9. 留下了“悬空”'go'关键字。这就是ANTLR的词法分析器的工作原理:你无法改变它。

    在您的情况下,一个可能的解决方案是使destination成为词法分析器规则而不是解析器规则:

    command
    :   'go' 'to' DESTINATION
    ;
    
    DESTINATION
    :   (UPPER | LOWER) (UPPER | LOWER | DIGIT)*
    ;
    
    SPACE
    :   ' ' {skip();}
    ;
    
    fragment UPPER
    :   'A'..'Z'
    ;
    
    fragment LOWER
    :   'a'..'z'
    ;
    
    fragment DIGIT
    :   '0'..'9'
    ;
    

    导致:

    enter image description here


    如果您不完全确定两者之间的区别,请参阅:Practical difference between parser rules and lexer rules in ANTLR?

    有关fragment s的更多信息:What does "fragment" mean in ANTLR?


    PS。 Glasgo的瓦特吗?