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

Parsing ANTLR4:import和tokenVocab之间有什么区别吗?,parsing,import,grammar,antlr4,lexical-analysis,Parsing,Import,Grammar,Antlr4,Lexical Analysis,import语句或tokenVocab选项可以放在解析器语法中以重用lexer语法 Sam Harwell建议始终使用tokenVocab而不是import[1] import和tokenVocab之间有什么区别吗?如果没有区别(Sam说使用tokenVocab),那么为什么要使用import语句呢 [1] 事实上,我建议避免使用import语句 ANTLR。改用tokenVocab功能。[山姆·哈维尔] 请参见首先,让我们谈谈导入 import的功能类似于C/C++语言中的#include,它

import
语句或
tokenVocab
选项可以放在解析器语法中以重用lexer语法

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

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

[1] 事实上,我建议避免使用import语句 ANTLR。改用tokenVocab功能。[山姆·哈维尔]


请参见

首先,让我们谈谈导入

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

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

  • 不是每种语法都能导入其他语法

    • Lexer语法可以导入Lexer语法
    • 解析器语法可以导入解析器语法
    • 组合语法可以导入lexer或parser语法
  • 导入时,语法中的
    选项将被忽略

  • 导入时,lexer语法中不允许使用
    模式
  • 因此,实际上不能在解析器语法中导入lexer语法,因为它们不是同一类。但是您可以在组合语法中导入lexer

    这些限制缩小了
    import
    的使用范围。我认为使用
    import
    的最佳情况是将一个大的lexer或parser语法分成几个部分,以便于管理

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

    上述结论将是:

    • 在lexer语法中,只能使用
      import
    • 在解析器语法中,只能使用
      import
      导入另一个解析器语法。您只能使用
      tokenVocab
      来使用另一个lexer语法
    • 在组合语法中,您可以同时使用
      import
      tokenVocab
    对于第三个,现在有什么区别

    区别在于使用
    tokenVocab
    需要首先编译lexer,因为
    tokenVocab
    只是声明需要另一种语法的选项。使用
    import
    时不需要这样做,因为它会将src复制到当前语法中

    例如,有三个语法文件:

    G1.g4

    G2.g4

    G3.g4

    如果我们直接编译G2,就可以了。但如果我们试图编译G3,就会出现错误:

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

    但是,如果我们先编译G1,就会有G1.tokens。现在编译G3将是一个成功

    grammar G1;
    r: B;
    
    grammar G2;
    import G1
    
    grammar G3;
    options { tokenVocab=G2; }
    t: A;