在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解决这些错误?有人有什么建议吗?
答案 0 :(得分:0)
从功能上来说,规则返回值中指定的内容实际上不是返回值。取而代之的是,表示规则的上下文将获得一个新的成员字段,该字段采用“返回”值。鉴于试图像C ++函数那样处理解析器规则没有任何意义,因此它们根本不可比。
除了处理语法中的所有字段外,我建议采用另一种方法:使用ANTLR4,您将获得一个解析树(如果启用),该树使用解析规则上下文表示匹配的规则(这是以前生成的规则的超级视图) AST)。该上下文包含所有已解析的值。解析运行后(通常称为语义阶段),您只需要在第二步中使用侦听器来遍历该树,拾取这些值并从中创建您自己的数据结构即可。这种分离还允许您使用解析器进行快速语法检查,因为您无需在解析运行中进行所有繁重的工作。