Compiler construction 编译器如何处理运行时错误消息中的行号

Compiler construction 编译器如何处理运行时错误消息中的行号,compiler-construction,runtime,lexical-analysis,Compiler Construction,Runtime,Lexical Analysis,几乎所有编译器都会返回一个行号和错误消息。我想知道,从编译器设计的角度来看,编译器是如何处理以下不同阶段的行号消息的?谢谢 扫描器 分析器 AST数据结构 代码生成 此外: 运行时环境 机器翻译 我已经为我的类分配实现了一个相当简单的编译器。它是Pascal的一个子集,还有一些其他限制 编译器是一种将一种语言翻译成另一种语言的工具。它通过执行错误检查来实现这一点,然后生成输出代码(如果可能)。通常,编译器的管道大致相当于: 输入代码->词法分析器(扫描器)->语法分析器->语义 分析器->

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

  • 扫描器
  • 分析器
  • AST数据结构
  • 代码生成
此外:

  • 运行时环境
  • 机器翻译

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

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

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

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

      使用语法分析器(解析器)检查例如“如果变量名以字母开头”,则算法类似

      当我扩展解析器时,我将一个标记与代码中的行相关联,以便在出现错误时返回它

      我不知道现代编译器是如何解决这个问题的,但我可以猜测这也是AST和行号之间的某种关联,因为一个AST可能在几行中(这取决于语言)

      通过代码生成,编译器知道(据他们所知)代码是正确的,返回的错误不是关于代码,而是编译器或进程有问题(错误、内存不足、无法写入位置等)

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

      *请注意,这是一个非常简单的3遍模型


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

      大多数lexer和parser生成器将生成具有错误报告方法的代码,这些方法在发生匹配错误时被调用。您可以重写该方法并执行您喜欢的操作

      如前所述,在lexer规范中,通常会将行和字符号与标识符或字符串/char/integer/boolean文本相关联。通常,lexer会提供一个
      yyline()
      方法来执行此操作。而不是让lexer返回原始标记(例如字符串)值,让它返回一个包含字符串值、字符和行号的对象

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

      解析器将在解析过程中接收符号,并应获取位置信息以及令牌值,并将其插入AST节点。该信息最终将进入符号表。在类型分析期间,每个叶节点都将绑定位置信息。这就是您需要提供的全部信息I很好的错误诊断。

      运行时和机器解释器不是编译器的组成部分。谢谢。我对问题做了一些编辑。