保持ANTLR4语法目标独立的方法 我正在为C++目标编写语法,但是我希望它也能与java一起工作,因为ANTLR带有伟大的工具,用于java目标的语法。这本书(“权威的ANTLR 4参考”)说,实现目标独立性的方法是使用听众和/或访问者。但有一个问题。我可能需要的任何谓词、局部变量、自定义构造函数、自定义标记类等都会引入无法删除的目标语言依赖性,至少根据我从书中获得的信息是这样的。由于这本书可能已经过时,以下是问题:

保持ANTLR4语法目标独立的方法 我正在为C++目标编写语法,但是我希望它也能与java一起工作,因为ANTLR带有伟大的工具,用于java目标的语法。这本书(“权威的ANTLR 4参考”)说,实现目标独立性的方法是使用听众和/或访问者。但有一个问题。我可能需要的任何谓词、局部变量、自定义构造函数、自定义标记类等都会引入无法删除的目标语言依赖性,至少根据我从书中获得的信息是这样的。由于这本书可能已经过时,以下是问题:,antlr4,Antlr4,有没有一种方法可以以独立于语言的方式声明基元变量,比如: item[$bool hasAttr] : type ( { $hasAttr }? attr | ) ID ; parser grammar testParser; options { tokenVocab=testLexer; } @header <lang=Cpp>{ #include "utils/helper.h" } <lang=Java>{ import test.utils.THelper;

有没有一种方法可以以独立于语言的方式声明基元变量,比如:

item[$bool hasAttr]
:
  type ( { $hasAttr }? attr | ) ID
;
parser grammar testParser;
options
{
tokenVocab=testLexer;
}

@header
<lang=Cpp>{
#include "utils/helper.h"
}
<lang=Java>{
import test.utils.THelper;
}

@members
<lang=Cpp>{
public:
  testParser(antlr4::TokenStream *input, utils::THelper *helper);

private:
  utils::THelper *Helper;

public:
}
<lang=Java>{
public testParser(TokenStream input, THelper helper) {
  this(input);
  Helper = helper;
}

private THelper Helper;
}

start
:
  (
  <lang=Cpp>{ Helper->OnUnitStart(this); }
  <lang=Java>{ Helper.OnUnitStart(this); }
  unit
  <lang=Cpp>{ _localctx = Helper->OnUnitEnd(this); }
  <lang=Java>{ _localctx = Helper.OnUnitEnd(this); }
  )*
  EOF
;

...
<> >代码> $BOOL将被翻译成C++中的代码> BoOL <代码>,但java中的<>代码>布尔< /代码>(在这种情况下,工作将是使用<代码> int /代码>,但很可能不在所有潜在目标中)

是否有一种方法可以声明某些代码片段仅用于特定目标,例如:

item[$bool hasAttr]
:
  type ( { $hasAttr }? attr | ) ID
;
parser grammar testParser;
options
{
tokenVocab=testLexer;
}

@header
<lang=Cpp>{
#include "utils/helper.h"
}
<lang=Java>{
import test.utils.THelper;
}

@members
<lang=Cpp>{
public:
  testParser(antlr4::TokenStream *input, utils::THelper *helper);

private:
  utils::THelper *Helper;

public:
}
<lang=Java>{
public testParser(TokenStream input, THelper helper) {
  this(input);
  Helper = helper;
}

private THelper Helper;
}

start
:
  (
  <lang=Cpp>{ Helper->OnUnitStart(this); }
  <lang=Java>{ Helper.OnUnitStart(this); }
  unit
  <lang=Cpp>{ _localctx = Helper->OnUnitEnd(this); }
  <lang=Java>{ _localctx = Helper.OnUnitEnd(this); }
  )*
  EOF
;

...
parser语法测试parser;
选择权
{
tokenVocab=testLexer;
}
@标题
{
#包括“utils/helper.h”
}
{
导入test.utils.THelper;
}
@成员
{
公众:
testParser(antlr4::TokenStream*input,utils::THelper*helper);
私人:
utils::THelper*助手;
公众:
}
{
公共测试解析器(令牌流输入,THelper助手){
这(输入);
助手=助手;
}
私人佣工;
}
开始
:
(
{Helper->OnUnitStart(this);}
{Helper.OnUnitStart(this);}
单元
{{u localctx=Helper->OnUnitEnd(this);}
{{u localctx=Helper.OnUnitEnd(this);}
)*
EOF
;
...
暂时保持两个单独的语法改变java一个,并且在我对结果满意的同时,将这些变化合并到C++中,但是如果可能的话
我宁愿把它保存在一个文件中。

这个目标依赖关系是一个非常讨厌的问题,我已经在考虑如何以一种好的方式消除它。还没有找到完全可用的东西

<>你可以做的是保持java和C++都能理解的语法(例如,写一个谓词,比如函数调用:<代码>:{ISValueU.S.}),B C;<代码>,并在派生派生类的基类中实现这些函数(ANTLR允许通过语法选项指定这样的基类:代码>超类< /C> >)。
< C++ C++目标还获得了一些额外的信息,你可以用来指定C++特定的东西。

嗨,迈克!我正在用函数调用来处理同样的方法。我将计划使用它来处理新的JavaScript语法。在官方的存储库中可以找到一个具有可怕的运行时依赖和重复代码的旧版本。我将上传它。至少对于秋季的C#和Java运行时来说是这样。此外,我还考虑了如何将其用于JavaScript和Python运行时(正如您在google小组中提到的,他们在
self
前缀和其他语法方面遇到了一些麻烦)。噢,非常欢迎对JS语法进行更新。它是否支持最新的ES6/7功能?我首先针对ES6功能,这些示例:在我们的Positive Technologies fork上提供了一个通用函数调用的草稿:@Mike Thanke you,额外的命名操作看起来非常有用。不过我发现了一些奇怪的地方-而
@parser::listenerdeclarations
和所有类似的都放在类公共区域,而
@parser::listenermembers
和类似的都放在私有区域,主
@parser::declarations
@parser::members
的行为正好相反。嗯,该死,这不应该发生。应该是一致的。你能提交一份bug报告吗为了这个?