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

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

  • 辨析:
    • 表达式———————有值
    • 语句———有分号————
  • 语法和语义分开定义规则
  • 源代码—(词法分析,分割分类)—>单词符号流—(语法分析,与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

 三地址代码生成

原文地址:https://www.cnblogs.com/ggotransfromation/p/11609589.html