ANTLR3:在输入中使用已定义的标记代替ID时出现MissingTokenException

时间:2014-11-27 10:55:42

标签: antlr3

我在为create table编写语法规则时偶然发现了这个问题。当列名已经在语法中定义了令牌时,我的语法失败了(不能列名称'创建'匹配'创建'关键字!

Simple UseCase:

grammar hello;


start   :   
    'hello' 'world' ID 
    ;

ID : 'a'..'z'+ ;
WS : (' '|'\n'|'\r')+ {$channel=HIDDEN;} ;

对于这个语法,我如何制作" Hello World Hello"作为有效的输入。目前, MissingTokenException 失败了。

AST

                root
                 |   
                start
    __________________________________
    |              |                  |
  hello          World             MissingTokenException   

提前致谢。

编辑:

我找到了这个内联规则,而#34;你好"的定义规则&安培; "世界",仍然要找到它是如何工作的。

grammar hello;


stat: keyHELLO keyWORLD expr 
    ;

expr: ID
;

/** An ID whose text is "hello" */
keyHELLO : {input.LT(1).getText().equals("hello")}? ID ;

/** An ID whose text is "world" */
keyWORLD : {input.LT(1).getText().equals("world")}? ID ;
    // END:rules

ID : 'a'..'z'+ ;
WS : (' '|'\n'|'\r')+ {$channel=HIDDEN;} ;

AST

                root
                 |   
                start
    __________________________________
    |              |                  |
 keyHello        keyWorld             expr   
    |               |                  |
  hello           world             world

希望它可能会有所帮助。

1 个答案:

答案 0 :(得分:0)

当您解析某种语言时,他们总是拥有"保留字"。没有它们几乎不可能工作。在您的情况下,您有两种选择:

  1. 定义一组保留字并使您的ID成为其延伸。我不推荐你这种可能性,因为当你使用整个语法时,或者当你使用词法分析器 - 树时,这将是一个可怕的混乱,并且你想用一些令牌或保留词做出不同的东西(也许跳过它们。)

    RW: 'hello' | 'world';
    
    ID: 'a'..'z'+ | RW;
    
  2. 在这种情况下,您将能够确定何时解析RW而不是ID,因为ID和RW都遵循相同的规则......

    1. 选择其他保留字,优于'你好'或类似的普通词。对我来说,这是最好的选择。
    2. 以第二个选项为例,您可以定义一个除了这些新闻ID之外的子组,我告诉您。您还可以在词汇表中选择一组选定的单词(' world',' hello'等),并在树中处理不同的单词。

      我希望这会对你有所帮助!!