c++ 模板类实现堆栈实验报告_编译原理——小型类C编译器的设计和实现(生成8086汇编代码)之1:问题定义以及总体功能...

前面花了两篇文章来介绍词法分析和语法分析,接下来才是比较有意思的部分——一个小型类C编译器的设计和实现(其实是编译原理的课程设计啦!~)我用的是python2.7.13+PyQt来做的。。。事实上,正是从编译原理课程设计开始,我开始转战python,这也算是用python写的第一个程序吧^_^局限性肯定是存在的,只要大家从中能get到一点点于自己而言有用的东西我就灰常开森了O(∩_∩)O哈哈~最后,欢迎大家批评指正!THX~

一、 实验目标

  1. 了解形式语言与自动机理论在计算机中的应用,掌握文法的构造方法。
  2. 了解词法分析的原理,并掌握利用语法栈对词法分析的结果进行自上而下的语法分析的方法。
  3. 了解中间代码的构成形式,掌握语法制导的翻译方法和跳转回填的方法。
  4. 了解8086汇编语言的语法,并掌握利用语义分析生成的中间代码进行目标代码生成的方法。
  5. 了解一遍完成的、简单语言的编译方法。
  6. 在上述基础上,实现一个类C编译器,要求读入指定格式的C语言代码并生成8086汇编代码。(选择了含过程调用的文法)

二、开发前提

1.开发语言

选取python作为本次类C编译器的开发语言,解释器为python2.7.13。(不同版本语法有一定的差异)与C++相比如下所示:

1.1 优点

  1. python集成了一些基本的字符串操作,具有强大的字符串处理能力。
  2. Python中没有变量类型定义的概念,变量实现机制实质是封装了的指针,通过使用变量来区分变量类型,省去了变量类型定义的麻烦
  3. python中提供了list类型和dictionary类型变量的处理方法,通过使用这两个类,可以实现变量的快速索引和查找。
  4. 提供了turple元组处理方法,可以用list来实现数据表。

1.2 缺点

  1. 与相比C++而言,Python代码更简洁,但是执行速度不如C++。
  2. python没有指针的概念,没有变量引用的概念,在参数传递时需要通过数组来进行地址传递。
  3. Python对开发环境限制较多。
  4. 综合上述对比,以及想学习一门新的编程语言的想法,我选择python作为开发语言。

2、开发环境

  • pycharm2016 professional+Aconoad2(解释器为python2.7.13)
  • UI界面使用PyQt4(引入工具包)
  • 其余使用到的库均为python的标准库,主要如下:
import json     # 处理格式化数据读入的库
import collections      # 定义元组的库
import sys      # 系统操作库
import re       # 正则表达式处理库
import PyQt     # 界面采用库

3. C语言语法规则

该部分将从目标语言的词法规则,语法规则入手,介绍对对文法的预处理过程,为后来代码的编写打好了基础。(PS:这里的目标语言就是课程设计中所要求的简易类C语言)

3.1 词法规则

关键字:int | void | if | else | while | return

标识符: 字母(字母|数字)* (注:不与关键字相同)

数值:数字(数字)*

赋值号: =

算符: + | - | * | / | = | == | > | >= | < | <= | !=

界符:

分隔符:

注释号: /* */ | //

左括号:

右括号:

左大括号: {

右大括号: }

字母:| a |....| z | A |....| Z |

数字:0| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

结束符:#

3.2 语法规则

选择了包含过程调用的文法1来进行本次编译器的开发,文法1的详细内容详见实验要求(PS:为了方便我还是贴过来好了),在此主要通过原始文法与处理后文法的对照,来简要介绍对文法1的处理(详见功能模块中文法处理部分)

【文法1_包含过程调用】 (说明: { }中的项表示可重复若干次)
Program ::= <声明串>
<声明串> ::=<声明>{<声明>}
<声明> ::=int  <ID>  <声明类型> | void  <ID>  <函数声明>   #记下变量类型      
<声明类型>::=<变量声明> | <函数声明>			#填入变量表   声明语句处理模块
<变量声明> ::=  ;
<函数声明> ::=’ (‘<形参>’) ‘<语句块>    
<形参>::= <参数列表> | void               #新建一张变量表,存储形参和局部变量
<参数列表>  ::= <参数> {, <参数>}
<参数> ::= int  <ID>    #填入形参和局部变量类型表     定义函数类(名字,形参,内变)
<语句块> ::= ‘{‘<内部声明>  <语句串>’}’
<内部声明> ::= 空 | <内部变量声明>{; <内部变量声明>}#内变填入刚刚新生成的函数类
<内部变量声明>::=int  <ID>
<语句串> ::= <语句>{  <语句> }
<语句> ::= <if语句> |< while语句> | <return语句> | <赋值语句>
<赋值语句> ::=  <ID> =<表达式>; 
<return语句> ::= return  [ <表达式> ] (注:[ ]中的项表示可选)
<while语句> ::= while ‘( ‘<表达式> ‘)’  <语句块>
<if语句> ::= if ‘(‘<表达式>’)’  <语句块>  [  else  <语句块> ](注:[ ]中的项表示可选)
<表达式>::=<加法表达式>{ relop  <加法表达式> }  (注:relop-> <|<=|>|>=|==|!=)
<加法表达式> ::= <项> {+ <项> | -<项>}
<项> ::= <因子> {* <因子> | /<因子>}
<因子> ::=num | ‘(‘<表达式>’)’ |<ID>  FTYPE
FTYPE ::= <call> | 空
<call> ::=’(’<实参列表> ’) ’
<实参> ::=<实参列表> | 空
<实参列表> ::= <表达式>{, <表达式>} 
<ID>::=字母(字母|d数字)*
【程序实例】
int a;
int b;
int program(int a,int b,int c)
{int i;int j;i=0; 	if(a>(b+c)){j=a+(b*c+1);}else{j=a;}while(i<=100){i=j*2;}return i;
}int demo(int a)
{a=a+2;return a*2;
}void main(void)
{int a;int b;int c;a=3;b=4;c=2;a=program(a,b,demo(c))return;
}

4、8086汇编语言语法规则

8086汇编语言属于CISC指令集,指令集比较庞大,实现的功能较多,但指令长短不一。该部分将从8086汇编的代码结构和语法简介两方面来介绍目标代码的语法规则。

4.1 代码结构

【数据段】
DATA   SEGMENT
//该段需要声明程序中所用到的数据
//严格遵循先定义,后使用,除非采用内存分配方式
DATA   ENDS【代码段】
CODE   SEGMENTASSUME  CS:CODE,DS:DATA	// 固定语句,完成代码段和数据段的加载工作PPOCEDURE PROC   NEAR //调用子函数的代码段           PPOCEDURE  ENDP     START:	MOV  AX,DATA		//主函数段MOV     DS,AXEND   START
CODE	ENDS      //代码段结束标志 

4.2 语法简介

8086语言基本指令解释以及针对本次实验的文法所用到的指令和基本语法解释如下:

(1)内存操作指令

MOV OP1,OP2 PO1<---OP2

寄存器,存储器,累加器<---寄存器,存储器,累加器,立即数

(兼有LOAD和STORE指令的功能)

(2)临时变量存储指令

PUSH 压栈

POP 出栈

(3)加减运算指令

寄存器<---寄存器,存储器

ADD OP1,OP2 OP1<--OP1+OP2

SUB OP1,OP2 OP1<--OP1-OP2

(4)乘除运算指令

MUL OPRD EDX:EAX<--EAX*OPRD

DIV OPRD EDX:EAX/OPRD = 商EAX,余数EDX

(5)条件跳转指令

CMP OP1,OP2 OP1-OP2

JZ 等于0跳转

JNZ 非0跳转

JG 大于跳转

JGE 大于等于0跳转

JL 小于0跳转

JLE 小于等于0跳转

二、总体设计

该部分设计主要描述了编译器的总体架构,首先从编译器的原理和功能模块两部分阐述了整个设计,具体如下所示:

1、实验原理

实验中实现的指定文法的类C编译器,故首先需要了解编译程序的流程,并对整个编译器代码框架作出布局,具体如下所示:

1.1 编译程序

编译程序的流程如下图所示:

5ba5e7fee31f74df8a2d9eeaf30c9563.png
多次提到这个流程,前边也有——by hallucination

1.2 文法处理

整个编译程序执行之前,需要对给定的文法进行处理,转化为便于计算机识别的形式。此外,还需要将转化后的文法变为符合LL(1)的文法,具体处理后的文法如下所示:

  • 文法名对照(肯定要先把推导公式里的汉字转变成英文表示嘛~)

Program:Prog 声明串:Dstr 声明:Decl 声明类型:Type

变量声明:Vari 函数声明:Func 形参:Vpam 参数列表:Pist

语句块:Bloc 内部声明:Kdec 内部变量声明:Kdev

语句串:Lstr 赋值语句:Asla 语句:Lang return语句:Rela

表达式:Expr while语句:Whla if语句:Ifla 加法表达式:Aexp

FTYPE:FTYP 因子:Fact 项:Item Call:Call

实参:Rpam 实参列表:Rist ID:ID

中间变量:Stem/Ptem/Ltem/Rtem/Atem/Itmp/Ftem/Rltm

  • 处理后的文法

注:左边汉字表示的是未处理的文法,右边带标号的字符串表示编译器处理时采用的文法。

1.3 功能划分

按照编译程序的执行流程,将整个编译器划分为如下几个部分来实现:

  • 类的定义:ClassType.py
  • 词法分析:LEX.py
  • 语法分析:SynAly.py
  • 语义分析:SemAly.py
  • 目标代码生成:CodeGen.py
  • 界面生成:compiler.py

其中语法分析模块调用词法分析的结果,并在执行到相应的语义动作时调用语义分析模块,语义分析模块在基本块完成时调用目标代码生成模块生成目标代码。

2.功能模块

在对整个编译器的原理进行分析并完成了文法的处理后,开始详细分析整个编译器的执行流程,并附加上每个模块的数据流,绘制出系统的功能流程图如下所示(实际上也对系统的开发模块做了规划):

6d12399573605d7413dc8950690caf72.png
整个编译器的工作流程图——by hallucination

内容略多。。。。所以,功能设计部分就放在下一回再说啦~感谢大家持续关注✿✿ヽ(°▽°)ノ✿

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/305428.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ansys fluent udf manual 下载_FLUENT流固耦合柱体结构涡激振动仿真案例解析

作者 | 陈东阳博士 仿真秀科普作者一、柱体结构涡激振动定义对于海洋工程、风工程上普遍采用的圆柱形断面结构物&#xff0c;流体绕过柱体时会产生交替发放的泻涡&#xff0c;这种交替发放的泻涡又会在柱体上生成顺流向及横流向周期性变化的脉动压力。如果此时柱体是弹性支撑的…

SQL Server的数据导入MySQL数据库方法简介

第一种是安装mysql ODBC&#xff0c;利用sql server的导出功能&#xff0c;选择mysql数据源&#xff0c;进行数据的直接导出&#xff0c;这种方法很简便&#xff0c;但是针对实际应用有很多弊端&#xff0c;最主要体现就是数据类型问题&#xff0c;首先&#xff0c;sql server数…

添加图标_win10系统轻松添加显示桌面图标的操作方法

win10系统想必大家都非常熟悉吧&#xff0c;然而有时候可能会碰到win10系统对win10系统添加显示桌面图标进行设置&#xff0c;比如近日有用户到本站反映说对win10系统添加显示桌面图标设置的情况&#xff0c;到底该怎么设置win10系统添加显示桌面图标呢&#xff1f;我们只用按照…

分享干货:靠刷算法题,真的可以刷进大厂吗?

在国外 Facebook&#xff0c;Google 等互联网巨头中&#xff0c;算法无疑是面试中的重头戏&#xff0c;不过&#xff0c;在最近几年国内互联网大厂面试中&#xff0c;算法的比重也越来越高&#xff0c;算法不扎实&#xff0c;笔试可能就直接被刷了。那你知道大厂的技术面为什么…

SwitchBox系列 - 介绍

很多客户问到了如何让iAMT能够穿过防火墙或网关被管理&#xff0c;他们中的部分也了解到了Intel工程师开发的SwitchBox方案&#xff0c;但都不是很了解。基于此&#xff0c;我正好有机会来共享一些在SwitchBox方面的经验和理解。虽然Intel AMT技术是基于TCP/IP协议上的&#xf…

获取两个数据的交集_MySQL交集和差集的实现方法

在MySQL中&#xff0c;只支持Union(并集)集合运算&#xff0c;而对于交集Intersect和差集Except并不支持。那么如何才能在MySQL中实现交集和差集呢&#xff1f;一般在MySQL中&#xff0c;我们可以通过in和not in来间接实现交集和差集&#xff0c;当然也有一定局限性&#xff0c…

Asp.Net Core之Identity应用(上篇)

一、前言在前面的篇章介绍中&#xff0c;简单介绍了「IdentityServer4」持久化存储机制相关配置和操作数据&#xff0c;实现了数据迁移&#xff0c;但是未对用户实现持久化操作说明。在总结中我们也提到了&#xff0c;因为「IdentityServer4」本就支持了接入其他认证方式&#…

c++ 读文件_第十六节:读文件,文件的创建,写文件,文件的读写以及鼠标键盘事件和图形绘制...

读文件//读文件文件的创建public 写文件public 文件的读写重点&#xff1a;文件类主要功能&#xff1a;创建&#xff0c;读属性&#xff0c;写属性&#xff0c;删除等文件读写操作File类File类的对象用来获取文件本身的信息&#xff0c;如文件所在目录、文件长度、文件读写权限…

docker安装jenkins并用docker部署net

1. 部署jenkins1.1 创建jenkins的工作目录//创建工作目录 mkdir /var/jenkins_home //赋予权限 chown -R 1000 /var/jenkins_home1.2 通过docker部署1.2.1 拉取镜像docker pull jenkinsci/blueocean1.2.2 生成容器#注意&#xff1a;切换一行执行命令 docker run -u root -d…

ie插件获取dom_读书笔记《DOM编程艺术》DOM

DOM的理解1.1 D&#xff1a;当创建了一个网页并把它加载到Web浏览器中时&#xff0c;DOM就生成了&#xff0c;它将我们编写的网页文档转换成一个文档对象。1.2 O&#xff1a;“对象”是一种自足的数据集合&#xff0c;相关联的变量称为这个对象的属性&#xff0c;只能通过这个对…

针对Fluent-Bit采集容器日志的补充

hello&#xff0c;之前我写过《一套标准的ASP.NET Core容器化应用日志收集分析方案》&#xff0c;在公司团队、微信公众号、Github上反映良好。其中配置Fluent-bit使用Forward协议收集容器日志&#xff0c;需要在Docker-Compose App配置Loging DriverFluentd实践中&#xff0c;…

在每个运行中运行多个查询_在Kubernetes中运行OpenEBS

什么是OpenEBS&#xff1f;现在&#xff0c;OpenEBS是kubernetes下与容器原生和容器附加存储类型相关通用的领先开源项目之一。 通过为每个工作负载指定专用的存储控制器&#xff0c;OpenEBS遵循容器附加存储或CAS的脚步。 为了向用户提供更多功能&#xff0c;OpenEBS具有精细的…

如何在 C# 8 中使用默认接口方法

C# 8 中新增了一个非常有趣的特性&#xff0c;叫做 默认接口方法 (又称虚拟扩展方法)&#xff0c;这篇文章将会讨论 C# 8 中的默认接口方法以及如何使用。在 C# 8 之前&#xff0c;接口不能包含方法定义&#xff0c;只能在接口中定义方法签名&#xff0c;还有一个就是接口的成员…

.Net下二进制形式的文件(图片)的存储与读取 [ZT]

.Net下图片的常见存储与读取凡是有以下几种:存储图片:以二进制的形式存储图片时&#xff0c;要把数据库中的字段设置为Image数据类型(SQL Server),存储的数据是Byte[].1.参数是图片路径:返回Byte[]类型: publicbyte[] GetPictureData(stringimagepath) { /**…

c++tcp接收文件缓存多大合适_网易面经:深剖TCP协议的流量控制和拥塞控制,你懂了吗?...

1.自我介绍项目2.RPC框架和普通http有什么区别和优势&#xff1f; 基于Tcp封装还是http封装的3.rpc是长连接吗&#xff1f;如果要传输一个特别大的文件 底层还是基于流吗&#xff1f; Nio是一个什么IO模型&#xff1f;4.github了的watch star fork5.异常和error的区别&#xff…

如何在 ASP.Net Core 中使用 LoggerMessage

ASP.NET Core 是一个开源的、跨平台的、轻量级模块化框架&#xff0c;可用于构建高性能、可伸缩的web应用程序&#xff0c;你也许不知道 ASP.NET Core 中有一个藏得很深&#xff0c;而且非常强大的特性&#xff0c;那就是 LoggerMessage&#xff0c;与内建的 Logger 相比&#…

模拟器显示空白图片_Kawaks街机模拟器,还是小时候的味道!

APP菜园打造属于我们自己的APP帝国1.打开支付宝app&#xff0c;首页搜索 “8221050” 然后点击快捷功能&#xff0c;天天领红包。2.软件领取流程&#xff1a;1.认真阅读下软件介绍&#xff1b;2.找到图片下方的“获取链接”复制&#xff1b;3.打开手机上的浏览器粘贴链接搜索(…

ASP.NET Core 查看应用状态和统计

在日常开发中&#xff0c;我们需要关注 .NET 应用的资源使用情况&#xff0c;方便排查问题和扩容。通过 Ajax 请求获取统计信息&#xff0c;展示成图表&#xff0c;如下图&#xff1a;CLRStats 插件&#xff0c;一个统计 .NET 应用资源使用情况的插件&#xff0c;包含&#xff…

【Vscode】调试DotNet Core代码

Visual Studio作为宇宙第一的IDE&#xff0c;开发调试.net core app&#xff0c;无一能出其右&#xff0c;我们还需要去了解Visual Studio Code吗&#xff1f;答案是肯定。杀鸡焉用牛刀&#xff1a;就一个hello world的Console App&#xff0c;还需要打开Visual Studio吗&#…

pandownload 卢本伟_PanDownload复活了!60MB/s!附下载地址

最近几天&#xff0c;听说PanDownload 复活了有人接盘了&#xff0c;重新制作上线推出了更加强劲的复活版&#xff01;但是笔者去下载了一下&#xff0c;发现并不能使用于是经过百般搜寻&#xff0c;发现被人提供的已经是旧版了于是&#xff0c;我找到了最新版&#xff0c;9月2…