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

编译原理--期末复习

本文是我学习以下博主视频所作的笔记,写的不够清晰,建议大家直接去看这些博主的视频,他/她们讲得非常好:

基础知识+概念:
1.【【编译原理】期末复习 零基础自学】,资料

2.【编译原理—混子速成期末保过】,评论区楼主笔记

注重题型+解法:

1.【1编译原理求语法树的短语直接短语等等】, 对应的资料:链接,提取码:ozz4

2.【编译原理根据正规表达式构造NFA,到DFA,以及最后的DFA化简/最小化】,对应的资料:链接,提取码:uwud

在此对上述博主的产出表示感谢,也希望大家都能高分通过期末考试~


引论

一、高级语言与低级语言的定义

1. 高级语言(High-Level Language)
  • 定义
    高级语言是一种接近人类自然语言(如英语)和数学表达式的编程语言,屏蔽了计算机硬件细节(如内存地址、寄存器操作),使用更抽象的语法(如函数、类、循环)描述逻辑。
    • 例子:Python、Java、C++、C#、JavaScript、Go 等。
  • 特点
    • 可读性强:语法接近自然语言,易于理解和维护(如 if (x > 0) { ... })。
    • 平台无关性:代码可在不同操作系统(Windows/Linux/macOS)和硬件架构上移植,无需针对底层硬件重写。
    • 抽象程度高:提供内置数据结构(数组、对象)、内存管理(自动垃圾回收)、高级控制结构(循环、递归)等。
2. 低级语言(Low-Level Language)
  • 定义
    低级语言是直接面向计算机硬件(CPU、内存、寄存器)的编程语言,贴近机器指令格式,需手动处理底层细节。
    • 分类
      • 机器语言:由二进制指令(0/1序列)组成,是CPU唯一能直接执行的语言(如 10110000 表示加载数据到寄存器)。
      • 汇编语言:用助记符(如 MOVADD)替代二进制指令,需通过汇编器转换为机器语言(如 MOV AX, 1 表示将数值1存入AX寄存器)。
  • 特点
    • 可读性差:语法复杂,依赖硬件架构(不同CPU的汇编指令集不同,如x86、ARM)。
    • 平台依赖性强:代码只能在特定硬件或操作系统上运行。
    • 控制精细:可直接操作内存地址、寄存器,适合编写高性能或硬件驱动程序。

二、高级语言需要编译/链接的原因

1. 计算机只能执行机器语言

高级语言代码(如C语言的 .c 文件)无法被CPU直接执行,必须经过 翻译过程 转换为机器语言(二进制可执行文件)。这一过程通常包括 编译、链接 等步骤,目的是将抽象的高级语法转换为CPU能理解的指令序列。

2. 编译(Compilation)的作用
  • 步骤
    1. 预处理:处理 #include 头文件、#define 宏定义(如展开代码)。
    2. 编译:将高级语言代码转换为 汇编语言(中间形式)。
    3. 汇编:将汇编语言转换为 目标文件.o.obj,包含二进制机器指令,但未解决外部依赖)。
  • 输出:目标文件(二进制,但可能包含未解析的符号,如调用其他文件的函数)。
3. 链接(Linking)的作用
  • 解决依赖
    目标文件可能引用其他文件的函数(如C标准库的 printf)或全局变量,链接器负责:
    1. 合并目标文件:将多个 .o 文件(如主函数和自定义函数)合并为一个整体。
    2. 解析符号引用:将未定义的符号(如函数名)映射到实际内存地址。
    3. 链接库文件:引入标准库(如C的 libc)或第三方库的代码。
  • 输出:可执行文件(.exe 或无扩展名,能直接在操作系统中运行)。

三、编译型语言 vs. 解释型语言

高级语言按翻译方式分为两类:编译型解释型,核心区别在于翻译过程是“一次性完成”还是“边运行边翻译”。

1. 编译型语言(Compiled Language)
  • 工作流程
    源代码 → 编译器(Compiler) → 目标代码(机器语言)→ 链接器 → 可执行文件。
  • 特点
    • 一次编译,多次执行:编译后的可执行文件可直接运行,无需重新编译(如C语言的 .c 文件编译为 .exe)。
    • 执行效率高:机器语言直接由CPU执行,速度快(适合计算密集型任务,如游戏、操作系统)。
    • 平台依赖性:不同操作系统/CPU架构需重新编译(如Windows的 .exe 不能在Linux直接运行,这里如何实现跨平台,可以参考这个视频:【这个问题99%的人会答错!包括我】)。
  • 例子:C、C++、Go、Rust。
2. 解释型语言(Interpreted Language)
  • 工作流程
    源代码 → 解释器(Interpreter) → 边逐行翻译边执行(不生成独立的可执行文件)。
    • 部分语言(如Java、Python)会先生成中间形式(字节码),再由虚拟机(JVM、Python解释器)解释执行。
  • 特点
    • 跨平台性强:只要目标平台安装解释器/虚拟机,代码即可运行(如Python代码在Windows/Linux上无需修改)。
    • 执行效率较低:每次运行都需翻译,速度慢于编译型语言(适合快速开发、脚本任务)。
    • 动态类型支持:变量类型在运行时确定,灵活性高(如Python的 x = 1x = "hello" 无需声明类型)。
  • 例子:Python、JavaScript、Ruby、PHP、Perl。
3. 混合类型(中间形式)
  • Java、C#:先编译为字节码(平台无关的中间代码),再由虚拟机(JVM、.NET CLR)解释执行,兼具编译型的跨平台性和解释型的灵活性。
  • Python(优化模式):可通过 pyc 文件缓存字节码,减少重复翻译,但本质仍是解释执行。

四、核心区别对比

特性编译型语言解释型语言
翻译时机运行前一次性编译为机器码运行时逐行解释执行
执行效率高(机器码直接执行)低(解释器逐条翻译)
跨平台性差(需针对不同平台重新编译)好(依赖解释器/虚拟机)
开发效率低(编译错误需重新编译)高(即时反馈,无需编译步骤)
典型场景系统级开发、高性能计算脚本编写、Web开发、快速原型
代表语言C、C++、GoPython、JavaScript、Ruby

五、总结

  • 高级语言 提升开发效率,屏蔽硬件细节;低级语言 控制硬件,实现高性能。
  • 编译/链接 是将高级语言转换为机器可执行代码的必要步骤,解决代码依赖和平台差异。
  • 编译型 vs. 解释型 的选择取决于需求:追求效率选编译型(如C),追求灵活和跨平台选解释型(如Python),而Java等语言通过中间形式平衡两者优势。
    理解这些区别有助于根据项目需求选择合适的编程语言和开发模式。

其中我们要学习的 编译 就是上述的一个步骤。
在这里插入图片描述

其中编译阶段又分为几个步骤:
在这里插入图片描述

词法分析(Lexical Analysis)

词法分析是编译的首个阶段,此阶段的词法分析器会把C++源代码当作字符流来处理,接着按照C++词法规则,将其转换为一系列有意义的词法单元(Token)。

  • 关键作用
    • 过滤掉注释和空白字符(像空格、换行符这类)。
    • 识别出标识符(例如变量名、函数名)、关键字(像int、if)、字面量(例如123、“hello”)以及运算符(如+、*)。
    • 进行词法错误检查,比如检测非法字符、不匹配的引号等问题。
  • C++示例
    对于源代码int a = 42 + b;,经过词法分析后会生成如下词法单元:
    [int] [标识符:a] [=] [字面量:42] [+] [标识符:b] [;]
    

语法分析(Syntax Analysis)

语法分析阶段,语法分析器会依据C++的语法规则,把词法单元构建成抽象语法树(AST)。

  • 关键作用
    • 验证代码结构是否符合C++语法规范。
    • 检测语法错误,例如括号不匹配、缺少分号、错误的if语句结构等。
    • 为后续的语义分析和代码生成搭建结构化的表示形式。
  • C++示例
    对于表达式a = 42 + b;,其抽象语法树可能呈现为:
    AssignmentExpr
    ├─ Left: Identifier(a)
    └─ Right: BinaryOp(+)├─ Left: Literal(42)└─ Right: Identifier(b)
    

语义分析(Semantic Analysis)

语义分析阶段会对抽象语法树进行静态语义检查,保证代码在语义上是合法的。

  • 关键作用
    • 类型检查:保证操作数的类型是兼容的,例如intint相加,而不是int和函数指针相加。
    • 符号表查询:确认变量和函数在使用之前已经被声明或定义。
    • 检测语义错误,例如变量未定义、类型不匹配、函数调用参数数量不对等。
  • C++示例
    • 错误示例:int a = "hello";(类型不匹配)
    • 正确示例:int a = func(42);(假设func被声明为返回int类型)

中间代码生成(Intermediate Code Generation)

该阶段会把抽象语法树转换为与机器无关的中间表示形式(IR),像三地址码、LLVM IR等。

  • 关键作用
    • 简化后续的代码优化和目标代码生成工作。
    • 支持跨平台编译,因为中间代码可以被翻译成不同架构的机器码。
  • C++示例
    对于代码a = (b + c) * d;,可能生成如下三地址码:
    t1 = b + c
    t2 = t1 * d
    a = t2
    

代码优化(Code Optimization)

代码优化阶段会对中间代码进行转换,以提升代码的执行效率,同时不会改变程序的语义。

  • 关键作用
    • 常量传播:例如把x = 5 + 3;优化成x = 8;
    • 死代码消除:移除不会被执行的代码,如if (false) { ... }
    • 循环不变代码外提:将循环内不会改变结果的计算移到循环外面。
    • 强度削弱:把昂贵的运算(如乘法)替换为代价更低的运算(如移位)。
  • C++示例
    原始代码:
    int a = 10;
    int b = a * 4; // 会被优化成 b = a << 2
    
    优化后的中间代码:
    a = 10
    b = a << 2  // 用移位替代乘法
    

一些问题:

  1. 高级语言的执行都存在中间代码生成阶段。(❌)

解释:像 Python 这类解释型语言存在中间代码生成阶段,而直接编译型语言(如 C 语言)可能直接生成目标代码。

  1. 中间代码所生成的依据是语法分析。(❌)

解释:在进行了语法分析和语义分析阶段的工作之后,有的编译程序将源程序变成一种内部表示形式,这种内部表示形式叫做中间语言或中间代码。

所谓“中间代码”是一种结构简单、含义明确的记号系统,这种记号系统可以设计为多种多样的形式,重要的设计原则为两点:一是容易生成;二是容易将它翻译成目标代码。

  1. 词法分析中,对变量分析后的输出是该变量的值和类型。(❌)

解释:词法分析的输出是记号(Token),包含类型和属性值,并非变量的实际值与类型,变量值和类型的确定发生在语义分析阶段。

  1. 源程序经词法分析后得到的中间结果是 (A)
    A. 单词(token)
    B. 四元式
    C. 语法树
    D. 语法分析程序

解释

  • 词法分析:输出 Token 序列。
  • 语法分析:依据 Token 序列构建出抽象语法树(AST)。
  • 中间代码生成:生成三地址码或者四元式等中间表示形式。
  • 语法分析程序:属于编译程序的一个组件,并非词法分析的输出内容。

第一/二章:概述、文法和语言

在这里插入图片描述

  • 空串,一个字符串的长度为0
  • 空集,一个集合中没有任何元素(空串也是一个元素)
  • 字符串的乘积,字符串直接拼接在一起
  • 集合的乘积,使用前一个集合中的元素与后一个集合中元素进行拼接。
  • 集合的闭包,有限个集合的乘积。

在这里插入图片描述


在这里插入图片描述


文法

分类

  • 0型文法:短语文法
  • 1型文法:上下文有关文法
  • 2型文法:上下文无关文法
  • 3型文法:正规文法

上下文无关文法

上下文无关文法,是一个四元组,包含非终结符号、终结符号、重写规则集合、识别符,可以理解为由 非终结符定义为非终结符/终结符 产生式组成的文法。

  • 终结符号,只在产生式的右边出现的符号。
  • 第一条产生式的左部,是识别符。
  • 通常使用大写字母表示非终结符,小写字母表示为终结符。(但并不是说,“文法中的小写字母一定是指终结符”,在文法里,习惯上用小写字母表示终结符,但这并非强制规定,具体要依据文法的定义来判断符号类型。)

在这里插入图片描述

  • 左线性文法和右线性文法,在一个文法中同时只能出现一种,这个文法才是正规文法
    在这里插入图片描述
    在这里插入图片描述

相关概念

在这里插入图片描述
在这里插入图片描述

所以,句子一定是句型


在这里插入图片描述

在这里插入图片描述

  • 子树:树根和其向下射出的部分。
  • 简单子树:有且只有单层分支的子树。
  • 子树的末端结支符号串是相对于子树根的短语
  • 简单子树的末端结点组成的符号串是相对于简单子树根的简单短语/直接短语。(根节点能够直接推出终结符)
  • 素短语:(在短语中找,至少含有一个终结符,且不含其他更小素短语)
  • 最左简单子树的末端结点组成的符号串是句柄。(句柄这个概念只会出现在最右推导/规范推导中才会出现的概念)

一个句型的最左 直接短语 称为该句型的句柄。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
根据文法画出语法树,进行推导:
在这里插入图片描述


在这里插入图片描述


二义性

在这里插入图片描述

  • 如果两种推导方式画出的树不同,则说明该文法有二义性。
  • 可能存在两个不同的最左推导,但是它们对应的语法树相同。

注意错误的说法如下(充分条件和必要条件的区别):

  1. 如果文法是二义的,则最左推导和最右推导必然不同(❌)
  2. 如果文法是二义的,则最左推导和最右推导对应的语法树必定相同。(❌)

在这里插入图片描述
在这里插入图片描述


二义文法由于无法进行语法分析,没有存在的必要。(❌)

解释: 二义文法并非无法进行语法分析,而是需要结合消除歧义的规则(如优先级、结合性)来唯一确定语法结构。在编译实践中,二义文法常被合理使用,以简化文法描述并保持分析的正确性,因此具有明确的存在价值。

第三章:词法分析

右线性文法

在这里插入图片描述

正规式

在这里插入图片描述


在这里插入图片描述

解析: 正规式的本质作用是定义和识别语言集合。当两个正规式 M 1 M_1 M1 M 2 M_2 M2 识别的语言集合相等时,即对于任意一个字符串,若 M 1 M_1 M1能识别(接受该字符串), M 2 M_2 M2 也能识别,反之亦然,那么就称这两个正规式等价 。


在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这一步可以先不看,先看后面的“根据正规式得到NFA”。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

题型:

  1. 根据正规式画出NFA图
  2. 根据NFA图,使用子集构造法
  3. 根据子集构造法,画出DFA(新状态集合中,凡是包含原来NFA终态的,都是新的终态)

参考视频。

根据正规式得到NFA

参考视频:【编译原理根据正规表达式构造NFA,到DFA,以及最后的DFA化简/最小化】
在这里插入图片描述

NFA的确定化和最小化

在这里插入图片描述
先以第(2)问进行讲解:
在这里插入图片描述
在这里插入图片描述
获取到确定化后的集合,也可以画出对应的图。

在这里插入图片描述
最小化是对已经确定好的DFA来说的,有这几个步骤:

  1. 初始化,将集合换分为两个集合:一个终态集合,一个其他集合
  2. 判断其他集合是否可区分:可区分就单独成一个集合。
    在这里插入图片描述

最终答案:

在这里插入图片描述

在这里插入图片描述

具有ε动作的NFA确定化

在这里插入图片描述
在这里插入图片描述
这里关于第一行 q 0 q_0 q0状态到 q 2 q_2 q2中,有 S 3 S_3 S3状态的解释:假设a,b,c是各种票,空是免费通过, S 2 S_2 S2用c票到了 S 2 S_2 S2,然后走免费通道到了 S 3 S_3 S3(必须先有一张票,才能走免费通道)
在这里插入图片描述


在这里插入图片描述


考察题目

  1. 没有ε边的有限自动机一定是DFA。(❌)

解释

  • DFA 要求每个状态对每个输入符号必须有且仅有一个确定的转移。
  • NFA 允许对同一输入符号存在多个转移(非确定性)或无转移,即使没有ε边也是如此。
  1. 不确定的有限自动机(NFA)可能存在一个以上的起始状态。(✔)

评分标准:
(1) 正规式得2分,构造NFA得4分(共6分)
(2) 子集构造法:表格4分,DFA 4分,最简判断1分(9分)

在这里插入图片描述
(1)正规式 a ( a ∣ b ) ∗ b a(a|b)^*b a(ab)b

这里中间部分 ( a ∣ b ) ∗ (a|b)^* (ab)的含义在前面讲解过:
在这里插入图片描述
中间部分的正规式可以表示为(a|b)*,但需要注意,这里中间部分可能为空,即允许字符串长度为2的情况(如ab)。因此,整个正规式可以写成:a(a|b)*b。这个表达式表示以a开头,中间有零个或多个a或b,最后以b结尾的所有字符串。

(2)得到NFA:
在这里插入图片描述

(3)根据子集构造法,得到最简DFA
ε-CLOSURE{S} = {S}

I ε I_ε Iε I a I_a Ia I b I_b Ib
q 0 q_0 q0{S}{A, B, C} q 1 q_1 q1
q 1 q_1 q1{A, B, C}{B, C} q 2 q_2 q2{B, C, Z} q 3 q_3 q3
q 2 q_2 q2{B, C}{B, C} q 2 q_2 q2{B, C, Z} q 3 q_3 q3
q 3 q_3 q3{B, C, Z}{B, C} q 2 q_2 q2{B, C, Z} q 3 q_3 q3
  • 始态: q 0 q_0 q0
  • 终态: q 3 q_3 q3

π = { { q 0 q_0 q0 q 1 q_1 q1 q 2 q_2 q2},{ q 3 q_3 q3}}

{ q 0 q_0 q0 q 1 q_1 q1 q 2 q_2 q2}不可区分:
在这里插入图片描述

第四章:自顶向下语法分析方法

在这里插入图片描述

在这里插入图片描述

First和Follow集

求这两个集合是后续做题的基础,所以必须会!!!

  • First(A):要找到左边等于A的产生式,然后看产生式的右部可能出现的终结符。空串也属于符号集。
  • Follow(A):要找到产生式右部含有A的产生式,然后查看A右边的情况,找出该非终结符后面所能跟随的所有终结符:
    • 如果A右边是空,则将Follow(左部非终结符) 添加到结果集中
    • 否则求出A右边符号串的First集 - 空串。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

LL(1)文法

当需要选用自顶向下分析技术时(文法到字符串),必须判别所给文法是否是LL(1)文法。因而对任给文法需首先计算FIRST、FOLLOW、SELECT集合,进而判别文法是否为LL(1)文法。

LL (1) 中第一个 L 表示从左到右扫描输入串,第二个 L 表示最左推导,1 表示向前看一个终结符。

判断一个文法是否是LL(1)文法,有两种方式(在使用这两个方法之前,还必须要消除文法的左递归和回溯):

First集的交集为空集

对于一个非终结符有多个产生式,才需要求出该非终结符的First集。
在这里插入图片描述
在这里插入图片描述

select集

选择符号集:
在这里插入图片描述

  1. 右部推导不出空串,就是First集
  2. 右部可以推导出空串,就是First集-空串,左部的Follow集。

在这里插入图片描述
所以说,判断一个文法是否是LL(1)文法,只需要求出 “一个非终结符号有多于两个的产生式” 的非终结符的select集。

非LL(1)文法到LL(1)文法的等价变换

以下这两个步骤,都是在考察LL(1)文法时要进行的第一步操作,类似于:
在这里插入图片描述

提取左公共因子

在这里插入图片描述

消除左递归

在这里插入图片描述

在这里插入图片描述

  1. 与E无关是β,这里是T
  2. 与E相关,出现在右边的是α

在这里插入图片描述


在这里插入图片描述

在这里插入图片描述

LL(1)分析的实现

表驱动分析程序/LL(1)分析表

  1. 先求出First集,如果一个非终结符能推出 ε ε ε,就需要求出Follow集
  2. 将产生式写到 是非终结符,其First集为终结符的
    在这里插入图片描述

在这里插入图片描述

递归向下分析方法

  • 一个非终结符对应一个子程序
  • 根据产生式的右部来设计:
    • 每遇到一个终结符,判断当前读入的单词是否与终结符匹配,如果匹配则继续读下一个单词;如果不匹配则进行错误处理。
    • 每遇到一个非终结符,则调用对应的子程序

在这里插入图片描述
在这里插入图片描述

分析过程

在这里插入图片描述

在这里插入图片描述


考察题目

评分标准:文法5+集合10+分析表3+分析过程2=20

在这里插入图片描述

(1)消除左递归和左公因子后的文法:

  • A → a A ′ A→a A' AaA
  • A ′ → A B c ∣ ε A'→ABc|ε AABcε
  • B → d B ′ B→dB' BdB
  • B ′ → b B ′ ∣ ε B'→bB'|ε BbBε
    在这里插入图片描述

(2)改造后的文法是LL(1)文法。预测分析表如下:

非终结符abcd#
A A → a A ′ A→a A' AaA
A’ A ′ → A B c A'→ABc AABc A ′ → ε A'→ε Aε A ′ → ε A'→ε Aε
B B → d B ′ B→dB' BdB
B’ B ′ → b B ′ B'→bB' BbB B ′ → ε B'→ε Bε

(3)输入串 ( aadc# ) 的分析过程:

步骤分析栈剩余输入串动作
1#Aa a d c # A → a A ′ A→a A' AaA
2#A’aa a d c #匹配a
3#A’a d c # A ′ → A B c A'→ABc AABc
4#cBAa d c # A → a A ′ A→a A' AaA
5#cBA’aa d c #匹配a
6#cBA’d c # A ′ → ε A'→ε Aε
7#cBd c # B → d B ′ B→dB' BdB
8#cB’dd c #匹配d
9#cB’c # B ′ → ε B'→ε Bε
10#cc #匹配c
11##匹配#,接受

输入串 ( aadc# ) 被成功分析。

第六章:LR分析

在这里插入图片描述

LR(0)项集规范族构造过程

  1. 增广文法的变换:开始符号有多个产生式,需要对开始符号进行增广文法的变换,使新的开始符号只有一个产生式。
  2. 列表的形式给出:状态、项目集、后继符号、后继状态
  3. 一个状态的项目集,就是在产生式右部写一个点,如果点后面(后继符号)是非终结符,则需要在项目集中添加该非终结符的产生式(右部也需要带点)

在这里插入图片描述
4. 还需要求 S 0 S_0 S0的项集中每一个式子的闭包,就是把点向后移动一个,如果点后面是非终结符,就进行上面的步骤;如果是终结符/空,就结束。
5. 如果是空,其后继符号就是把项目集抄一下,然后在前面加上一个#
6. 如果是终结符,其后继符号就是终结符

在这里插入图片描述
在这里插入图片描述

LR(0)文法

在这里插入图片描述

  • 如果 I i I_i Ii里同时有归约项目和移进项目,就是移进-归约冲突
  • 看一个状态 I i I_i Ii里面,是不是只存在一个归约项目,如果状态里有两个归约项目,京就是归约-归约冲突
  • 比如 I i I_i Ii明明是归约状态却又伸出来个箭头指向其他的状态就说明冲突了

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

分析表和分析过程

在这里插入图片描述


在这里插入图片描述
在这里插入图片描述

  1. 遇到 r i r_i ri时,使用第 i 个归约式进行出栈归约,并且GOTO[状态栈顶状态, 非终结符],如GOTO[5, B] = 9
  2. 将 GOTO[状态栈顶状态, 非终结符] 放到状态栈中,非终结符放到符号栈中。
  3. 直到 栈顶状态,输入串 = acc,结束

SLR(1)分析

判定

冲突项目集的简单向前看1集合的交集为空集,则是SLR(1)语法:

  • 归约-移进冲突:归约项的FOLLOW集,与移进项的终结符的交集。
  • 归约-归约冲突:求两者FOLLOW集的交集

在这里插入图片描述

分析表

与LR(0)分析表不同的是,对于归约项不要将一行全使用 r i r_i ri进行填写,而只是在FOLLOW(A)集合所在列填写。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

分析过程

在这里插入图片描述

LR(1)文法

在这里插入图片描述

  • 后继状态的向前搜索符,就是前一个状态的向前搜索符。
  • 当前集合的扩展闭包的向前搜索符,连接字符串的First集

冲突如何解决?

  • 归约-归约冲突,向前搜索符不相交,就可以解决冲突
  • 归约-移进冲突,归约项看向前搜索符,移进项还是看点后面的终结符。

表格:

  1. 归约项的列,由向前搜索符决定。写成 r i r_i ri
  2. 移进项的列,由点后面的终结符决定

LR1会使同心集分裂,所以它的状态数(项目集数)是最多的。

LALR(1)分析

  1. 拓广文法
  2. 合并同心集:产生式相同,合并向前搜索符
  3. 重新构造表
    在这里插入图片描述

如何区分LR文法

【11编译原理如何区别LR(0),SLR(1),LR(1),LALR(1)文法】

逆波兰表达式

找主运算符的原则:

  1. 括号内的表达式要先看作一个整体;
  2. 运算符优先级越低,也是主运算符;
  3. 在逆波兰表达式中越是右边的,越是主运算符

在这里插入图片描述
对于这个中缀表达式:

  1. 先将括号内部的表达式看作一个整体: E 1 = ( B ∗ D − C / A ) E_1 = (B*D-C/A) E1=(BDC/A),表达式变为 A ∗ E 1 + B A*E_1+B AE1+B
  2. 对于 A ∗ E 1 + B A*E_1+B AE1+B表达式,比较*和+的优先级,+的优先级较低,作为主运算符,写在逆波兰表达式的最后: ( A ∗ E 1 ) B + (A*E_1)B+ (AE1)B+

在这里插入图片描述

相关文章:

编译原理--期末复习

本文是我学习以下博主视频所作的笔记&#xff0c;写的不够清晰&#xff0c;建议大家直接去看这些博主的视频&#xff0c;他/她们讲得非常好&#xff1a; 基础知识概念&#xff1a; 1.【【编译原理】期末复习 零基础自学】&#xff0c;资料 2.【编译原理—混子速成期末保过】&…...

软件工程各种图总结

目录 1.数据流图 2.N-S盒图 3.程序流程图 4.UML图 UML用例图 UML状态图 UML时序图 5.E-R图 首先要先了解整个软件生命周期&#xff1a; 通常包含以下五个阶段&#xff1a;需求分析-》设计-》编码 -》测试-》运行和维护。 软件工程中应用到的图全部有&#xff1a;系统…...

Go 与 Gin 搭建简易 Postman:实现基础 HTTP 拨测的详细指南

Go 与 Gin 搭建简易 Postman&#xff1a;实现基础 HTTP 拨测的详细指南 文章目录 Go 与 Gin 搭建简易 Postman&#xff1a;实现基础 HTTP 拨测的详细指南项目简介代码结构各部分代码功能说明&#xff1a; 代码实现&#xff1a;main.go代码解释 handlers/probe.go代码解释 probe…...

层次原理图

层次原理图简介 层次原理图&#xff08;Hierarchical Schematic&#xff09;是一种常用于电子工程与系统设计的可视化工具&#xff0c;通过分层结构将复杂系统分解为多个可管理的子模块。它如同“设计蓝图”&#xff0c;以树状结构呈现整体与局部的关系&#xff1a;顶层展现系…...

嵌入式硬件篇---拓展板

文章目录 前言 前言 本文简单介绍了拓展板的原理以及使用。...

Redis的主从架构

主从模式 全量同步 首先主从同步过程第一步 会先比较replication id 判断是否是第一次同步假设为第一次同步 那么就会 启动bgsave异步生成RDB 同时fork子进程记录生成期间的新数据发送RDB给从节点 清空本地数据写入RDB 增量同步 对比ReplicationID不同因此选择增量同步在Rep…...

IIS入门指南:原理、部署与实战

引言&#xff1a;Web服务的基石 在Windows Server机房中&#xff0c;超过35%的企业级网站运行在IIS&#xff08;Internet Information Services&#xff09;之上。作为微软生态的核心Web服务器&#xff0c;IIS不仅支撑着ASP.NET应用的运行&#xff0c;更是Windows Server系统管…...

【上位机——WPF】布局控件

布局控件 常用布局控件Panel基类Grid(网格)UniformGrid(均匀分布)StackPanel(堆积面板)WrapPanel(换行面板)DockerPanel(停靠面板)Canvas(画布布局)Border(边框)GridSplitter(分割窗口)常用布局控件 Grid:网格,根据自定义行和列来设置控件的布局StackPanel:栈式面板,包含的…...

使用 C# 入门深度学习:线性代数详细讲解

在深度学习的领域中&#xff0c;线性代数是基础数学工具之一。无论是神经网络的训练过程&#xff0c;还是数据的预处理和特征提取&#xff0c;线性代数的知识都无处不在。掌握线性代数的核心概念&#xff0c;对于理解和实现深度学习算法至关重要。在本篇文章中&#xff0c;我们…...

操作系统之EXT文件系统

1.理解硬件 1.1磁盘、服务器、机柜、机房 机械磁盘是计算机中唯一的一个机械设备 磁盘--- 外设慢容量大&#xff0c;价格便宜 1.1.1光盘 1.1.2服务器 1.1.3机房 1.2磁盘的物理结构 1.3磁盘的存储结构 一个盘片又两个面 每个面都有一个磁头 磁头沿着盘面的半径移动 1.3.1…...

继MCP、A2A之上的“AG-UI”协议横空出世,人机交互迈入新纪元

第一章&#xff1a;AI交互的进化与挑战 1.1 从命令行到智能交互 人工智能的发展历程中&#xff0c;人机交互的方式经历了多次变革。早期的AI系统依赖命令行输入&#xff0c;用户需通过特定指令与机器沟通。随着自然语言处理技术的进步&#xff0c;语音助手和聊天机器人逐渐普…...

Java大厂面试:从Web框架到微服务技术的场景化提问与解析

Java大厂面试&#xff1a;从Web框架到微服务技术的场景化提问与解析 场景&#xff1a; 某知名互联网大厂的面试现场。面试官一脸严肃&#xff0c;对面坐着搞笑的程序员谢飞机。以下是他们的对话&#xff1a; 第一轮&#xff1a;Web框架基础与数据库操作 面试官&#xff1a;谢…...

最新缺陷检测模型:EPSC-YOLO(YOLOV9改进)

目录 引言:工业缺陷检测的挑战与突破 一、EPSC-YOLO整体架构解析 二、核心模块技术解析 1. EMA多尺度注意力模块:让模型"看得更全面" 2. PyConv金字塔卷积:多尺度特征提取利器 3. CISBA模块:通道-空间注意力再进化 4. Soft-NMS:更智能的重叠框处理 三、实…...

leetcode hot100刷题日记——2.字母异位词分组

涉及知识点:vector、哈希表 解答我的解答的时间复杂度分析我的解答的空间复杂度分析复习&#xff1a;排序算法的时间复杂度 和第一题需要的知识点相同&#xff0c;所以知识点复习可见 link1《leetcode hot100刷题日记——1.两数之和》 解题思路&#xff1a;是字母异位词的字符…...

elementUI 单选框存在多个互斥的选项中选择的场景

使用 el-radio-group 来使用单选框组&#xff0c;代码如下&#xff1a; <el-radio-group input"valueChangeHandler" v-model"featureForm.type"><el-radio name"feature" label"feature">业务对象</el-radio><…...

基于区块链技术的智能汽车诊断与性能分析

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 钝感力的“钝”&#xff0c;不是木讷、迟钝&#xff0c;而是直面困境的韧劲和耐力&#xff0c;是面对外界…...

基于区块链技术的供应链溯源系统:重塑信任与透明度

在当今全球化的商业环境中&#xff0c;供应链的复杂性不断增加&#xff0c;产品从原材料采购到最终交付消费者手中的过程涉及多个环节和众多参与者。然而&#xff0c;传统供应链管理面临着诸多挑战&#xff0c;如信息不透明、数据易篡改、追溯困难等&#xff0c;这些挑战不仅影…...

基于OpenCV的实时文档扫描与矫正技术

文章目录 引言一、系统概述二、核心代码解析1. 导入必要库2. 辅助函数定义3. 坐标点排序函数4. 透视变换函数5. 主程序流程 三、完整代码四、结语 引言 在日常工作和学习中&#xff0c;我们经常需要将纸质文档数字化。手动拍摄文档照片常常会出现角度倾斜、透视变形等问题&…...

基于STM32F103与Marvell88W8686的WIFI无线监控视频传输系统研发(论文)

基于STM32F103与Marvell88W8686的WIFI无线监控视频传输系统研发 中文摘要 在当今社会信息化进程不断加速的时代背景下&#xff0c;众多领域对于监控系统的需求日益增长&#xff0c;像车内安全监控、电梯运行监控等场景都离不开监控系统的支持。过去&#xff0c;不少领域普遍采用…...

华为云Astro中各种变量与参数的区别与用法

目录 🧠 华为云 Astro 各类变量与参数详解 🧩 一、变量与参数的核心作用是什么? 🖼️ 二、整体分类与结构图 📘 三、逐一详细解析 + 类比说明 + 使用建议 🔹 1. 输入参数(Input Parameter) 🔹 2. 输出参数(Output Parameter) 🔹 3. 变量(本地变量)…...

数字人技术的核心:AI与动作捕捉的双引擎驱动(210)

**摘要&#xff1a;**数字人技术从静态建模迈向动态交互&#xff0c;AI与动作捕捉技术的深度融合推动其智能化发展。尽管面临表情僵硬、动作脱节、交互机械等技术瓶颈&#xff0c;但通过多模态融合技术、轻量化动捕方案等创新&#xff0c;数字人正逐步实现自然交互与情感表达。…...

华为云Astro轻应用创建业务对象(BO)的概念梳理

目录 一、业务对象(BO)是什么?——【详细概念解释】 二、形象理解业务对象(BO) 🍱 类比方式: 📦 举个具体例子:以做一个“智能烟雾报警系统”应用 三、为什么使用BO很重要? 四、小结: 一、业务对象(BO)是什么?——【详细概念解释】 在华为云Astro轻应用…...

MySQL开发规范

目录 一、建表规约 二、索引规约 三、SQL语句 四、 ORM映射 一、建表规约 强制&#xff1a; 1、表达是与否概念的字段&#xff0c;必须使用is_xxx的方式命名&#xff08;PoJo中不加is前缀&#xff09;&#xff0c;数据类型是unsigned tinyint&#xff08;1表示是&#xf…...

K8s入门教程(一)

Kubernetes(K8s)入门教程:从零开始掌握容器编排 目录 Kubernetes(K8s)入门教程:从零开始掌握容器编排 1. Kubernetes 简介 1.1 什么是 Kubernetes? 1.2 核心功能 2. 环境搭建与 Minikube 安装 2.1 安装 Minikube 安装步骤(以 macOS 为例): 安装 kubectl(Kub…...

k8s备份namespace

在 Kubernetes 中备份 Namespace 有多种方法&#xff0c;以下是几种常见的备份方式&#xff1a; 1.使用 kubectl 命令备份 通过 kubectl 命令可以导出指定 Namespace 中的资源&#xff0c;生成 YAML 文件进行备份。 备份所有资源&#xff1a; kubectl -n <namespace> ge…...

前端动画库 Anime.js 的V4 版本,兼容 Vue、React

前端动画库 Anime.js 更新了 V4 版本&#xff0c;并对其官网进行了全面更新&#xff0c;增加了许多令人惊艳的效果&#xff0c;尤其是时间轴动画效果&#xff0c;让开发者可以更精确地控制动画节奏。 这一版本的发布不仅带来了全新的模块化 API 和显著的性能提升&#xff0c;还…...

OpenHarmony外设驱动使用 (四),Face_auth

OpenHarmony外设驱动使用 &#xff08;四&#xff09; Face_auth 概述 功能简介 人脸识别功能是端侧设备不可或缺的一部分&#xff0c;为设备提供一种用户认证能力&#xff0c;可应用于设备解锁、支付、应用登录等身份认证场景。它是基于人的脸部特征信息进行身份识别的一种…...

【Java ee初阶】jvm(1)

一、JVM Java虚拟机 面试中相关的问题有三块&#xff1a; 1.JVM内存区域划分 2.JVM的类加载机制 3.JVM的垃圾回收机制 JDK、JRE 和 JVM 的关系 JDK&#xff08;Java Development Kit&#xff09;是 Java 开发工具包&#xff0c;包含了编写、编译和调试 Java 程序所需的所…...

【Java ee初阶】jvm(2)

类加载机制&#xff1a; JVM从最开始的读取.class文件&#xff0c;到最终构造完成 类 对象的整个过程&#xff0c;也就是把 类 从硬盘 加载到内存中的机制。 Java的类加载机制主要分为五个步骤&#xff1a;加载、验证、准备、解析和初始化。 步骤一 加载&#xff08;Loading…...

Django 项目创建全攻略

目录 一、环境准备​ 1. 安装 Python​ 2. 安装虚拟环境&#xff08;可选但推荐&#xff09;​ 3. 安装 Django​ 二、创建 Django 项目​ 1. 使用命令创建项目​ 2. 运行开发服务器​ 三、创建 Django 应用​ 1. 创建应用​ 2. 注册应用​ 四、配置项目​ 1. 数据…...

windows11 安装好后右键没有 git bash 命令

win键 R 键&#xff0c;输出 regedit&#xff0c;打开注册表 找到 \HKEY_CLASSES_ROOT\Directory\Background\shell 新建项 git-bash 然后在 git-bash 下在新建项 Command&#xff0c;默认值设为 "C:\Program Files\Git\git-bash.exe" --cd"%v." 在 …...

Java八股文——Java基础篇

目录 1、你是怎样理解OOP面向对象2、重载和重写的区别3、接口与抽象类的区别4、深拷贝与浅拷贝的理解5、sleep和wait区别主要区别 6、什么是自动拆装箱&#xff0c;int和Integer有什么区别自动拆装箱int和Integer的区别Integer缓存机制 7、和equals区别String特殊情况 8、Strin…...

蓝桥杯19682 完全背包

问题描述 有 N 件物品和一个体积为 M 的背包。第 i 个物品的体积为 vi​&#xff0c;价值为 wi​。每件物品可以使用无限次。 请问可以通过什么样的方式选择物品&#xff0c;使得物品总体积不超过 M 的情况下总价值最大&#xff0c;输出这个最大价值即可。 输入格式 第一行…...

2025年- H27-Lc135- 239.滑动窗口最大值(自定义双端队列)---java版

1.题目描述 2.思路 &#xff08;1&#xff09;双端队列可以移除最左边的元素&#xff0c;也可以移除最右边的元素&#xff08;两端移除&#xff09; &#xff08;2&#xff09;在最右边插入元素&#xff08;右边加入&#xff09; &#xff08;3&#xff09;队列单调性&#xf…...

EKS 工作节点的集群网络架构

AWS EKS&#xff08;弹性 Kubernetes 服务&#xff09;是亚马逊提供的托管 Kubernetes 服务&#xff0c;一旦配置完成&#xff0c;即可像变魔术一样运行。但这通常是 EKS 的默认设置。如果您打算根据组织的设计、合规性标准和隐私要求进行自定义&#xff0c;该怎么办&#xff1…...

【技海登峰】Kafka漫谈系列(十一)SpringBoot整合Kafka之消费者Consumer

【技海登峰】Kafka漫谈系列(十一)SpringBoot整合Kafka之消费者Consumer spring-kafka官方文档: https://docs.spring.io/spring-kafka/docs/2.8.10/reference/pdf/spring-kafka-reference.pdf KafkaTemplate API: https://docs.spring.io/spring-kafka/api/org/springframe…...

Python字符串格式化(一):三种经典格式化方法

文章目录 一、% operator&#xff1a;C语言风格的初代格式化方案&#xff08;Python 2.0引入&#xff09;1. 语法核心&#xff1a;占位符与类型码2. 进阶用法&#xff1a;格式修饰符3. 致命缺陷&#xff1a;类型严格匹配的陷阱4. 适用场景&#xff1a;旧代码维护的兼容性选择 二…...

浅谈无服务器WebSocket的优势

实际上&#xff0c;一个实用的解决方案是将构建业务关键型实时平台的复杂性卸载到专门的云服务中。 完全托管的无服务器 WebSocket 解决方案为事件驱动的消息传递提供了基础结构;它使底层基础设施成为一种商品。客户端使用提供程序服务发送/接收低延迟消息&#xff0c;并专注于…...

10.7 LangChain v0.3架构大升级:模块化设计+多阶段混合检索,开发效率飙升3倍!

LangChain v0.3 技术生态与未来发展 关键词:LangChain Chains, Agents 架构, Retrieval Strategy, LangGraph, 模块化设计 3. LangChain 项目:Chains, Agents, Retrieval Strategy LangChain v0.3 通过 Chains-Agents-Retrieval 三位一体的技术栈,构建起完整的大模型应用开…...

GLPK(GNU线性规划工具包)中建模语言MathProg的使用

GNU MathProg是一种用于描述线性数学规划模型的建模语言。用GNU MathProg语言编写的模型描述由一组语句和数据块组成。 在MathProg中&#xff0c;模型以集合、参数、变量、约束和目标(sets, parameters, variables, constraints, objectives称为模型对象)的形式进行描述。 在Ma…...

系统思考:IT企业项目困境分析

最近遇到一家快速发展的IT技术公司&#xff0c;遭遇了项目进度滞后、团队沟通不畅和资源分配不合理等一系列挑战。虽然他们拥有一支技术强大的团队&#xff0c;但在项目管理和团队协作上却显得力不从心。结果&#xff0c;多个项目超预算、交期延迟&#xff0c;客户满意度直线下…...

计算机网络 - 2.基础协议

1.TCP协议 1.TCP(Transmission Control Protocol):传输控制协议2.TCP协议是一种面向连接的、可靠的、 基于字节流的传输层通信协议 1.面向连接:两个使用TCP协议的应用(通常一个客户和一个服务器)在彼此交换数据包之前必须先建立一个TCP连接2.可靠的 1.数据传输之前都要建立…...

go语法大赏

前些日子单机房稳定性下降&#xff0c;找了好一会才找到真正的原因。这里面涉及到不少go语法细节&#xff0c;正好大家一起看一下。 一、仿真代码 这是仿真之后的代码 package mainimport ("fmt""go.uber.org/atomic""time" )type StopSignal…...

运行vscode编辑器源码

距离上次二次开发vscode已经是三年前的事了&#xff0c;当时是1.60.0版本&#xff0c;目前vscode已升级到了1.99.2版本&#xff0c;里面改动很大&#xff0c;最近下载下来了新版源码跑起来看看 准备node、python 源码里面node版本做了限制 2025-01-27 09:53:00.450 [info] Fo…...

ShenNiusModularity项目源码学习(26:ShenNius.Admin.Mvc项目分析-11)

本文学习并分析ShenNiusModularity项目中商城系统模块的小程序用户页面、用户收货地址页面。 1、小程序用户页面 小程序用户页面用于检索、浏览使用商城系统的用户数据&#xff08;保存在shop_appuser表内&#xff0c;系统用户保存在sys_user表内&#xff09;&#xff0c;该页…...

C#中的成员常量:编译时的静态魔法

在C#编程中&#xff0c;常量(const)是一个强大而特殊的语言特性&#xff0c;特别是当它们作为类的成员时。本文将深入探讨成员常量的特性、使用场景以及与静态量的区别。 成员常量的基本特性 成员常量是声明在类内部的常量&#xff0c;具有以下核心特点&#xff1a; 声明位置…...

C# 深入理解类(成员常量)

成员常量 成员常量类似前一章所述的局部常量&#xff0c;只是它们被声明在类声明中而不是方法内&#xff0c;如下面的 示例&#xff1a; 与局部常量类似&#xff0c;用于初始化成员肯量的值在编译时必须是可计算的&#xff0c;而且通常是一个预定 义简单类型或由它们组成的表达…...

服务端HttpServletRequest、HttpServletResponse、HttpSession

一、概述 在JavaWeb 开发中&#xff0c;获取客户端传递的参数至关重要。http请求是客户端向服务端发起数据传输协议&#xff0c;主要包含包含请求行、请求头、空行和请求体四个部分&#xff0c;在这四部分中分别携带客户端传递到服务端的数据。常见的http请求方式有get、post、…...

有哪些GIF图片转换的开源工具

以下是关于GIF图片转换的开源工具的详细总结,涵盖功能特点、适用场景及用户评价: 1. FFmpeg 功能特点: 作为开源命令行工具,FFmpeg支持视频转GIF、调整帧率、分辨率、截取片段等操作,可通过脚本批量处理。适用场景: 适合开发者或技术用户进行高效批处理,常用于服务器端自…...

Vue.js教学第五章:计算属性与侦听器详解

Vue.js 之计算属性与侦听器详解 一、计算属性 (一)概念 计算属性(Computed Properties)是 Vue.js 中的一个核心概念。它允许我们基于一个或多个数据属性来定义一个新的属性,该属性的值会根据其依赖的数据属性的变化而自动更新。这就好像是一个 “智能” 属性,它的值不是…...