• 编译器架构Compiler Architecture(下)


    编译器架构Compiler Architecture(下)

    Combining Scanning and Parsing

    实际上没有必要将扫描(词法分析/标记化)与解析(语法分析/树生成)分开。基于PEGs的系统,比如Ohm,实际上是无扫描的:它们以一种预测的方式执行解析,将词汇和语法规则混合在一起。(但是,像Ohm这样的系统需要一个预解析阶段来处理缩进和凹陷。)             

    当使用无扫描系统时,语言设计者和编译器编写者仍然会考虑符号和短语,但不必担心像所谓的最大Munch原则这样的复杂规则。Lookahead捕获您需要的任何类型的标记化方案。此外,无扫描解析的预测性意味着我们不必确定*是一元运算符指针解引用令牌,还是二进制乘法运算符令牌或星形令牌。在进行预测性分析时,我们总是有上下文。

    Semantic Analysis

    在语义分析过程中,我们必须检查合法性规则,同时,我们将语法树的片段(通过解析标识符引用、为隐式强制插入强制转换操作等)捆绑起来,形成一个语义图。             

    继续上面的例子:

    显然,每种语言的合法性规则是不同的。您可能会在类似Java的语言中看到的合法性规则示例包括:             

    一个范围内的变量的多个声明              

    在变量声明之前引用它             

    引用没有声明的标识符             

    违反访问(公共、私有、受保护等)规则             

    方法调用中的参数太多             

    方法调用中没有足够的参数             

    类型不匹配(有很多这样的情况)

    练习:列举以上每一个例子。             

    在此阶段发生的错误称为静态语义错误。             

    练习:Pascal语言在表达式方面有一种不同寻常的语法:它赋予and运算符(需要布尔操作数)比关系运算符更高的优先级!说明这意味着表达式x-4<=5和2<y是静态语义错误。

    中间代码生成Intermediate Code Generation             

    中间代码生成器生成一个流图,由分组到基本块中的元组组成。对于上面的例子,我们可以看到:

    可以在其他地方阅读更多关于中间表示的内容。

    Machine Independent Code Improvement

    对语义图或中间代码进行的代码改进称为与机器无关的代码优化。在实践中,有无数已知的优化(er,改进),但没有一个真正适用于我们的运行示例。

    Code Generation

    代码生成产生实际的目标代码,或者类似的代码。这是我在使用面向x86-64的gcc 6.3进行组装时得到的结果,没有任何优化:

    以下是ARM的代码,使用gcc 5.4,无需优化:

    MIPS代码,gcc 5.4也未优化:

     Machine Dependent Code Improvement

    通常编译的最后阶段是清理和改进目标代码。对于上面的例子,我在将优化级别设置为-O3时得到了如下结论:

    Optimized ARM code:

    Optimized MIPS code:

     

  • 相关阅读:
    ORACLE创建、修改、删除序列
    mysql添加索引
    Mysql事物与Metadata lock 问题
    oracle 查询最近执行过的 SQL语句
    ORACLE 常用SQL查询
    ssh-keygen的用法
    sql之left join、right join、inner join的区别
    Linux下使用 ipset 封大量IP及ipset参数说明
    今天学习的小命令
    Linux下查看分区内目录及文件占用空间容量
  • 原文地址:https://www.cnblogs.com/wujianming-110117/p/13234641.html
Copyright © 2020-2023  润新知