我对ANTLR不太熟悉,我有一个当前项目,需要从ANTLR3(版本3.5)合并到ANTLR4。我遍历本书并尝试了演示,所有这些都工作正常,但是我自己的项目给我带来了以下问题:
将ANTRL3项目转换为ANTLR4项目(解决所有警告和错误)之后,我能够构建lexer.h和lexer.cpp文件,但出现以下错误: 错误(33):缺少代码生成模板NonLocalAttrRefHeader 错误(33):缺少代码生成模板SetNonLocalAttrHeader (大约50次)。我在任何地方都找不到这些模板的任何引用。是否有人可以对这些错误消息有所了解?因为他们没有说任何关于行号的内容,也没有引用我完全看不到的其他代码。
我已经建立了一个测试环境,测试了演示g4文件。我已将g4文件从我的(VS2017)项目中拉出,并使用批处理文件分别尝试过。
由于缺少参考,因此我无法显示导致该问题的实际代码。我已经尝试了部分解析,但是还没有从中获得任何线索。
这些错误显示: 错误(33):缺少代码生成模板NonLocalAttrRefHeader 错误(33):缺少代码生成模板SetNonLocalAttrHeader
我已经构造了一个小例子来说明问题:
/*
* AMF Syntax definition for ANTLR.
*
*/
grammar amf;
options {
language = Cpp;
}
amf_group[amf::AmfGroup& amfGroup] locals [int jsonScope = 2]
: statements=amf_statements (GROUPSEP WS? LINE_COMMENT? EOL? | EOF)
{
amfGroup.SetStatements(std::move($statements.stmts));
}
;
amf_statements returns [amf::AmfStatements stmts]
: ( WS? ( stmt=amf_statement { stmts.emplace_back(std::move($stmt.value)); } WS? EOL) )*
;
amf_statement returns [amf::AmfStatementPtr value]
: (
{$amf_group::jsonScope == 1}? jsonparent_statement
| {$amf_group::jsonScope == 2}? jsonvalue_statement
)
{
value = std::move(context.expression(0).value);
}
;
jsonparent_statement returns [amf::AmfStatementPtr value] locals [int lineno=0]
:
(T_JSONPAR { $lineno = $T_JSONPAR.line;} ) WS (arg=integer_const)
{
value = std::make_shared<amf::JSONParentStatement>($lineno, nullptr);
}
;
jsonvalue_statement returns [amf::AmfStatementPtr value] locals [int lineno=0]
: ( T_JSONVALUE { $lineno = $T_JSONVALUE.line; } ) WS (arg=integer_const) (WS fmt=integer_const)?
{
value = std::make_shared<amf::JSONValueStatement>($lineno, std::move(arg), std::move(fmt));
}
;
integer_const returns [amf::AmfArgPtr value]
: p='%' (
(signed_int)
{
long num = std::stol($signed_int.text);
value = std::make_shared<amf::AmfArg>(ARG_TYPE::ARG_INTEGER, num);
}
| signed_float
{
value = std::make_shared<amf::AmfArg>(ARG_TYPE::ARG_INTEGER, std::stof($signed_float.text));
}
)
;
signed_int
: MINUS? INT;
signed_float
: MINUS? FLOAT;
T_JSONPAR : 'JSONPAR' | 'JSONPARENT';
T_JSONVALUE : 'JSONVAL' | 'JSONVALUE';
/* Special tokens */
GROUPSEP : '%%';
MINUS : '-';
INT : DIGIT+;
FLOAT
: DIGIT+ '.' DIGIT* EXPONENT?
| '.' DIGIT+ EXPONENT?
| DIGIT+ EXPONENT
;
ID : ('A'..'Z'|'_') ('A'..'Z'|'0'..'9'|'_')*
;
COMMENT
: ('/*' .*? '*/') -> channel(HIDDEN)
;
LINE_COMMENT
: ('//' ~('\n'|'\r')* '\r'?) -> channel(HIDDEN)
;
EOL : ('\r'? '\n');
QOUTED_STRING
: '"$' ( ESC_SEQ | ~('\\'|'"') )* '"'
;
SIMPLE_STRING
: '$' ~(' '|'\t'|'\r'|'\n')*
;
WS : (' '|'\t')+;
fragment
DIGIT
: '0'..'9'
;
fragment
EXPONENT
: 'E' ('+'|'-')? ('0'..'9')+
;
fragment
ESC_SEQ
: '\\' (
'R'
|'N'
|'T'
|'"'
|'\''
|'\\'
)
;
一旦添加amf_statement的谓词(在这种情况下为“缺少NonLocalAttrTefHeader的代码生成模板” 4次),就会发生错误。我尝试将输出语言更改为Python或CSharp,但这无济于事。
答案 0 :(得分:1)
仔细查看所有步骤后,我偶然发现执行Java命令的批处理命令中的一个小但很关键的区别:我使用了以前的antrl3批处理文件的副本,该文件使用java -jar选项执行antlr- 4.7.2-complete.jar代替cp并执行org.antlr.v4.Tool。一切似乎都进行得很好,命令行选项显示得很好,语法错误都就位,直到创建了实际的词法分析器和解析器代码:然后显示error(33),但仅在使用动态作用域的情况下,否则一切似乎进展顺利。
更新:我想我可以继续进行我的项目,但这只是部分解决方案:当我切换回Cpp输出时,返回了错误。标准输出和CSharp输出都可以,一旦尝试生成Cpp输出,我就会收到相同的错误,再次在使用动态作用域时出现:第25和26行。如果删除谓词,错误就会消失。
所以我仍然会遇到这些错误,但仅限于C ++。