ANTLR4:import和tokenVocab之间有什么区别?

时间:2015-03-03 10:10:29

标签: parsing import grammar antlr4 lexical-analysis

可以将import语句或tokenVocab选项放入解析器语法中以重用词法分析器语法。

Sam Harwell建议始终使用tokenVocab而不是import [1]。

importtokenVocab之间有什么区别吗?如果没有区别(Sam说要使用tokenVocab),为什么要有import语句?

  

[1]我实际上建议完全避免使用import语句   ANTLR。请改用tokenVocab功能。 [Sam Harwell]

请参阅ANTLR4: Unrecognized constant value in a lexer command

1 个答案:

答案 0 :(得分:10)

首先,我们来谈谈import

import的作用类似于C / C ++语言中的#include,它将src复制到dst。如果存在冲突,ANTLR4将尝试合并两个语法。

使用import有点令人沮丧,因为有很多限制因素:

  1. 并非每种语法都可以导入其他类型的语法。

    • Lexer语法可以导入lexer语法。
    • 解析器语法可以导入解析器语法。
    • 组合语法可以导入词法分析器或解析器语法。
  2. 导入时,语法中的options将被忽略。

  3. 导入时,词法分析器语法中不允许mode
  4. 因此,您实际上无法在解析器语法中导入词法分析器语法,因为它们不是同一类型。但是你可以用组合语法导入词法分析器。

    这些限制缩小了import的使用范围。我认为使用import的最佳情况是将一个大词法分析器或解析器语法分成几个部分,以便更容易管理。

    现在,请记住我们不能使用import在解析器语法中导入词法分析器语法?这就是为什么我们需要tokenVocab,它被设计为在解析器或组合语法中使用单独的词法分析器。

    上述结论将是:

    • 在词法分析器语法中,您只能使用import
    • 在解析器语法中,您只能使用import导入另一个解析器语法。您只能使用tokenVocab来使用其他词法分析器语法。
    • 在组合语法中,您可以同时使用importtokenVocab

    对于第三个,现在有什么不同?

    不同之处在于使用tokenVocab需要首先编译词法分析器,因为tokenVocab只是一个声明需要另一个语法的选项。使用import时不需要,因为它会将src复制到当前语法。

    例如,有三个语法文件:

    G1.g4

    grammar G1;
    r: B;
    

    G2.g4

    grammar G2;
    import G1
    

    G3.g4

    grammar G3;
    options { tokenVocab=G2; }
    t: A;
    

    如果我们直接编译G2,那就OK了。但是如果我们尝试编译G3,就会出现错误:

      

    错误(160):G3.g4:3:21:找不到令牌文件./G1.tokens

    但是,如果我们先编译G1,那么就会有G1.tokens。现在编译G3会很成功。