如何正确扩展ANTLR4语法?

如何正确扩展ANTLR4语法?,antlr4,Antlr4,我有一个要求,我想用语法B中定义的附加项扩展现有的语法a,以生成语法C 我已经尝试过在B中导入语法A,但这只选择了语法A中定义的某些内容。我的猜测是,在生成类时跳过了B中A未使用的内容。这是有道理的,因为要求不是继承而是混合/合并/组合这两个语法 为了便于理解(原始语法非常庞大),举个例子: 文件:A.g4: grammar A; keywords : X | Y | Z ; X: 'X'; Y: 'Y'; Z: 'Z'; grammar B; keyw

我有一个要求,我想用语法B中定义的附加项扩展现有的语法a,以生成语法C

我已经尝试过在B中导入语法A,但这只选择了语法A中定义的某些内容。我的猜测是,在生成类时跳过了B中A未使用的内容。这是有道理的,因为要求不是继承而是混合/合并/组合这两个语法

为了便于理解(原始语法非常庞大),举个例子:

文件:A.g4:

grammar A;

keywords
    : X
    | Y
    | Z
    ;

X: 'X';
Y: 'Y';
Z: 'Z'; 
grammar B;

keywords
    : A
    | B
    | C
    ;

A: 'A';
B: 'B';
C: 'C'; 
grammar C;

keywords
    : X
    | Y
    | Z
    | A
    | B
    | C
    ;

X: 'X';
Y: 'Y';
Z: 'Z';
A: 'A';
B: 'B';
C: 'C'; 
文件:B.g4:

grammar A;

keywords
    : X
    | Y
    | Z
    ;

X: 'X';
Y: 'Y';
Z: 'Z'; 
grammar B;

keywords
    : A
    | B
    | C
    ;

A: 'A';
B: 'B';
C: 'C'; 
grammar C;

keywords
    : X
    | Y
    | Z
    | A
    | B
    | C
    ;

X: 'X';
Y: 'Y';
Z: 'Z';
A: 'A';
B: 'B';
C: 'C'; 
文件:C.g4:

grammar A;

keywords
    : X
    | Y
    | Z
    ;

X: 'X';
Y: 'Y';
Z: 'Z'; 
grammar B;

keywords
    : A
    | B
    | C
    ;

A: 'A';
B: 'B';
C: 'C'; 
grammar C;

keywords
    : X
    | Y
    | Z
    | A
    | B
    | C
    ;

X: 'X';
Y: 'Y';
Z: 'Z';
A: 'A';
B: 'B';
C: 'C'; 
注意:我没有直接操作语法A的选项,但我希望保留语法A中的所有功能以及语法B中定义的其他规则/关键字等,如上所示


任何帮助都将不胜感激。谢谢。

语法导入可能无法按预期工作。导入语法中的规则优先于导入语法中的相同命名规则。因此,您不能覆盖主语法中的现有规则。另见:

将import看作更像一个智能include语句(它不包括已经定义的规则)

但是,应该可以重写第二个导入语法中的规则。在您的情况下,您不会在主语法中定义
关键字
(我假设这是
C
)。如果希望
B
's
关键字
规则优先于
A
中的规则,请按相反顺序导入语法
A
B

import B, A;
此标记文件中的图像也演示了这一点:


语法
G2
中的规则
r
被忽略,因为它是最后导入的,所以
G3
有点“覆盖”它。

语法导入可能无法按预期工作。导入语法中的规则优先于导入语法中的相同命名规则。因此,您不能覆盖主语法中的现有规则。另见:

将import看作更像一个智能include语句(它不包括已经定义的规则)

但是,应该可以重写第二个导入语法中的规则。在您的情况下,您不会在主语法中定义
关键字
(我假设这是
C
)。如果希望
B
's
关键字
规则优先于
A
中的规则,请按相反顺序导入语法
A
B

import B, A;
此标记文件中的图像也演示了这一点:


语法
G2
中的规则
r
被忽略,因为它是最后导入的,所以
G3
有点“覆盖”它。

所有语法都缺少导入语句。请添加它们。所有语法都缺少导入语句。mike,我理解导入是如何工作的,但这涉及到合并两个复合语法以创建第三个语法。我的回答应该会对您有所帮助。“因此您不能[覆盖]主语法中的现有规则”有点混乱。你的意思是B不能修改C中的规则吗?听起来OP并没有试图这么做,而是让B修改a中的规则。文档状态导入就像一个包含操作,它忽略了已经存在的规则。这应该清楚地表明,您不能覆盖导入语法中的规则。但是,如果您的导入语法导入了另外两个语法,并且它们都包含导入语法中不存在的规则,则此规则将导入其中。两者中的哪一个取决于导入语法的顺序。应该首先导入包含最终规则的语法(因为第二次导入不能再覆盖该规则)。这正是图中所示。mike,我理解导入是如何工作的,但这与合并两个复合语法以创建第三个语法有关。我的回答应该会对您有所帮助。“因此您不能[覆盖]主语法中的现有规则”有点让人困惑。你的意思是B不能修改C中的规则吗?听起来OP并没有试图这么做,而是让B修改a中的规则。文档状态导入就像一个包含操作,它忽略了已经存在的规则。这应该清楚地表明,您不能覆盖导入语法中的规则。但是,如果您的导入语法导入了另外两个语法,并且它们都包含导入语法中不存在的规则,则此规则将导入其中。两者中的哪一个取决于导入语法的顺序。应该首先导入包含最终规则的语法(因为第二次导入不能再覆盖该规则)。这正是图片所显示的。