编译原理四元式实验_记一次编译原理实验——词法+语法&语义分析(Python实现)...

2023-11-11

记一次编译原理实验——词法+语法&语义分析(Python实现)

编译原理是每个CS学子的必修课。编译原理的实验课对提高我们对编译过程的理解很重要。

本文章写于实验结束后,所有代码已上传至Github : https://github.com/kabu1204/compilation。

建议拉到底下点击阅读原文,微信排版不行,表格内的公式加载不出来,而且LATEX的换行符失效。

水平有限,如有问题还望指正。

环境:Python 3.6.9

  • 词法分析器

    • 预处理

    • DFA

  • 语法分析——LR(1)的强大

    • LR(1)文法

    • 自动求FIRST集

    • 自动推导LR(1)项目集族和生成ACTION & GOTO表

  • 语义分析

    • 文法改写

    • 预先定义的一些东西

    • 真链 假链 回填

    • 语义动作

    • 运行结果

词法分析器

一个编程语言的词法通常用正规文法描述,由正则表达式表示,使用DFA进行识别,三者在描述能力/识别能力上是等价的。

事实上,正则表达式的匹配就是使用DFA作为引擎的,当然也有NFA引擎。

在这一部分,我们要设计并实现SAMPLE语言的词法分析器,自然,设计的重点是其识别工具:DFA.

当然我们也可以直接使用正则表达式进行匹配,但这对我们理解DFA的原理并无裨益,不过我还是用到了RE库来实现源程序文本的切分。

下面介绍一下我实现词法分析器的过程。

预处理

读入的源程序实际上是一个字符串,而词法分析的对象是一个个单词(包括界符)。显然,能将其分为一个一个具有独立意义的单词,更便于我们的处理。

为了实现切分,我们先介绍一个函数re.split()

re.split()

re.split(pattern:AntStr, string:AnyStr)

第一个参数pattern是划分依据的正则表达式,第二个参数string是要进行划分的字符串。

  • 按一个单字符切分:
>>> s="var A;B;C:integer;"
>>> re.split(r";",s)
['var A', 'B', 'C:integer', '']

如果字符串最后一个字符是被切分字符,则切分时还会产生一个''字符

  • 按多个单字符切分(用[]框住):
>>>re.split(r"[;:]",s)
['var A', 'B', 'C', 'integer', '']
  • 分组:
>>>re.split(r"(;)",s)
['var A', ';', 'B', ';', 'C:integer', ';', '']

此时默认保留切分符

  • 分组不保留:
>>>re.split(r"(?:;)",s)
['var A', 'B', 'C:integer', '']
  • 多字符切分:
>>>re.split(r“(in)",s)
['var A;B;C:', 'in', 'teger;']
  • 组合情况:
>>>re.split(r"(in|er|[A-C]|[;:])",s)
['var ', 'A', '', ';', '', 'B', '', ';', '', 'C', '', ':', '', 'in', 'teg', 'er', '', ';', '']

那么对于源程序,我们切分的依据又是什么呢?

  • 首先想到的肯定是各种空白字符:”\n“,"\t","\n"等。由于本实验所分析的文法对缩进是不敏感的,因此在使用这些空白字符进行划分时,我们无需保留它们。

使用\s匹配所有单个空白字符,等价于[\f\n\r\t\v]

import re

with open(file_path,'r') as f:
    raw=f.read()
print(raw)
print(re.split(r"\s",raw))

运行结果

program example2;
var  A,B,C:integer;
     X,Y:bool;
begin  /*  this  is  an  example  */
  A:=B*C+37;
  X:='ABC'
end.

['program', 'example2;', 'var', '', 'A,B,C:integer;', '', '', '', '', '', 'X,Y:bool;', 'begin', '', '/*', '', 'this', '', 'is', '', 'an', '', 'example', '', '*/', '', '', 'A:=B*C+37;', '', '', "X:='ABC'", 'end.', '']

可以看到,很多保留字、标识符等还和;:,:=这些界符黏在一起,我们还要进一步切分

但是请注意,我们不能直接把所有界符当作切分符,因为双界符通常由两个单界符构成,放在一起切分会拆开双界符。

  • 因此我们需要先根据双界符进行切分。
import re

with open(file_path,'r') as f:
    raw = f.read()
PreSplit = re.split(r'(<>|<=|>=|:=|/\*.*\*/|\.\.|\s)', raw)
print(PreSplit)

运行结果

['program', ' ', 'example2;', '\n', 'var', ' ', '', ' ', 'A,B,C:integer;', '\n', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', 'X,Y:bool;', '\n', 'begin', ' ', '', ' ', '', '/*  this  is  an  example  */', '', '\n', '', ' ', '', ' ', 'A', ':=', 'B*C+37;', '\n', '', ' ', '', ' ', 'X', ':=', "'ABC'", '\n', 'end.', '\n', '']
  • 然后我们还可以把一些不参与构成双界符的单界符(如+,-,(,']'等)也加入:
import re

with open(file_path,'r') as f:
    raw = f.read()
PreSplit = re.split(r'(<>|<=|>=|:=|/\*.*\*/|\.\.|[\+\-\(\)\[\];,\s])', raw)
print(PreSplit)

运行结果

['program', ' ', 'example2', ';', '', '\n', 'var', ' ', '', ' ', 'A', ',', 'B', ',', 'C:integer', ';', '', '\n', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', 'X', ',', 'Y:bool', ';', '', '\n', 'begin', ' ', '', ' ', '', '/*  this  is  an  example  */', '', '\n', '', ' ', '', ' ', 'A', ':=', 'B*C', '+', '37', ';', '', '\n', '', ' ', '', ' ', 'X', ':=', "'ABC'", '\n'
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编译原理四元式实验_记一次编译原理实验——词法+语法&语义分析(Python实现)... 的相关文章

  • springboot添加验证码功能

    开源验证码 1 Happy Captcha 提供了图片和动画两种展现形式 验证码内容包括中文 数字 09 中文数字 零至九 中文大写数字 零至玖 数字与字母混合 09 az AZ 数字与小写字母混合 09 az 数字与大写字母混合 09 A
  • Clang 中 AST 相关类简介(不定时更新)

    Clang 中 AST 相关类简介 不定时更新 1 Decl declaration 1 1 FunctionDecl 2 Stmt statement 3 Expr expression 3 1 FullExpr 3 2 ExprWith
  • 【Grub2】BIOS添加Grub2引导(Windows下操作)

    电脑上安装的系统是Windows10 BIOS MBR 想利用Grub2安装CentOS 和RemixOS三个操作系统 为了实现硬盘安装CentOS 需要用到Grub2 第一步 Grub2下载 文件准备到Grub2官网ftp ftp gnu
  • C语言库函数— qsort () 详解

    目录 1 qsort 函数简介 1 1 函数原型 1 2 函数参数 2 比较函数简介 2 1 比较函数参数 2 2 比较函数使用 3 qsort 函数使用 3 1 整形数组排序 3 2 字符数组排序 3 3 浮点型数组排序 double类型
  • 降压式变换电路(Buck电路)详解

    降压式变换电路 Buck电路 详解 一 BUCK电路基本结构 开关导通时等效电路 开关关断时等效电路 二 等效的电路模型及基本规律 1 从电路可以看出 电感L和电容C组成低通滤波器 此滤 波器设计 的原则是使 us t 的直流分量可以通过
  • 计算机英语第三版司爱华,論计算机英语的特征.doc

    論计算机英语的特征 毕业设计 论文 题目 论计算机英语的特征 形式 层次 专科 专业 经贸英语 班号 学号 学生姓名 指导教师 年 月 日 摘 要 计算机英语是英语的一个分支 属于专业英语的范畴 所以有其自己的特征本文主要从计算机英语的词汇
  • 第2天:基础入门-数据包拓展

    前言 如有不妥之处 还望指正 目录 前言 1 网站解析对应 2 HTTP HTTPS数据包 2 1 HTTP 与 HTTPS 区别 2 2 HTTP简要通信过程 2 3 HTTPS简要通信过程 2 4 Request请求数据包数据格式 2
  • AI真的快让我失业了

    以下文章来源于深燃 作者深燃团队 编辑 深燃 聚焦创新经济 专注深度内容 来源 深燃 ID shenrancaijing 作者 邹帅 李秋涵 王敏 唐亚华 王璐 编辑 李秋涵 本文已获授权 跟AI有关的新闻 一个接着一个 前一天你还和往常一
  • 光纤收发器的六个指示灯代表是什么意思?

    对光纤收发器这块了解的朋友应该知道 光纤收发器有6个LED指示灯 它们分别显示了收发器的工作状态 根据LED所示 我们就能判断出收发器是否工作正常和可能有什么问题 从而能帮助找出故障 那么 光纤收发器的六个指示灯分别代表什么意思 有哪些作用
  • 刷题_day2:双指针法

    题目介绍 给你一个数组 nums 和一个值 val 你需要 原地 移除所有数值等于 val 的元素 并返回移除后数组的新长度 可以使用暴力解法 嵌套两个for循环 但是时间复杂度为O n2 双指针法 快慢指针 可以利用两个指针 在一次for
  • Spring Boot自动装配原理(易懂)

    Spring Boot的自动装配原理 易懂 熟练使用Spring Boot那么自动装配原理的掌握是必不可少的 文章目录 Spring Boot的自动装配原理 易懂 一 自动装配是什么 二 启动类注解流程关系分析 1 首先展示 SpringB
  • R语言中如何给向量改变赋值

    R语言中如何给向量改变赋值 一 创建向量 二 访问向量特定位置 三 改变向量特定位置赋值 结果 一 创建向量 a lt c rep 冬季盛宴 5 rep 盛宴 6 二 访问向量特定位置 代码如下 示例 在这里插入代码片 a 4 三 改变向量
  • ln: 创建符号链接 "/usr/bin/java": 文件已存在

    执行下述命令创建软链接 ln s JAVA HOME bin java usr bin java 出现下述错误提示 ln 创建符号链接 usr bin java 文件已存在 这种情况可以通过命令ll检查下 usr bin java现有的软链
  • Shell 批量搜索关键词并保存结果到文件中(数组、循环)

    bin bash keywords 不需要 不用谢谢 xxx xxx for var in keywords do echo var cat corpus txt grep var wc l cat corpus txt grep var
  • 微信支付V3 生成平台证书

    微信支付V3里必须有平台证书文件 才能唤起唤醒支付 平台证书生成前提需要提前下载好设置apikey3后下载的证书3个证书文件 apiclient key pem apiclient cert pem apiclient cert p12 官
  • C++ 栈和队列

    前言 前几次我们学习了vector list 分别对应线性表和链表 这两个基础的数据结构 本篇 我们将基于前面知识的基础 学习线性表和链表的应用结构 栈和队列 文章目录 前言 一 栈 1 概要 2 适配器 配接器模式 3 栈的使用 4 模拟
  • 富文本编辑器提取纯文本(uniapp、vue没有简介用详情替代)

    1 js方法 filtersText val if val null val let reg u4e00 u9fa5 g let names val match reg val names names join return val els
  • 以太坊之Downloader同步区块流程

    随着以太坊的数据越来越多 同步也越来越慢 使用full sync mode同步的话恐怕得一两个礼拜也不见得能同步完 以太坊有fast sync mode 找了些文章还不是很明白具体内容 所以尝试着看懂写下来 如有错误之处欢迎指正 关于fas
  • Python3 实现进度条

    本文实例讲述了Python显示进度条的方法 是Python程序设计中非常实用的技巧 分享给大家供大家参考 具体方法如下 首先 进度条和一般的print区别在哪里呢 答案就是print会输出一个 n 也就是换行符 这样光标移动到了下一行行首

随机推荐

  • sykwalking分布式微服务链路追踪

    不做介绍 直接上教程 skuwalking历史版本下载地址 https archive apache org dist skywalking 一 安装服务端 下载apache skywalking apm 8 4 0 tar gz 丢到服务
  • Java的垃圾回收机制介绍

    1 java的语言框架 1 CPU gt 操作系统内核 gt 应用层框架 gt JVM java虚拟机 gt Java字节码 gt Java源代码 2 java是解释型语言 嵌入式常用的C C 是编译型语言 简单来说 编译型语言只需要编译一
  • Amy-Tabb机器人世界手眼标定(1、环境搭建)

    本文为https github com amy tabb RWHEC Tabb AhmadYousef的环境搭配 写的有点乱 遇到类似问题可以直接ctrl f进行全局搜索查找 sudo命令 Linux sudo命令以系统管理者的身份执行指令
  • DCGAN,即深度卷积 GAN

    DCGAN 即深度卷积 GAN 是一种生成对抗网络架构 它使用了一些指南 特别是 用跨步卷积 鉴别器 和分数跨步卷积 生成器 替换任何池化层 在生成器和鉴别器中使用 batchnorm 为更深层次的架构移除完全连接的隐藏层 在生成器中对所有
  • 渗透测试工具Burpsuite

    学习文档 https portswigger net burp documentation desktop getting started download and install Burp Suite是一款流行的集成式Web应用程序安全测
  • 测试老鸟经验,性能测试重点17个疑难解答,一篇打通...

    目录 导读 前言 一 Python编程入门到精通 二 接口自动化项目实战 三 Web自动化项目实战 四 App自动化项目实战 五 一线大厂简历 六 测试开发DevOps体系 七 常用自动化测试工具 八 JMeter性能测试 九 总结 尾部小
  • cmos是计算机主板上的一块可读写,关于基本输入输出系统(BIOS)及CMOS存储器,下列说法中错误的是...

    选B CMOS通常是指主板上一块可读写的存储芯片 它用于存储计算机的时钟信息和硬件配置信息等内容BIOS芯片是主板上一块长方型或正方型芯片 BIOS中主要存放 自诊断程序 加电自检程序 通过读取CMOS RAM中的内容识别硬件配置 并对其进
  • Burpsuite使用教程

    目录 Burpsuite基础 1 Proxy 2 spider 3 Decoder burp 进阶 1 Scanner 2 intruder 3 Repeater 4 comparer 5 sequencer Burp Suite是一款集成
  • SQL计算留存率等指标

    一 问题1 留存率计算 字段及表说明 表名 user log 字段名 log day 登录日期 device id 用户设备id app id 用户app的id 其中device id和app id确定唯一的用户 1 1计算某日留存率 次日
  • 关于SD卡挂载失败问题的解决方法

    单片机为STM32F103RBT6 SD卡为金士顿8G 在SD卡初始化通过后 在挂载SD卡时 遇到了问题 挂载部分代码如下 exfuns init 为fatfs相关变量申请内存 while FR OK f mount pfs 0 0 1 挂
  • 房屋、贷款相关公开数据集(免费下载链接)

    1 Loan Prediction 简单的贷款预测 贷款预测 包含贷款ID 性别 婚否 教育 贷款价格等 DataCastle 数据科学创新与实践平台https www datacastle cn dataset description h
  • 【软件测试】单元测试、系统测试、集成测试的区别及示例

    目录 一 单元测试 二 集成测试 三 系统测试 一 单元测试 定义 单元测试是对软件组成单元进行测试 细粒度 测试目的 用于检验软件基本组成单位的正确性 测试对象 一个工作单元 通常是类内部的一个方法 测试使用方法 白盒测试 测试依据 详细
  • “ldd”命令详解

    ldd 命令详解 ldd 1 语法 2 举例说明 背景知识 1 ldd不是一个可执行程序 而只是一个shell脚本 2 ldd实质是通过ld linux so elf动态库的装载器 来实现的 3 ld linux so查找共享库的顺序 3
  • 二、@RequestMapping注解和参数的获取

    1 RequestMapping RequestMapping value testRequestMapping method RequestMethod POST params username jack headers Accept v
  • 53.Eight (15分待续)

    题目内容 在3 3的棋盘上 摆有八个棋子 每个棋子上标有1至8的某一数字 棋盘中留有一个空格 空格用0来表示 空格周围的棋子可以移到空格中 要求解的问题是 给出一种初始布局和目标布局 为了使题目简单 设目标状态为 1 2 3 8 0 4 7
  • 用SPM技术固定EBS标准功能的SQL执行计划

    Introduction介绍 本文是Oracle SPM技术的一个应用实例 分享给没了解过SPM或者没用过SPM的老铁们 通过本文 应该要了解什么是SPM 它的作用是什么 它的应用场景是什么 这个应用实例总结就是 通过使用SPM技术 固定S
  • 找错:ZdalRuleCalculateException: 规则引擎计算出错,拆分值=

    序言 这一段是我遇上问题的过程 可以直接跳转到下面的正文 在刚写的博客 Zdal分库分表介绍 超详细一步一步搭建简单的zdal框架 中 是通过向线程中存放数据库远程路由来指定操作哪个数据库 在mybatis执 行插引用块内容入操作时 会从数
  • JVM调优

    1 查看当前jvm使用详情 java XX PrintGCDetails或者 Xloggc data jvm gc log或者 verbose gc 2 JVM调优工具 jps l 查看java程序pid 3 jstat gc pid 50
  • IMT-2030(6G)推进组发布《6G总体愿景与潜在关键技术》白皮书

    来源 中国信通院CATCT 编辑 蒲蒲 当前 新一轮科技革命和产业变革突飞猛进 随着5G商用的大规模部署 全球业界已开启对下一代移动通信 6G 的探索研究 日前 IMT 2030 6G 推进组 以下简称 推进组 正式发布 6G总体愿景与潜在
  • 编译原理四元式实验_记一次编译原理实验——词法+语法&语义分析(Python实现)...

    记一次编译原理实验 词法 语法 语义分析 Python实现 编译原理是每个CS学子的必修课 编译原理的实验课对提高我们对编译过程的理解很重要 本文章写于实验结束后 所有代码已上传至Github https github com kabu12