微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

没有可行的替代解析宏和覆盖

如何解决没有可行的替代解析宏和覆盖

使用这个 https://github.com/antlr/grammars-v4/tree/master/cpp antlr 语法我正在尝试解析 C++ 代码。下面是我正在使用的同一个访问者类,我没有实现太多的访问者功能

#include <iostream>
#include <antlr4-runtime.h>

#include "parser/CPP14Lexer.h"
#include "parser/CPP14BaseVisitor.h"
#include "parser/CPP14Parser.h"
#include "parser/CPP14Visitor.h"


class TREEVisitor : public CPP14BaseVisitor {
    public:
        virtual antlrcpp::Any TREEVisitor::visitFunctionBody(
            CPP14Parser::FunctionBodyContext *ctx) override
        {
            std::cout << ctx->getText() << std::endl;
            return visitChildren(ctx);
        }
};


int main(int argc,char *argv[]) {

    std::ifstream stream;
    stream.open(argv[1]);
    antlr4::ANTLRInputStream input(stream);
    CPP14Lexer lexer(&input);
    antlr4::CommonTokenStream tokens(&lexer);
    CPP14Parser parser(&tokens);
    antlr4::tree::ParseTree *tree = parser.translationunit();

    // Visitor
    auto *visitor = new TREEVisitor();
    visitor->visit(tree);

    return 0;
}

我正在尝试解析以下 C++ 代码

#include <atomic>

#define RUN_ONCE                                       \
    for (static std::atomic<int> _run_already_(false); \
         !_run_already_.fetch_or(true);)               \

void foo()
{
    RUN_ONCE
    {
        printf("Hello only once!\n");
        /* Other statements follow */
    }
}

然后我收到以下消息

line 11:36 no viable alternative at input 'voidfoo(){RUN_ONCE{printf("Hello only once!\n");'
line 14:0 extraneous input '}' expecting <EOF>

RUN_ONCE{} 有问题,但我不确定如何解决这个问题?

我有一个名为 override 的变量时,我遇到了同样的问题!

void foo()
{
    std::string override;
}

我收到以下消息,

line 9:16 no viable alternative at input 'voidfoo(){std::stringoverride'
line 9:24 mismatched input ';' expecting {'try','{','=',':'}
line 10:0 extraneous input '}' expecting <EOF>

我不介意忽略 override 并且不再将其视为 C++ 关键字。我不知道我应该如何修改我的语法。

非常感谢您为解决此问题而提供的答案。

谢谢, 亚历克斯

解决方法

您使用的 C++ 语法并不真正支持宏¹。它只是在词法分析期间跳过以 # 开头的行,然后假定源的其余部分在没有任何宏处理的情况下在语法上是有效的。在您的代码中显然不是这种情况,这就是它不起作用的原因。

在将代码传递给解析器之前,您需要通过现有的预处理器传递代码,或者实现自己的预处理器。

您的第二个问题是由于语法将 override 视为关键字,而它应该是上下文关键字,即它仍然应该被允许作为标识符。您可以通过为匹配上下文关键字以及 Identifier 的标识符创建一个非终结符来解决这个问题,然后在当前使用 Identifier 的任何地方使用它。


¹ 这是可以预料的。您无法真正使用单一语法解析未经预处理的 C 或 C++。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。