【问题标题】:How to do proper error handling in BNFC? (C++, Flex, Bison)如何在 BNFC 中进行正确的错误处理? (C++、Flex、野牛)
【发布时间】:2015-02-10 11:33:12
【问题描述】:
我正在 BNFC 中制作一个编译器,它已经到了一个已经编译了一些东西并且代码可以在我的设备上运行的阶段。但在发布之前,我希望我的编译器在用户尝试编译无效程序时返回正确的错误消息。
我发现了 bison 如何在 stderr 流上写入错误并且我能够捕捉到这些错误。现在假设用户的代码没有语法错误,它只是引用了一个未定义的变量,我可以在我的访问者中捕捉到这个,但是我不知道行号是什么,我怎样才能找到行号?
【问题讨论】:
标签:
c++
bison
flex-lexer
bnfc
【解决方案1】:
在 bison 中,您可以使用变量 @$ 访问当前表达式的开始和结束位置,该变量包含具有成员 first_column、first_line、last_column 和 last_line 的结构。同样,@1 等分别包含子表达式 $1 等的相同信息。
为了以后可以访问相同的信息,您需要将其写入您的 ast.因此,在您的 AST 节点类型中添加一个字段来存储位置,然后在您的野牛文件中创建节点时设置该字段。
【解决方案2】:
(以前的答案更丰富)但是如果我们声明,在一些简单的解析器中
%option yylineno
在 flex 中,并在 yyerror 中打印,
yyerror(char *s) {
fprintf(stderr,"ERROR (line %d):before '%s'\n-%s",yylineno, yytext,s);
}
有时会有所帮助...