• 编译技术图式(第二章 实现一个简单的编译器)


    编译技术图示(第二章 实现一个简单的编译器)

    • 辨析:
      • 表达式———————有值
      • 语句———有分号————
    • 语法和语义分开定义规则
    • 源代码—(词法分析,分割分类)—>单词符号流—(语法分析,与BNF语法规则)—>抽象语法树/Token序列

    1、词法分析


    词法分析器所需函数

      取一个字符 getChar

      将当前字符加到当前已识别子串 addChar

      跳过多余空格/注释 getNonBlank

      关键字检查 checkKeywords

      符号检查 checkSymbol 

    2、语法定义BNF


     1.1描述方法

    1)词法定义:词素/终结符(不可分解),eg:关键字

    2)语法定义:非终结符,eg:while语句

    3)用大小写区分这两类语法成分

    4)语句先用汉语说出来,最后用英文描述(eg:“stmt”语句)

        表示中用符号:“—>”表示(具有如下形式,左词素句/非终结符句,右语句名/非终结符名),“|”或者

    1.2检验是否符合语言规则——规则放旁边“—>”

    1)归约:由具体到抽象(自下而上)将所有终结符化为非终结符

    2)推导:由抽象到具体(自上而下)将所有非终结符化为终结符

    • 递归下降分析法
      • 规则:  
        • 每个非终结符对应一个解析函数  
        • 语法规则右侧为其左侧非终结符对应的“函数体”
        • ‘+’与‘-’属于ASCⅡ,可用match()
        • 空串(|ε):遇到不符前规则则认为遇到空串,则判正(原本判负),但不消耗此终结符。(空串是想要多少个就有多少个)  
        • 递归调用A{A B }死循环,A{B A}  
      • 关于函数体:  
        • 右侧终结符对应从输入串中消耗(advance)该终结符    
        • 右侧非终结符对应函数调用    
        • “|”对应“if-else”语句    
      • 两个函数模式:  
        • 1)void:    
          • 终结符:if!match(){报错;结束}advance();消耗      
          • 函数调用:直接调用      
        • 2)int:    
          • 终结符:if!match(){报错,return 0}advance();消耗      
          • 函数调用:if!match(函数调用){报错;return 0}advance();消耗      
          • 最后位直接 return函数调用;
      • 串 i+i*i# 递归下降分析过程

    1.3建立抽象语法树

    抽象语法树AST

      是源代码的抽象语法结构的树状表现

        不保留仅语法用的符号

       与具体语法树相对应

        包括语法规则中的各种符号

    抽象语法树 结点类型 设计

     

    3、语义分析


    1)符号表

    2)类型检查

    3)类型转换

    隐式(自动)转换

    显式(强制)转换

    两种转换方式:(1)扩展(2)收缩

    4)中间代码(三地址码)

    三地址代码中的地址 既代表地址,又表示其对应的值,类似于高级语言

    实际编译器的三地址代码类似于汇编语言,即:把地址 与 值 分开保存,要么是值,要么是地址

    LLVM:clang -emit-llvm -S ./llvm_example.c

     三地址代码生成

  • 相关阅读:
    AAPay v1.5使用介绍
    我的第一款实用工具眼保程序(EyesBaby)
    C/C++中const关键字详解
    go 中flag模块
    go语言的一些基础知识
    12.Redis6中的新的数据类型
    性能测试实战30讲笔记——2.性能分析思路
    11.redis6的发布与订阅(编号大小无关内容)
    k8s——1.k8s介绍
    Docker——容器数据卷
  • 原文地址:https://www.cnblogs.com/ggotransfromation/p/11609589.html
Copyright © 2020-2023  润新知