当前位置: 首页 > news >正文

【编译原理】语法分析方法总结

目录

一、预测分析法

整体结构

1. 核心条件:LL(1)文法

2. 预测分析表的构造

3. 分析过程

二、算符优先分析法

整体结构

优先函数

1. 核心条件:算符文法(OG)与算符优先文法(OPG)

2. 关键集合:FIRSTVT 与 LASTVT

3. 优先关系定义

4. 优先关系矩阵与优先函数

5. 分析过程

三、LR分析法

整体结构

1. LR分析法概述

2. LR(0) 分析法

3. SLR(1) 分析法

4. LR(1) 分析法


一、预测分析法

确定的自上而下语法分析方法,适用于LL(1)文法

其核心是通过预测分析表(LL(1)分析表)和栈结构,唯一确定每一步推导(最左推导)使用的产生式,避免回溯

整体结构

1. 核心条件:LL(1)文法

预测分析法要求文法满足以下条件:

  1. 无左递归(直接或间接)。

  2. 候选式的FIRST集互不相交:对同一非终结符的不同候选式,其首符号集无交集。

  3. ε候选式的处理:若某候选式可推出ε,则该非终结符的FOLLOW集与其他候选式的FIRST集无交集。


2. 预测分析表的构造

步骤

  1. 计算FIRST集

    • 终结符的FIRST集为自身。

    • 非终结符的FIRST集由其产生式右部的首符号决定,递归推导直至遇到终结符或ε。

  2. 计算FOLLOW集

    • 开始符号的FOLLOW集包含#

    • 若存在产生式A→αBβ,则FIRST(β)-{ε}加入FOLLOW(B)

    • β可推导出ε,则将FOLLOW(A)加入FOLLOW(B)

  3. 填充分析表

    • 对每个产生式A→α

      • a ∈ FIRST(α),则M[A, a] = A→α

      • α可推导出ε,则对b ∈ FOLLOW(A)M[A, b] = A→α


3. 分析过程

数据结构

  • 分析栈:初始为#和文法的开始符号(如E)。

  • 输入串:末尾添加#作为结束符。

步骤

  1. 栈顶为终结符

    • 若与当前输入符号匹配,弹出栈顶,输入指针后移。

    • 若不匹配,报错。

  2. 栈顶为非终结符

    • 查预测分析表M[X, a],找到产生式X→α

    • 弹出X,将α逆序压入栈(如α=XYZ,则压入Z Y X)。

  3. 成功条件

    • 栈顶和输入符号均为#,分析成功。

  4. 失败条件

    • 查表无对应产生式,报错。


自下而上分析方法是从输入符号串开始,查找当前 句柄,并用产生式将它归约成相应的非终结符号,最后 归约为开始符号的一种分析方法

(1)对输入符号串的扫描,采用自左向右的顺序;

(2)分析过程是自下而上进行的(对语法树来说从末端    结点开始,最后归约到根结点);

(3)每次归约是对最左简单短语(句柄)进行的;

(4)算法的关键是确定最左简单短语。

二、算符优先分析法

算符优先分析法是一种自下而上的语法分析方法,特别适合处理表达式

其核心是通过终结符之间的优先关系确定归约顺序,而非严格遵循规范归约

整体结构

优先函数

优点:

 编程时便于比较运算,即用一般的关系运算即可;

 比用文法的优先关系矩阵节省内存,若有n个终结符号,优先关系矩阵占内存为(n+1)2,优先函数为2(n+1);

缺点:

   本来不存在优先关系的两个终结符号,变成可比较了,不易发现语法错误。

注意:

应区别对待一目运算“减”和二目运算“减”,它们虽然使用相同的符号‘-’,但优先级不同,可使用不同的符号代替一目运算“减”,即看成两种运算。

1. 核心条件:算符文法(OG)与算符优先文法(OPG)

  • 算符文法(OG):文法中任意产生式的右部不含连续的非终结符

  • 算符优先文法(OPG):OG基础上,任意两终结符之间至多一种优先关系(<, =, >)。


2. 关键集合:FIRSTVT 与 LASTVT

  • FIRSTVT(U):非终结符U能推导出的所有符号串的第一个终结符

  • LASTVT(U):非终结符U能推导出的所有符号串的最后一个终结符

  • 计算方法

    • FIRSTVT:若产生式形如 U→b... 或 U→Vb...,则 b ∈ FIRSTVT(U)

    • LASTVT:若产生式形如 U→...a 或 U→...aV,则 a ∈ LASTVT(U)


3. 优先关系定义

  • a < b:若存在产生式 U→...aV...,且 b ∈ FIRSTVT(V)

  • a = b:若存在产生式 U→...ab... 或 U→...aVb...

  • a > b:若存在产生式 U→...Vb...,且 a ∈ LASTVT(V)


4. 优先关系矩阵与优先函数

  • 优先关系矩阵:矩阵的行和列为终结符,元素为 <=>

  • 优先函数(f和g):将终结符映射为整数,满足:

    • 若 a < b,则 f(a) < g(b)

    • 若 a = b,则 f(a) = g(b)

    • 若 a > b,则 f(a) > g(b)


5. 分析过程

数据结构

  • 符号栈:存放已分析的符号。

  • 输入串:末尾添加结束符 #

步骤

  1. 初始化:将 # 压入符号栈,输入指针指向第一个符号。

  2. 比较优先级

    • 栈顶终结符为 a,输入符号为 b

    • 若 a < b 或 a = b移进 b

    • 若 a > b归约最左素短语。

  3. 归约规则

    • 找到栈顶最左素短语(至少含一个终结符,且无更小素短语)。

    • 用对应的非终结符替换素短语。

  4. 结束条件

    • 栈中只剩 #S(S为开始符号),输入为 #,分析成功。

    • 若无法匹配优先级,报错。

三、LR分析法

整体结构

1. LR分析法概述

LR分析法是一种有效的自底向上的语法分析技术, 它能适用于大部分上下文无关文法的分析,一般叫 LR(k)分析方法,其中L是指自左(Left)向右扫描输入单词串,R是指分析过程都是构造最右(Right)推导的逆过程(规范归约),括号中的k是指在决定当前分析动作时向前看的符号个数

核心思想:自下而上语法分析,通过构造分析表(动作表 Action 和状态转换表 Goto)驱动分析过程。
特点

  • L:从左向右扫描输入串

  • R:构造最右推导的逆过程(规范归约)

  • k:向前看 k 个符号(通常 k=1

分析过程

  1. 初始化:栈中压入初始状态 S0 和 #(输入串边界符)。

  2. 查表决策

    • 移进(Shift):将输入符号和对应新状态压栈。

    • 归约(Reduce):按产生式替换栈顶符号,查 Goto 表更新状态。

    • 接受(Accept):栈顶为开始符号,输入为 #

    • 报错:无合法动作。


2. LR(0) 分析法

核心:基于 LR(0) 项目集规范族,每个状态不含冲突(移进-归约或归约-归约)。
步骤

  1. 拓广文法:添加 S'→S,确保唯一接受状态。

  2. 构造项目集

    • LR(0) 项目:形如 A→α·β,圆点表示分析进度。

    • 闭包(Closure):若 A→α·Bβ,则加入 B→·γ 的所有产生式。

    • 转换函数(Goto):根据符号 X 转移到新状态。

  3. 构造分析表

    • 移进Action[S_i, a] = S_ja 是终结符)。

    • 归约:若 A→α·,则 Action[S_i, *] = r_kk 为产生式编号)。

    • 接受S'→S· 时 Action[S_i, #] = acc

缺点:无法处理冲突(需文法为 LR(0) 文法)。


3. SLR(1) 分析法

改进:在 LR(0) 基础上,利用 Follow 集 解决冲突。
冲突解决规则

  • 若状态中存在 A→α· 和 B→β·aγ,且 a ∈ Follow(A),则对 a 选择移进,其他符号归约。

步骤

  1. 构造 LR(0) 项目集

  2. 填充分析表

    • 归约动作仅对 a ∈ Follow(A) 生效(Action[S_i, a] = r_k)。

优点:比 LR(0) 更灵活,适用于更多文法。
缺点:若 Follow(A) 与移进符号有交集,仍无法解决冲突。


4. LR(1) 分析法

核心:引入 向前搜索符(Lookahead),每个项目形式为 [A→α·β, a],表示归约时需匹配 a
步骤

  1. 构造 LR(1) 项目集

    • 闭包:若 [A→α·Bβ, a],则加入 [B→·γ, b],其中 b ∈ First(βa)

    • 转换函数:类似 LR(0),但携带向前搜索符。

  2. 构造分析表

    • 归约动作仅在输入符与向前搜索符匹配时触发(Action[S_i, a] = r_k)。

优点:解决 SLR(1) 无法处理的冲突(如 Follow 集与移进符号重叠)。
缺点:项目集数量庞大,构造复杂度高。

方法核心机制冲突解决复杂度适用性
LR(0)无冲突项目集无法处理冲突严格无冲突文法
SLR(1)利用 Follow 集解决部分移进-归约冲突多数程序设计语言
LR(1)向前搜索符(精确匹配)解决所有 LR 冲突复杂或二义性文法
  • LR(0):简单但限制严格,仅适用于无冲突文法。

  • SLR(1):通过 Follow 集扩展,实用性更强。

  • LR(1):最强大但构造复杂,适合处理复杂文法。

  • YACC/LALR(1):实际工具(如 YACC)采用折中的 LALR(1),合并 LR(1) 状态以平衡能力与效率。

相关文章:

  • 医疗AI项目文档编写核心要素硬核解析:从技术落地到合规实践
  • ​《Nacos终极指南:集群配置+负载均衡+健康检查+配置中心全解析,让微服务稳如老狗!》​
  • upload-labs通关笔记-第21关 文件上传之数组绕过
  • 数据结构---二叉树
  • 使用Spring Boot和Spring Security结合JWT实现安全的RESTful API
  • kafka之操作示例
  • Web安全技术体系
  • 09 接口自动化-用例管理框架pytest之allure报告定制以及数据驱动
  • 【概率论基本概念01】点估计
  • github好玩的工具
  • GitHub 趋势日报 (2025年05月23日)
  • 39-居住证管理系统(小程序)
  • 2025年第八届广西大学生程序设计大赛(热身赛)题解
  • jmeter中文乱码问题
  • x64_ubuntu22.04.5安装:cuda driver + cuda toolkit
  • JavaSE核心知识点03高级特性03-03(IO流)
  • 人工智能在医疗影像诊断上的最新成果:更精准地识别疾病
  • Oracle表索引变为不可用状态了怎么办
  • 【C/C++】红黑树学习笔记
  • python:机器学习概述
  • js网站下拉置顶代码/网络营销收获与体会
  • 购物网站 怎么做/百度软件应用中心下载
  • 佛山最好的网站建设/百度网站收录提交入口
  • 北京高端网站建设制作设计/成都推广团队
  • 做英文网站2014/一周热点新闻
  • 更改wordpress菜单字体/seo优化关键词排名