我可以在 ANTLR4 中使用类似于 c++ 的虚拟令牌(具有相同返回值的令牌)吗?

Can I use virtual tokens (tokens with identical return value) in ANTLR4 similar to c++?

本文关键字:令牌 返回值 虚拟 ANTLR4 c++ 类似于 我可以      更新时间:2023-10-16

C++我可以使用虚函数来处理来自具有相同父/祖先的类似类的数据,ANTLR4 是否支持此功能,我必须如何设置语法?

我尝试设置一个语法,使用具有相同返回值的参数,并在包含不同"子类化"令牌的令牌中使用该值。

这是我尝试使用的一些代码:

amf_group 
: statements=amf_statements (GROUPSEP WS? LINE_COMMENT? EOL? | EOF)
;
amf_statements returns [amf::AmfStatements stmts]
: ( WS? ( stmt=amf_statement { stmts.emplace_back(std::move($stmt.stmtptr)); } WS? EOL) )*
;
amf_statement returns [amf::AmfStatementPtr stmtptr] 
: (
stmt = jsonparent_statement 
| stmt = jsonvalue_statement
)
{ 
$stmtptr = std::move($stmt.stmtptr);
}
;
jsonparent_statement returns [amf::AmfStatementPtr stmtptr] locals [int lineno=0]
:
(T_JSONPAR      { $lineno = $T_JSONPAR.line;} )  WS (arg=integer_const)
{
$stmtptr = std::make_shared<amf::JSONParentStatement>($lineno, nullptr);
}
;
jsonvalue_statement returns [amf::AmfStatementPtr stmtptr] locals [int lineno=0]
: ( T_JSONVALUE { $lineno = $T_JSONVALUE.line; } ) WS (arg=integer_const) (WS fmt=integer_const)?
{
$stmtptr = std::make_shared<amf::JSONValueStatement>($lineno, std::move($arg.argptr), std::move($fmt.argptr));
}
;

我收到以下错误:

错误 (75): amf1.g4:23:10:标签 stmt=jsonvalue_statement 类型与以前的定义不匹配:stmt=jsonparent_statement

这个错误当然是很合乎逻辑的,因为标记确实是不同类型的,但返回值类型是相同的。对于两个(虚拟)令牌,我可以单独编写所有代码,但就我而言,我有一些 40+ 不同的标记表示参数或语句,编写所有组合会很麻烦。顺便说一下,上面的代码确实在 Antlr3 中工作。

有没有另一种方法可以使用ANTLR4解决这些错误?有人有什么建议吗?

规则返回值中指定的内容并不是函数意义上的真正返回值。相反,表示规则的上下文将获得一个采用"return"值的新成员字段。鉴于试图将解析器规则视为C++函数是没有意义的,因此它们根本没有可比性。

与其处理语法中的所有字段,我建议采用不同的方法:使用 ANTLR4,您将获得一个解析树(如果启用),它使用解析规则上下文(这是先前生成的 AST 的超级视图)表示匹配的规则。此上下文包含已分析出的所有值。你只需要在解析运行后的第二步(通常称为语义阶段)中有一个侦听器来遍历这棵树,选取这些值并从中创建自己的数据结构。这种分离还允许使用解析器进行快速语法检查,因为您不会在解析运行中完成所有繁重的工作。