【问题标题】:Phases of a compiler?编译器的阶段?
【发布时间】:2011-03-05 08:48:09
【问题描述】:

在编译的哪个阶段可以识别编程语言的关键字?

我有点困惑

  1. 词法分析。
  2. 程序的解析。

我曾经使用正则表达式用 C 语言编写了一个词法分析器,但它也将 int main(void) 中的 main() 识别为关键字。

在这些方面,我认为我们必须构建一个解析树来识别关键字。

【问题讨论】:

  • @Mehrdad:绝对正确,但是对于标记化(与任何嵌套无关;词法分析器只返回一个平面标记流),它们是很棒 !
  • @Mehrdad - 还有一些基于正则表达式的工具,它们增加了处理嵌套的有限能力 - 足以用于可嵌套的 cmets 等。Ragel 是一个很好的例子。注意我说的是“基于”(我已经习惯了人们在这里跳来跳去的东西;-)),我知道一旦你支持任意深度的嵌套,整个语法就不再规则了。

标签: compiler-theory


【解决方案1】:

今年我必须构建一个简单的编译器作为我使用 Java 的项目。关键词的识别是在词法分析的基础上进行的。在那个阶段,我会读取输入语言并创建一个带有类型(对于关键字类型是 variable_declaration )及其值的标记。对于每种情况,我也有不同的类型,例如标识符,常量,乘法运算,加法运算等。然后传递这些标记到一个队列,然后到一个解析器,它会检查语法并创建一个二叉树,然后用它来创建输出语言。

【讨论】:

    【解决方案2】:

    通常,编译的词法分析阶段将输入文本分解为词位序列,每个词位都属于某些特定的标记类型,在以后的分析中很有用。因此,为了使解析更容易,通常在词法分析期间首先识别关键字。由于解析器倾向于通过编写标记而不是词位的上下文无关文法来实现(即,词位的类别而不是词位的内容),在词法分析期间标记关键字时,构建解析器要容易得多。例如,如果我想要一个将“if”视为关键字的解析器,那么我可能想要一个在我的 CFG 中看起来像这样的规则:

    Statement ::= 'IF' Expr 'THEN' Expr
    

    如果我不将IF 和THEN 分类为它们自己的标记类型,那么我的解析器就无法编写像上面这样的语句。

    【讨论】:

      【解决方案3】:

      这在很大程度上取决于定义,特别是您在扫描仪、标记器、词法分析器和解析器之间画线的位置。因为这是家庭作业,只有你的教授才是正确的。说它是正确的:看看你的阅读材料中提供的定义。

      关于 main():你可以肯定地说 main() 和所有其他函数一样,不是关键字,而是一个标记。标记器识别子串“main”是一个标记,解析器将其设置为与其“(...)”和“{...}”部分相关。此外,对于 main(),解析器会自动生成一个程序入口点。

      【讨论】:

        【解决方案4】:

        那就是词法分析。

        某些语言具有“特殊”标识符和关键字。这些通常在解析开始之前添加到标识符表中并分配已知的常量 ID 值,以便可以轻松发现它们。不过,这些通常对解析器没有特殊意义 - 它们应该在解析后在抽象语法树 (AST) 中检测到。

        例如,看看 Oberon 语言报告...

        http://www-old.oberon.ethz.ch/oreport.html

        不是语言推荐 - 只是一个容易获得和简单的语言规范(非常 Wirths 风格)。

        无论如何,“词汇和表示”部分包括“运算符和分隔符”列表,其中包括大多数人会识别为关键字的内容。这些将被词法分析器识别。

        在“声明和范围规则”部分,有一个预定义标识符列表,例如“ABS”和“BOOLEAN”。我对 Oberon 不够熟悉,无法确定,但如果我要编写一个编译器,我很有可能只是预初始化普通标识符表以包含这些预定义的标识符。

        在 C 中,“main”在大多数情况下只是另一个函数。编译器可能会将其视为特殊的,也可能不会。可能唯一的“特殊”之处在于链接到最终可执行文件的启动代码会调用该函数。

        【讨论】:

          【解决方案5】:

          传统上,关键字由词法分析器识别(这使您可以使用由一组固定关键字组成的语言)。但是当然你可以在解析过程中做到这一点。你甚至可以完全摆脱你的词法分析器,使用众多无词法分析技术之一(例如,PEGs)。它可能会帮助您避免混淆。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-09-23
            • 1970-01-01
            • 2012-03-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-05-30
            相关资源
            最近更新 更多