我正在为C ++目标编写语法,但是我还想继续使用Java,因为ANTLR带有适用于具有Java目标的语法的优秀工具。本书(“The Definitive ANTLR 4 Reference”)表示,实现目标独立性的方法是使用听众和/或访问者。但是有一个问题。我可能需要的任何谓词,局部变量,自定义构造函数,自定义标记类等引入了无法删除的目标语言依赖性,至少根据我从本书中获取的信息。由于这本书可能已经过时,所以问题是:
是否有一种以语言无关的方式声明原始变量的方法,如:
item[$bool hasAttr]
:
type ( { $hasAttr }? attr | ) ID
;
其中$bool
将在C ++中转换为bool
,但在Java中转换为boolean
(在这种情况下,解决方法是使用int
但很可能并非全部潜在目标)
是否有办法声明某些代码片段仅用于特定目标,例如:
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
;
...
目前我正在保留两个单独的语法来改变Java,并且一旦我对结果感到满意,就将更改合并到C ++中,但是如果可能的话 我宁愿将它保存在一个文件中。
答案 0 :(得分:1)
这个目标依赖是一个真正的麻烦,我已经思考了一段时间已经如何以一种好的方式摆脱它。 Haven仍然发现了一些完全可用的东西。
您可以做的是保持Java和C ++都能理解的语法(例如,编写一个类似函数调用的谓词:a: { isValid() }? b c;
,并在从中派生解析器的基类中实现这些函数(ANTLR)允许通过语法选项superClass
)指定这样的基类。
C ++目标还有一些额外的named actions,您可以使用它们来指定C ++特定的东西。