如何在 BNFC 中进行正确的错误处理? (C++、Flex、Bison)

How to do proper error handling in BNFC? (C++, Flex, Bison)

我正在 BNFC 中制作一个编译器,它已经到了一个阶段,它已经编译了一些东西并且代码可以在我的设备上运行。但是在发布之前,我希望我的编译器在用户尝试编译无效程序时 return 正确的错误消息。

我发现 bison 如何在 stderr 流上写入错误并且我能够捕捉到这些错误。现在假设用户的代码没有语法错误,它只是引用了一个未定义的变量,我可以在我的访问者中捕捉到它,但我不知道行号是多少,我如何找到行号?

在 bison 中,您可以使用变量 @$ 访问当前表达式的开始和结束位置,该变量包含一个包含成员 first_columnfirst_line、[=13 的结构=] 和 last_line。类似地 @1 etc. 分别包含子表达式 $1 etc. 的相同信息。

为了以后访问相同的信息,您需要将其写入您的ast。因此,向您的 AST 节点类型添加一个字段以存储位置,然后在您的 bison 文件中创建节点时设置该字段。

(之前的答案更丰富)但是在一些简单的解析器中如果我们声明

%option yylineno

在flex中,在yyerror中打印出来,

yyerror(char *s) { 
  fprintf(stderr,"ERROR (line %d):before '%s'\n-%s",yylineno, yytext,s);
}

有时会有帮助...