【问题标题】:Setting source filename in C++ target在 C++ 目标中设置源文件名
【发布时间】:2020-09-19 12:11:44
【问题描述】:

我有一个代码预处理器,它在源代码中插入一个#line 指令。该指令包含文件名、行号和字符位置。我有一个 #line 指令的词法分析器规则,它调用一个名为 newFile 的函数。 newFile 函数设置词法分析器的行号和字符位置。但是,我看不到设置源名称的方法。有一些函数可以获取源名称,但不能设置它。我尝试设置输入流源名称,但这似乎不起作用(我有一个errorListener,它从recognizer->getInputStream()->getSourceName() 获取文件名,但它总是返回初始文件名)。

我的代码是(C++目标):

preprocessor pp(_defines, _incpaths);
ANTLRInputStream input(pp.preprocess(filename));
myLexer lexer(&input);
CommonTokenStream tokens(&lexer);
myParser parser(&tokens);
antlr4::tree::ParseTree* tree = parser.start();

而且,newFile 代码是:

void myLexer::newFile (std::string newFilename, int newLine, int newPos)
{
    static_cast<ANTLRInputStream*>(_input)->name = newFilename;   // doesn't work
    setLine(newLine);
    setCharPositionInLine(newPos);
}

感谢所有帮助。

【问题讨论】:

    标签: c++ antlr filenames antlr4 preprocessor


    【解决方案1】:

    没有这样的内置功能。将此信息保存在单独的结构中并在那里管理更改。输入流名称只是一个方便的特性,对于那种处理来说不够灵活。

    【讨论】:

      【解决方案2】:

      感谢您的信息。我尝试了几种不同的方法将文件/位置信息存储在单独的结构中,但很快就变得过于复杂了。

      我利用 Antlr 的线路跟踪功能解决了这个问题。我将文件名存储在一个列表中,然后将文件名的列表索引编码为行号。

      int fileIndex = filename_list.size();
      filename_list.append(filename);
      int line = (fileIndex << 20) + newLine;
      setLine(line);
      setCharPositionInLine(newPos);
      

      然后,在 errorListener 或 AST 构建器中,很容易访问文件名:

      void errorListener::syntaxError(Recognizer* recognizer......)
      {
         int fileIndex = line >> 20;
         line &= 0xFFFFF;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多