1

如何获取错误的行号和列号(即字符串的哪一部分不符合语法规则)?我正在使用 yacc 解析器来检查语法。谢谢你。

4

1 回答 1

1

您最好阅读Dragon bookaho book,它们解释并展示了如何编写基于 lex/yacc 的编译器的示例。

为了得到错误的行/列,你应该让你的词法分析器保留列和行。所以在你的词法分析器中,你必须声明两个全局变量,SourceLine并且SourceCol(当然你可以使用更好的非驼峰命名)。

在每个令牌生产中,您必须计算所生产令牌的列,为此我使用如下宏:

#define Return(a, b, c)    \
{\
    SourceCol = (SourceCol + yyleng) * c; \
    DPRINT ("## Source line: %d, returned token: "a".\n", SourceLine); \
    return b; \
}

使用该宏的令牌生产是:

"for" { Return("FOR", FOR, 1);

然后为了保留行,对于创建新行的每个标记,我正在使用:

{NEWLINES}     {
    BEGIN(INITIAL);
    SourceLine += yyleng;
    Return("LINE", LINE, 0);
}

然后在您的解析器中,您可以获得SourceCol并且SourceLine如果您将它们声明为外部全局变量:

extern unsigned int SourceCol;
extern unsigned int SourceLine;

现在在您的parse_error语法制作中,您可以执行以下操作:

parse_error : LEXERROR
{ 
    printf("OMG! Your code sucks at line %u and col %u!", SourceLine, SourceCol); 
}

当然,您可能想要添加yytext、处理更详细的错误消息等。但这一切都取决于您!

于 2013-06-05T12:49:05.317 回答