问题描述
我有一个代码预处理器,该预处理器在源代码中插入一个#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);
}
感谢所有帮助。
解决方法
没有类似的内置功能。将这些信息保存在单独的结构中,并在那里进行更改。输入流名称只是一个方便的功能,对于这种处理来说不够灵活。
,感谢您的信息。我尝试了几种不同的方法来将文件/位置信息存储在单独的结构中,但很快变得过于复杂。
我通过利用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;