在语法文件上为C ++运行Antlr4解析器会显示错误33:缺少代码生成模板NonLocalAttrRefHeader

时间:2019-05-24 21:37:58

标签: c++ antlr4

我对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,但这无济于事。

1 个答案:

答案 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 ++。