2012-04-15 113 views
4

几乎所有的编译器都会返回一个行号和错误消息。我想知道在编译器设计的角度来看,编译器如何根据不同的阶段处理行号消息?谢谢。编译器如何处理运行时错误消息中的行号

  • 扫描仪
  • 分析器
  • AST数据结构
  • 代码生成

在附加:

  • 运行时环境
  • 机解释
+0

运行时和机器解释器不是编译器的组成部分。 – 2012-04-15 15:10:41

+0

谢谢。我编辑了一些问题。 – 2012-04-15 15:12:42

回答

1

我已经为我的类分配实现了一个相当简单的编译器。这是Pascal的一个子集,还有其他一些限制。

编译器是一种将一种语言翻译为另一种语言的工具。它通过执行错误检查然后生成输出代码(如果可能)。通常,编译器的管道是大致等效于:

输入代码 - >词法分析器(扫描仪) - >语法分析器 - >语义 分析器 - >代码生成器 - >输出代码*

因为我的语言很简单,所以我可以做一些假设,例如一条指令将只在一行中。我的Lexer使用正则表达式来检查不应该存在的字符,例如“不是数字,字母”的字符(“”,“,”“。”等等。“我将文件读入字符串列表中,其中每个字符串都是下一行,所以如果我扫描一行并发现错误,则返回索引+ 1,其是行的数目。

随着其检查例如该算法是类似的“如果一个变量名称以字母开头的”语法分析器(解析器)。

当我延伸解析器我将代码中的代码与代码中的行相关联,以便在发生错误时将其返回。

我不知道现代编译器如何解决此问题,但我可以猜测这也是某种AST和行号的关联记住一个AST可能在几行(好,这是语言的依赖)。

使用代码生成编译器知道代码是正确的(就他们的知识而言),并且返回错误不是关于代码,而是编译器或进程存在问题(错误,内存不足,不能写入位置等)。

运行环境和机器解释也可以有编译器,例如, JIT,但错误消息返回通常表示编译器或运行时错误,而不是代码。

*请注意,这是3道次的非常简单的模型。 Modern compilers have a lot more

编辑:我发现AST有一个字段,指示行号和文件的错误(每个节点)。

0

大多数词法分析器和分析器生成器将生成具有错误报告方法的代码,这些方法在发生匹配错误时被调用。你可以重写该方法,并做你喜欢的事情。

如前所述,在词法分析器规范中,将行和字符号与标识符或字符串/ char/integer /布尔文字相关联是很常见的。通常词法分析器会提供一个yyline()方法来执行此操作。而不是让词法分析器返回一个原始标记(例如字符串)值,让它返回一个包含字符串值,字符和行号的对象。例如,快速浏览this词法分析器规范。

private Symbol symbol(int type) { 
    return new Symbol(type, yyline, yycolumn); 
} 

解析器将在解析过程中收到符号,并应将位置信息和令牌值一起插入AST节点。这些信息最终应该在符号表中找到。在类型分析过程中,每个叶节点都会绑定位置信息。这应该是您需要提供相当好的错误诊断的全部内容。

相关问题