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