编译技术/编译原理期末复习

目录

  • [Part One: Lexical Analysis(Scanning)](#Part One: Lexical Analysis(Scanning))
  • [Part Two: Syntax Analysis(Parsing)](#Part Two: Syntax Analysis(Parsing))
    • [1. Grammar](#1. Grammar)
      • [1.1 **CFG**](#1.1 CFG)
      • [1.2 Parse Tree](#1.2 Parse Tree)
      • [1.3 Abstract Syntax Tree](#1.3 Abstract Syntax Tree)
      • [1.4 Ambiguity](#1.4 Ambiguity)
    • [2. Top-Down Parsing](#2. Top-Down Parsing)
      • [2.1 LL(1)](#2.1 LL(1))
      • [2.2 错误处理](#2.2 错误处理)
    • [3. Bottom-Up Parsing](#3. Bottom-Up Parsing)
  • [Part Three: Semantic Analysis](#Part Three: Semantic Analysis)

Part One: Lexical Analysis(Scanning)

  1. Regular Expression

    操作

    • Union

    • Concatenation

    • Kleene closure

    • Positive closure

  2. NFA

    有空串,无法确定当前状态

  3. 正则表达式转换成NFA

    一步一步把正则表达式拆开

  4. 问题

    1. 如何确定token对应的记号类型?(冲突)

      解决

      • 为正则表达式构建FA

      • 算法:Left-to right scan

      • 规则

        1. Maximal Munch(最大匹配规则)

        2. Priority rule

        3. "catch-all" rule:匹配任何字符并报错

    2. 如何多种可能的扫描方式?

      解决:DFA

    3. 如何高效实现词法分析?​

  5. DFA

NFA变为DFA

  1. 需解决

    • 消除空闭包

    • 消除同一字符跳转到不同状态

  2. 方法

    • Subset Construction(子集构造)

      • NFA变为DFA

      • 从空闭包开始,不断Ia,Iaa...

    • 最小化算法:简化DFA状态

Part Two: Syntax Analysis(Parsing)

1. Grammar

1.1 CFG

  1. R.E. vs. CFG

    • 允许递归,表达能力更强

    • CFG没有*

  2. 包含关系

    Regular Expression -> Context Free Grammar -> Context Sensitive Grammar -> Unrestricted Grammar(如图灵机Turing machine)

  3. Sentence

    • Sentential Form(句型)

      推导过程中产生的所有​​中间符号串(含非终结符;含最终结果)

    • Sentence(句子)

      推导的最终结果​(不含非终结符)

  4. 包含LL(k)

1.2 Parse Tree

Derivation(推导)

  1. Leftmost Derivation

    最左推导对应前序遍历(根左右)

  2. Rightmost Derivation

    最右推导的逆序对应后序遍历(左右根)

1.3 Abstract Syntax Tree

  1. 只保留必要信息

  2. AST和三地址码是中间表示形式

1.4 Ambiguity

  1. 同一句表达式对应不同语法解析树

  2. 解决二义性

    • Disambiguating rule(歧义消除规则)

      • 附加额外规则
    • Rewriting the grammar(重写文法)

      • 消除左递归

      • 提取左因子

2. Top-Down Parsing

自顶向下,最左推导

2.1 LL(1)

  1. 是预测分析文法

  2. 不含二义性,不含左递归和左因子

  3. 从左往右扫描输入,最左推导,1个lookahead

  4. First集和Follow集

  5. LL(1)文法判断

    • 无左递归和左因子

      • 注意这只是条件之一,无法判断一定是LL(1)
    • 根据定义

      • 任意First集无交集

      • First集包含 ε,则First集和Follow集无交集

  6. 非LL(1)变成LL(1)

    • 消除左递归

    • 提取左因子

  7. Recursive-Descent Parsing(递归下降分析)

    构造递归下降分析:

    • Step1:判断是否为LL(1)

    • Step2:构造递归下降解析器

    • Step3:构造语法分析树和抽象语法树

  8. 构建语法分析表

    • Step1:拆开所有"或",求First(α)

      Follow不用求,除非First包含ε,则Follow(ε)=Follow(A)

    • Step2:对于First(α)的每个a,A->α填入M[A,a]

    • Step3:对于Follow(A)的每个a,将A->α填入M[A,a]

  9. 语法分析过程

    • Stack,Input,Action

    • 产生式体的末尾先进栈

2.2 错误处理

错误恢复策略

  1. Panic Mode

    遇到错误跳过

  2. Phrase-Level Recovery

    局部修复错误

3. Bottom-Up Parsing

  1. 包含关系

    LR(0) 属于 SLR(1) 属于 LALR(1) 属于 LR(1)

  2. 自底向上,最右推导

  3. Handle

    • 是产生式体

    • 是最右推导链的句型的一部分

    • 在栈顶寻找句柄

  4. item

  5. 关于栈

    • Handle在栈顶附近

    • 栈顶必须是状态符号

    • 占地是任意符号(终/非终/状态)

  6. LR(0) Parsing

    1. 起始的产生式体不是单一字符要增广(augment)

    2. 构造DFA

      • NFA状态数与文法大小成正比,构造简单

      • DFA状态数呈指数级增长

    3. 判断LR(0)

      • 无SR冲突:SR冲突:lookahead没要求

      • 无RR冲突:RR冲突:lookahead需要存在交集

    4. 缺点

      • 无lookahead,仅依靠栈内符号

      • 限制语言类别

  7. Viable Prefix

    一个可行前缀是一个最右句型的前缀,并且它没有越过该最右句型的最右句柄的右端(可包括句柄)

    这些前缀的集合叫做可行前缀。

  8. SLR(1) Parsing

    1. 解决SR和RR冲突

      • 前提:I={X->α • bβ,Α->γ •,Β->δ•},若Follow(A)∩FOLLOW(B)=φ,且不包含b,下一输入为a

      • 策略

        • 若a=b,Shift

        • 若a∈FOLLOW(A),Reduce Α->γ

        • 若a∈FOLLOW(B),Reduce Β->δ

        • 其他情况error

    2. 构建SLR(1)语法分析表

      先构建DFA

    3. 判断SLR(1)

      • 存在SR或RR冲突

      • 对于每个Ai->α • aβ,Bi->γi •,有{ai}∩Follow(B1)∩Follow(B2)∩...=φ(避免缺点3),则是SLR(1)

    4. SLR(1)缺点

      • Follow集过于宽泛,可能错误归约

      • 状态合并,无法区分不同位置的相同非终结符

      • 存在无法解决的冲突,如next=b,且next∈FOLLOW(A)

  9. LR(1) Parsing

    1. 核心:添加lookahead

    2. 与SLR(1)区别

      • SLR(1)先构建LR(0)的DFA,再根据Follow引入lookahead决定归约

      • LR(1)直接构建带lookahead的DFA

    3. 计算lookahead

      • 起始S->E的的lookahead是$

      • 对于终结符T-> •t, a 的展开,lookahead=a

      • 对于非终结符A-> • Bγ, a的展开,lookahead=First(γa)

        • 若γ可推出ε,lookahead再加入a
    4. 构建LR(1)语法分析表

    5. LALR(1)

      • 即Lookahead LR(1),是LR(0)和LR(1)的折中

      • 合并不同状态里的同心集,若合并后存在RR冲突,则是LALR(1)

        • 同心集指逗号前产生式一样

        • 例如I5:A->d, a和B->d, c,I10:A->d, c和B->d, a

          合并后:A->d, a/c和B->d, a/c。lookahead一样,存在RR冲突,则是LALR(1)

Part Three: Semantic Analysis

  1. 编译器逻辑结构

    • Scanner

    • Parser

    • Semantic analyzer

    • IR genenration

    • IR optimizer

    • Code Generator

    • Target code optimizer

  2. 流程

    源代码 --Scanner--> Tokens --Parser--> AST --Semantic analyzer--> Annotated Syntax Tree --IR generation--> 中间代码(三地址码) --Code generator--> 目标代码(机器码/汇编代码) --Target code optimizer--> Target machine code

  3. 辅助部件

    • Literal table

    • Symbol table

    • Error handler

  4. 输入AST,输出dependency graph

  5. 符号表

    • 符号表​​是编译器的核心数据结构,支持语义分析和代码生成(synthesis)

    • 作用域检查通常通过符号表来实现,这种符号表可以采用链式结构实现,也可以采用显式的栈结构


相关推荐
沛沛rh454 小时前
深入并发编程:从 C++ 到 Rust 的学习笔记
c++·笔记·学习·算法·rust
chushiyunen4 小时前
float浮点数计算-原理笔记
笔记
A923A4 小时前
【小兔鲜电商前台 | 项目笔记】第二天
前端·vue.js·笔记·项目·小兔鲜
bukeyiwanshui4 小时前
2026.4.2随堂笔记
笔记
CheerWWW5 小时前
C++学习笔记——初始化列表、创建和实例化对象、new 关键字、隐式构造与 explicit 关键字、运算符与运算符重载
c++·笔记·学习
南境十里·墨染春水5 小时前
C++笔记 类模板(面向对象)
开发语言·c++·笔记
小陈phd5 小时前
多模态大模型学习笔记(二十八)—— 基于Qwen多模态大模型的城市道路积水智能检测助手实战
笔记·学习
南境十里·墨染春水5 小时前
C++ 笔记 function 函数包装器模板
开发语言·c++·笔记
泡泡茶壶Wending6 小时前
opengl笔记之VBO,VAO
笔记
鱼鳞_7 小时前
Java学习笔记_Day21
java·笔记·学习