编译原理课程设计-语义分析程序的设计与实现

合集下载

编译原理课程设计说明书--词法分析,语法分析,语义分析

编译原理课程设计说明书--词法分析,语法分析,语义分析

编译原理课程设计说明书题目:编译器原型设计与开发院(系):计算机科学与工程学院专业:计算机科学与技术目录1 引言 (1)1.1 设计概述 (1)1.2 设计目标 (2)1.3 小组分工 (3)2 开发过程 (3)2.1 词法分析 (3)2.1.1 消除白空格以及注释 (3)2.1.2 词法分析 (6)2.2 .语法分析 (8)2.2.1 递归下降手工编码 (8)2.2.2 first集合的计算 (8)2.2.3 左递归消除 (9)2.2.4 selection表自动生成 (10)2.2.5 LL(1)手工编码 (11)2.3 语义分析 (11)2.3.1 表达式求值LR(1) (11)2.3.2 四元式 (13)3 测试过程 (14)4 总结 (19)5 参考文献 (20)6 代码附录 (20)1引言编译程序是现代计算机系统的基本组成部分之一,而且多数计算机系统都配有不止一个高级语言的编译程序,对有些高级语言甚至配置了几个不同性能的编译程序。

从功能上看,一个编译程序就是一个语言翻译程序。

语言翻译程序把一种语言(称作源语言)书写的程序翻译成另一种语言(称作目标语言)的等价程序。

一个编译程序的重要性体现在它使得多数计算机用户不必考虑与机器有关的繁琐细节,使程序员和程序设计专家独立于机器,这对于当今机器的数量和种类持续不断地增长的年代尤为重要。

编译程序完成从源程序到目标程序的翻译工作,是一个复杂的整体的过程。

将编译过程划分成词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成六个阶段。

1.1设计概述编译原理程序结构框图词法分析词法分析是编译过程的第一个阶段。

这个阶段的任务是从左到右有一个字符一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(也称单词符号或符号)。

这里所谓的单词是指逻辑上紧密相连的一组字符,这些字符基友具体含义。

比如标识符是由字母字符开头,后跟字母、数字字符的字符序列组成的一种单词。

编译原理课程设计之第六章 语义分析

编译原理课程设计之第六章 语义分析

mcy
2
语义分析的任务:
计算各类语法成分的语义信息(属性信息),一般将收集
的语义信息存放到相应的信息表中,在编译程序中符号 表是用来存放源程序中标示符相关属性(语义)信息的一 种信息表。 静态语义检查
类型检查:指类型相容问题的检查,如果操作符作用于不相容的操作数, 则编译器应该报错。 上下文有关问题的检查:当某个对象出现时,要求它必须在前面的某个 适当位置已经出现过。 唯一性检查:有时,要求某个对象只能被定义一次。 控制流检查:引起控制流从某个结构中跳转出来的语句,必须能够决定 控制流转向的目标地址。
(1)所采用的语法分析方法
(2)属性的计算次序。 语法分析方法都要求从左向右处理输入程 序,等价于要求属性能通过从左向右遍历 分析树进行赋值。
mcy
44
定义属性a1,...,ak 的一个属性文法是L-属性(Lattributed)文法,如果满足
mcy
37
num→digit
num.val=digit.val digit.base=num.base digit.val=0 digit.val=1 digit.val=7
digit→0 digit→1 ...... digit→7
mcy
38
digit→8
digit→9
if digit.base=8 then digit.val=error else digit.val= 8 if digit.base=8 then digit.val= error else digit.val 9
mcy
29
文法规则
语义规则 var-list.dtype = type.dtype type.dtype = integer type.dtype = real

编译原理实验报告

编译原理实验报告

《编译原理》实验报告软件131 陈万全132852一、需求分析通过对一个常用高级程序设计语言的简单语言子集编译系统中词法分析、语法分析、语义处理模块的设计、开发,掌握实际编译系统的核心结构、工作流程及其实现技术,获得分析、设计、实现编译程序等方面的实际操作能力,增强设计、编写和调试程序的能力。

通过开源编译器分析、编译过程可视化等扩展实验,促进学生增强复杂系统分析、设计和实现能力,鼓励学生创新意识和能力。

1、词法分析程序设计与实现假定一种高级程序设计语言中的单词主要包括五个关键字begin、end、if、then、else;标识符;无符号常数;六种关系运算符;一个赋值符和四个算术运算符,试构造能识别这些单词的词法分析程序。

输入:由符合和不符合所规定的单词类别结构的各类单词组成的源程序文件。

输出:把所识别出的每一单词均按形如(CLASS,VALUE)的二元式形式输出,并将结果放到某个文件中。

对于标识符和无符号常数,CLASS字段为相应的类别码的助记符;VALUE字段则是该标识符、常数的具体值;对于关键字和运算符,采用一词一类的编码形式,仅需在二元式的CLASS字段上放置相应单词的类别码的助记符,VALUE字段则为“空”。

2、语法分析程序设计与实现选择对各种常见高级程序设计语言都较为通用的语法结构——算术表达式的一个简化子集——作为分析对象,根据如下描述其语法结构的BNF定义G2[<算术表达式>],任选一种学过的语法分析方法,针对运算对象为无符号常数和变量的四则运算,设计并实现一个语法分析程序。

G2[<算术表达式>]:<算术表达式> → <项> | <算术表达式>+<项> | <算术表达式>-<项><项> → <因式> | <项>*<因式> | <项>/<因式><因式> → <运算对象> | (<算术表达式>)若将语法范畴<算术表达式>、<项>、<因式>和<运算对象>分别用E、T、F和i 代表,则G2可写成:G2[E]:E → T | E+T | E-T T → F | T*F | T/F F → i | (E)输入:由实验一输出的单词串,例如:UCON,PL,UCON,MU,ID ······输出:若输入源程序中的符号串是给定文法的句子,则输出“RIGHT”,并且给出每一步分析过程;若不是句子,即输入串有错误,则输出“ERROR”,并且显示分析至此所得的中间结果,如分析栈、符号栈中的信息等,以及必要的出错说明信息。

编译原理课程设计语义

编译原理课程设计语义

编译原理课程设计语义一、教学目标本课程旨在让学生掌握编译原理的基本概念、理论及其在实际编译器设计与实现中的应用。

通过本课程的学习,学生将能够:1.知识目标:–理解编译原理的基本概念,如文法、语法分析、语义分析、中间代码生成、目标代码生成等;–掌握编译器的主要组成部分及其作用;–了解编译器优化技术及其应用。

2.技能目标:–能够使用编译原理相关工具,如词法分析器、语法分析器、编译器生成器等;–能够独立完成简单编译器的设计与实现;–能够对编译器进行性能分析和优化。

3.情感态度价值观目标:–培养学生的抽象思维能力和问题解决能力;–培养学生对计算机科学领域的探索精神和创新意识;–培养学生对编译原理的兴趣,提高其对计算机科学的热情。

二、教学内容本课程的教学内容主要包括以下几个部分:1.编译原理基本概念:介绍编译器的基本概念、编译过程及编译器的主要组成部分;2.词法分析:讲解词法分析的基本方法、词法分析器的实现及其优化;3.语法分析:介绍语法分析的基本方法、语法分析器的实现及其优化;4.语义分析:讲解语义分析的基本方法、语义分析器的实现及其优化;5.中间代码生成:介绍中间代码生成的基本方法及其优化;6.目标代码生成:讲解目标代码生成的基本方法及其优化;7.编译器优化:介绍编译器优化技术及其应用。

三、教学方法为了提高教学效果,本课程将采用多种教学方法,如:1.讲授法:通过讲解编译原理的基本概念、理论及其应用,使学生掌握相关知识;2.讨论法:学生进行小组讨论,培养学生的思考能力和问题解决能力;3.案例分析法:分析实际编译器的设计与实现案例,使学生更好地理解编译原理;4.实验法:让学生动手实现简单编译器,提高学生的实践能力。

四、教学资源为了支持本课程的教学,我们将准备以下教学资源:1.教材:《编译原理》(推荐使用国内外经典教材);2.参考书:提供相关领域的参考书籍,以便学生深入学习;3.多媒体资料:制作PPT、教学视频等,丰富教学手段;4.实验设备:提供计算机及相关软件,供学生进行实验和实践。

编译原理-课程简介

编译原理-课程简介
程序分析
编译原理中的程序分析技术可以 用于逆向工程中的程序分析,帮
助理解程序的结构和功能。
代码重构
在逆向工程中,编译原理可以帮助 对代码进行重构,提高代码的可读 性和可维护性。
病毒分析和防治
编译原理可以帮助分析和防治计算 机病毒,保护计算机系统的安全。
计算机体系结构相关应用
指令集设计
编译原理可以指导计算机指令集 的设计,提高处理器的性能。
• 向量化技术的实现方法:向量化技术的实现方法包括自动向量化和手动向量化 两种。自动向量化是指编译器自动将程序中的循环结构转换为向量运算;而手 动向量化则需要程序员手动编写向量运算的代码。在实现向量化技术时,需要 注意处理器的向量长度、数据对齐等问题。
04
CATALOGUE
运行时环境支持
存储管理策略及实现
定义不同类型的异常,如语法错误、 运行时错误等,以便程序能够识别并 处理异常情况。
控制异常在程序中的传播范围,避免异常对 程序其他部分的影响,同时提供异常恢复机 制,使程序能够从异常情况中恢复执行。
异常捕获与处理
在程序中设置异常捕获机制,当异常发 生时能够捕获异常并执行相应的处理代 码,保证程序的稳定性和可靠性。
自顶向下语法分析
从文法的开始符号出发,根据产生式 规则推导出输入符号串的过程。
自底向上语法分析
从输入符号串出发,逐步归约到文法 的开始符号的过程。
LL(1)语法分析方法
一种预测分析方法,根据当前输入符 号和上下文信息预测下一个要产生的 非终结符。
LR(1)语法分析方法
一种规范归约分析方法,根据当前输 入符号和栈顶信息确定句柄并进行归 约。
01
02
03
静态存储分配

编译原理课程设计基于LL(1)法的条件语句语法语义分析程序

编译原理课程设计基于LL(1)法的条件语句语法语义分析程序

计算机科学与技术学院课程设计报告(2008~2009学年度第一学期)课程名称编译原理实验名称基于LL(1)法的条件语句语法语义分析程序姓名学号专业班级地点教师目录一.系统需求分析------------------------------------------------------------------------------------ 二.概念模型设计------------------------------------------------------------------------------------ 三.逻辑模型设计------------------------------------------------------------------------------------四.物理模型设计------------------------------------------------------------------------------------ 五.实验结果分析------------------------------------------------------------------------------------六.心得体会--------------------------------------------------------------------------------------------七.源代码------------------------------------------------------------------------------------------------一.系统需求分析通过设计,编制,调试一个语法及语义分析程序,加深对语法及语义分析原理的理解。

IF 〈布尔表达式〉THEN 〈赋值语句〉ELSE 〈赋值语句〉其中(1)、可以选择递归下降法、LL(1)、算符优先分析法、LR法完成以上任务,中间代码选用四元式。

编译原理实验报告语义分析

编译原理实验报告语义分析

编译原理实验报告语义分析实验名称:语义分析实验目的:1.掌握词法分析器生成的词法单元序列的构造;2.学会设计语法分析器,实现对程序的基本语法结构检查,并生成抽象语法树;3.学习语义规约的实现,实现对程序的语义分析和错误检查;4.熟悉语义分析向语法分析的接口。

实验原理:语义分析是编译过程的一个重要环节,它的主要任务是对生成的抽象语法树进行遍历,并验证程序的类型一致性、语义规则的正确性、错误的检查和恢复等。

语义分析的输入是由语法分析生成的抽象语法树,输出是继续优化的抽象语法树或中间代码,以供后续的中间代码生成等工作使用。

实验步骤:1.设计语法分析器,包括语法规则、优先级关系等;2.生成词法单元序列;3.构建语法分析器,进行语法分析,并生成抽象语法树;4.针对不同的语义规约,设计语义动作,实现对程序的语义分析和错误检查;5.完成语义分析器的构建和测试。

实验设备:1.计算机;2. 编程语言:C++/Java/Python等;3. 开发环境:Visual Studio/ Eclipse/PyCharm等。

实验结果:通过对语法分析生成的抽象语法树进行遍历,实现了对程序的语义分析和错误检查。

具体实现包括:1.类型检查:根据语义规约,对程序中的类型进行检查,包括变量的声明及使用、函数的调用、赋值语句的一致性等;2.作用域检查:检查变量的作用域和可见性等;3.错误检查:检测语义错误,如变量未声明、函数重复定义等;4.错误恢复:当检测到错误时,采取适当的错误恢复措施,如跳过错误的部分继续分析、提示错误信息等。

实验心得:本次实验主要学习了语义分析的原理和实现方法,深入了解了编译过程中各个环节的作用和关系。

通过实践操作,加深了对语法分析和语义分析的理解,提高了编程能力和解决问题的能力。

同时,实验过程中也遇到了一些挑战和困难,例如语义规约的设计和实现、错误检查和恢复等,但通过查阅资料和与同学讨论,最终解决了这些问题。

通过本次实验,我对编译原理和语义分析有了更深入的了解,并且对以后的学习和工作有了更好的准备。

编译原理实验报告-语义分析

编译原理实验报告-语义分析

编译原理课程实验报告实验3:语义分析图2-1本程序根据之前两个实验的结果进一步进行语义分析,主要是通过在第二个实验句法分析过程中添加语义分析功能完成的。

在代码编写之前,我将程序的功能模块分为界面及主控程序,实体类和工具类三大部分。

MyCompiler是整个程序运行的入口,是主控程序;ComplierFrame完成程序的界面,以及界面里事件的响应;Token是词法分析中词法单元的实体类;ErrorToken是错误的词法单元实体类;Symbol是句法分析中符号的实体类;Production是产生式的实体类;ErrorProduction是句法分析中产生错误的时候使用的产生式实体类;Id是标示符实体类,保存了语义分析后的标识符表;Node是语法分析树的节点类,帮助完成语法分析树的构造;LL类使用LL(1)分析法完成句法分析,同时完成语义分析;MyScanner完成了词法分析。

图2-2三、详细设计及实现得分要求:对如下工作进行展开描述(1)核心数据结构的设计本程序使用了两个新的实体类,分别是Id和Node。

Id是标识符,里面也包含了该标识符在本程序中存储的地址和长度等信息。

Id的属性如下:private String name; //名private String type;//基本类型private int offset;//起始地址private int length;//长度开始输入词法分析读入Token尝试匹配是否错误存储错误记录,处理栈顶与Token 序列是否为语义符号存储产生式,处理栈顶与Token 序列判断动作符号执行语义动作是否读到Token末尾打印结果结束分析结果以及错误报告:图4-1 标识符表:图4-2。

编译原理课程设计--算术表达式的语法分析及语义分析程序设计 精品

编译原理课程设计--算术表达式的语法分析及语义分析程序设计 精品

课程设计任务书学生姓名:专业班级:指导教师:工作单位:题目: 算术表达式的语法分析及语义分析程序设计1.目的通过设计、编制、调试一个算术表达式的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。

2.设计内容及要求算术表达式的文法:(1)选择算符优先分析法完成以上任务,中间代码选用逆波兰式。

(2)写出算术表达式的符合分析方法要求的文法,给出分析方法的思想,完成分析程序设计。

(3)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

3.课程设计报告书的内容应包括:(1)设计题目、班级、学号、姓名、完成日期;(2)给出算术表达式的语法分析和语义分析的设计。

(3)简要的分析与概要设计;(4)详细的算法描述;(5)源程序清单;(6)给出软件的测试方法和测试结果;(7)设计的评价、收获与体会。

时间安排:第18周,周1-周3下午,周5全天指导教师签名:年月日系主任(或责任教师)签名:年月日1 课设要求设计题目算术表达式转换成逆波兰式(用算符优先分析法)1.1课程设计的目的课程设计是对学生的一种全面综合训练,是与课堂听讲、自学和练习相辅相成的必不可少的一个教学环节。

通常,设计题中的问题比平时的练习题要复杂,也更接近实际。

编译原理这门课程安排的课程设计的目的是旨在要求学生进一步巩固课堂上所学的理论知识,深化理解和灵活掌握教学内容,选择合适的数据逻辑结构表示问题,然后编制算法和程序完成设计要求,从而进一步培养学生独立思考问题、分析问题、解决实际问题的动手能力。

要求学生在上机前应认真做好各种准备工作,熟悉机器的操作系统和语言的集成环境,独立完成算法编制和程序代码的编写。

1.2 设计内容及要求算术表达式的文法:〈无符号整数〉∷=〈数字〉{〈数字〉}〈标志符〉∷=〈字母〉{〈字母〉|〈数字〉}〈表达式〉∷= [+|-]〈项〉{〈加法运算符〉〈项〉}〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}〈因子〉∷=〈标志符〉|〈无符号整数〉|‘(’〈表达式〉‘)’〈加法运算符〉∷=+|-〈乘法运算符〉∷=*|/1.选择算符优先分析法完成以上任务,中间代码选用逆波兰式。

《编译原理》实验教学大纲

《编译原理》实验教学大纲

《编译原理》实验教学大纲一、实验目的和任务编译原理是计算机科学与技术专业的一门重要课程,它主要研究的是将高级语言程序翻译成机器语言程序的方法和技术。

通过本实验课程的学习,旨在使学生掌握编译原理的基本原理和方法,培养学生对编译器结构与构造技术的专门知识和技能,为学生今后进行编译器设计与实现打下基础。

二、实验设备和工具1.计算机和相关硬件设备2. 编程语言的开发环境,如C/C++或Java三、实验内容1.实验一:词法分析器设计与实现a)实验目的:学习词法分析器的原理和设计方法,掌握正则表达式、DFA和NFA的转换方法。

b)实验任务:i.设计并实现一个词法分析器的原型,能够正确地识别出给定的程序中的词法单元。

ii. 使用给定的正则表达式设计并实现识别给定程序中的关键字、标识符、常量等的词法分析器。

2.实验二:语法分析器设计与实现a)实验目的:学习语法分析器的原理和设计方法,掌握上下文无关文法和LR分析表的构造方法。

b)实验任务:i.学习并理解上下文无关文法和LR分析表的构造方法。

ii. 设计并实现一个简单的递归下降语法分析器。

3.实验三:语义分析器设计与实现a)实验目的:学习语义分析器的原理和设计方法,掌握语义动作的定义和处理方法。

b)实验任务:i.学习并理解语义分析器的原理和设计方法。

ii. 设计并实现一个简单的语义分析器,能够对给定的程序进行语义分析和语义动作的处理。

4.实验四:中间代码生成器设计与实现a)实验目的:学习中间代码生成器的原理和设计方法,掌握中间代码的生成和优化方法。

b)实验任务:i.学习并理解中间代码生成器的原理和设计方法。

ii. 设计并实现一个简单的中间代码生成器,能够将给定的程序翻译成中间代码。

5.实验五:目标代码生成器设计与实现a)实验目的:学习目标代码生成器的原理和设计方法,掌握目标代码的生成和优化方法。

b)实验任务:i.学习并理解目标代码生成器的原理和设计方法。

ii. 设计并实现一个简单的目标代码生成器,能够将中间代码翻译成目标代码。

编译原理课程设计_算术表达式的语法分析及语义分析程序设计

编译原理课程设计_算术表达式的语法分析及语义分析程序设计

设计题一:算术表达式的语法分析及语义分析程序设计。

1.目的通过设计、编制、调试一个算术表达式的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。

2.设计内容及要求:算术表达式的文法:〈无符号整数〉∷=〈数字〉{〈数字〉}〈标志符〉∷=〈字母〉{〈字母〉|〈数字〉}〈表达式〉∷= [+|-]〈项〉{〈加法运算符〉〈项〉}〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}〈因子〉∷=〈标志符〉|〈无符号整数〉|‘(’〈表达式〉‘)’〈加法运算符〉∷=+|-〈乘法运算符〉∷=*|/选择算符优先分析方法完成以上任务,生成逆波兰式的中间代码;(1)写出算术表达式的符合分析方法要求的文法,给出分析方法的思想,完成分析程序设计。

(2)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

源代码#define _CRT_SECURE_NO_WARNINGS#include"stdio.h"#include"stdlib.h"#include<iostream>using namespace std;char data[20][20]; //算符优先关系char s[100]; //模拟符号栈schar lable[20]; //文法终极符集char input[100]; //文法输入符号串char str[20][10]; //用于输入串的分析int k,j;char a,q;int r; //文法规则个数int r1;int m, n, N; //转化后文法规则个数char st[10][30]; //用来存储文法规则char first[10][10]; //文法非终结符FIRSTVT集char last[10][10]; //文法非终结符LASTVT集int fflag[10] = { 0 }; //标志第i个非终结符的FIRSTVT集是否已求出int lflag[10] = { 0 }; //标志第i个非终结符的LASTVT集是否已求出int deal(); //对输入串的分析int terminal_symbol(char c); //判断字符c是否是终极符int location(char c); //求字符c在算符优先关系表中的下标void out(int j, int k, char *s); //打印s栈void firstvt(char c); //求非终结符c的FIRSTVT集void lastvt(char c); //求非终结符c的LASTVT集void table(); //创建文法优先关系表char output[10];//存储逆波兰式void main(){int i, j, k = 0;printf("请输入文法规则数:");scanf("%d", &r);printf("请输入文法规则:\n");for (i = 0; i<r; i++){scanf("%s", st[i]); //存储文法规则,初始化FIRSTVT集和LASTVT集*/first[i][0] = 0; /*first[i][0]和last[i][0]分别表示st[i][0]非终极符的FIRSTVT集和LASTVT集中元素的个数*/last[i][0] = 0;}for (i = 0; i<r; i++) //判断文法是否合法{for (j = 0; st[i][j] != '\0'; j++){if (st[i][0]<'A' || st[i][0]>'Z'){printf("文法error!\n");exit(-1);}if (st[i][j] >= 'A'&&st[i][j] <= 'Z'){if (st[i][j + 1] >= 'A'&&st[i][j + 1] <= 'Z'){printf("文法error!\n");exit(-1);}}}}for (i = 0; i<r; i++)//for (j = 0; st[i][j] != '\0'; j++)if ((st[i][j]<'A' || st[i][j]>'Z') && st[i][j] != '-'&&st[i][j] !='>'&&st[i][j] != '|')lable[k++] = st[i][j];lable[k] = '#';lable[k + 1] = '\0';table();//printf("FIRST集为:\n"); //输出每个非终结符的FIRST集for (i = 0; i<r; i++){printf("%c: ", st[i][0]);for (j = 0; j<first[i][0]; j++)printf("%c ", first[i][j + 1]);printf("\n");}printf("LAST集为:\n"); //输出每个非终结符的LAST集for (i = 0; i<r; i++){printf("%c: ", st[i][0]);for (j = 0; j<last[i][0]; j++){printf("%c ", last[i][j + 1]);}printf("\n");}printf("算符优先分析表如下:\n");for (i = 0; lable[i] != '\0'; i++)printf("\t%c", lable[i]);printf("\n");for (i = 0; i<k + 1; i++){printf("%c\t", lable[i]);for (j = 0; j<k + 1; j++){printf("%c\t", data[i][j]);}printf("\n");}printf("请输入文法输入符号串以#结束:");scanf("%s", input);deal();cout << "逆波兰式为:";for (i = 0; lable[i] != '\0'; i++)cout << output[i] << '\0';//cout << endl;}void table(){char text[20][10];//存储改写后的文法int i, j, k, t, l, x = 0, y = 0;int m, n;x = 0;for (i = 0; i<r; i++){firstvt(st[i][0]);lastvt(st[i][0]);}for (i = 0; i<r; i++)//改写文法{text[x][y] = st[i][0];y++;for (j = 1; st[i][j] != '\0'; j++){if (st[i][j] == '|')//{text[x][y] = '\0';x++;y = 0;text[x][y] = st[i][0];y++;text[x][y++] = '-';text[x][y++] = '>';}else{text[x][y] = st[i][j];y++;}}text[x][y] = '\0';x++;y = 0;}r1 = x;//printf("转化后的文法为:\n");for (i = 0; i<x; i++) //输出转化后的文法规则串{printf("%s\n", text[i]);}for (i = 0; i<x; i++) /*求每个终结符的推导结果(去掉"->"后的转化文法,用于最后的规约)*/{str[i][0] = text[i][0];for (j = 3, l = 1; text[i][j] != '\0'; j++, l++)str[i][l] = text[i][j];str[i][l] = '\0';}for (i = 0; i<x; i++){for (j = 1; text[i][j + 1] != '\0'; j++){if (terminal_symbol(text[i][j]) && terminal_symbol(text[i][j + 1])){m = location(text[i][j]);n = location(text[i][j + 1]);data[m][n] = '=';}if (text[i][j + 2] != '\0'&&terminal_symbol(text[i][j]) &&terminal_symbol(text[i][j + 2]) && !terminal_symbol(text[i][j + 1])){m = location(text[i][j]);n = location(text[i][j + 2]);data[m][n] = '=';}if (terminal_symbol(text[i][j]) && !terminal_symbol(text[i][j + 1]))//终结符和非终结符相接,用后于关系填表{for (k = 0; k<r; k++){if (st[k][0] == text[i][j + 1])break;}m = location(text[i][j]);for (t = 0; t<first[k][0]; t++){n = location(first[k][t + 1]);data[m][n] = '<';}}if (!terminal_symbol(text[i][j]) && terminal_symbol(text[i][j + 1]))//非终结符和终结符相接,用先于关系填表{for (k = 0; k<r; k++){if (st[k][0] == text[i][j])break;}n = location(text[i][j + 1]);for (t = 0; t<last[k][0]; t++){m = location(last[k][t + 1]);data[m][n] = '>';}}}}m = location('#');//#后于所有的终结符规约for (t = 0; t<first[0][0]; t++){n = location(first[0][t + 1]);data[m][n] = '<';}n = location('#');//for (t = 0; t<last[0][0]; t++){m = location(last[0][t + 1]);data[m][n] = '>';}data[n][n] = '=';}void firstvt(char c) //求FIRSTVT集{int i, j, k, m, n;for (i = 0; i<r; i++)//找出是第i个非终结符{if (st[i][0] == c)break;}if (fflag[i] == 0){n = first[i][0] + 1;m = 0;do{if (m == 2 || st[i][m] == '|'){if (terminal_symbol(st[i][m + 1])){first[i][n] = st[i][m + 1];n++;}else{if (terminal_symbol(st[i][m + 2])){first[i][n] = st[i][m + 2];n++;}if (st[i][m + 1] != c){firstvt(st[i][m + 1]);for (j = 0; j<r; j++){if (st[j][0] == st[i][m + 1])break;}for (k = 0; k<first[j][0]; k++){int t;for (t = 0; t<n; t++){if (first[i][t] == first[j][k + 1])break;}if (t == n){first[i][n] = first[j][k + 1];n++;}}}}}m++;} while (st[i][m] != '\0');first[i][n] = '\0';first[i][0] = --n;fflag[i] = 1;}}void lastvt(char c) //求LASTVT集{int i, j, k, m, n;for (i = 0; i<r; i++){if (st[i][0] == c)break;}if (lflag[i] == 0){n = last[i][0] + 1;m = 0;do{if (st[i][m + 1] == '\0' || st[i][m + 1] == '|'){if (terminal_symbol(st[i][m])){last[i][n] = st[i][m];n++;}else{if (terminal_symbol(st[i][m - 1])){last[i][n] = st[i][m - 1];n++;}if (st[i][m] != c){lastvt(st[i][m]);for (j = 0; j<r; j++){if (st[j][0] == st[i][m])break;}for (k = 0; k<last[j][0]; k++){int t;for (t = 0; t<n; t++){if (last[i][t] == last[j][k + 1])break;}if (t == n){last[i][n] = last[j][k + 1];n++;}}}}}m++;} while (st[i][m] != '\0');last[i][n] = '\0';last[i][0] = --n;lflag[i] = 1;}}int deal(){int i, j;int size = 0;//int x, y;int z; //输入串的长度k = 1;s[k] = '#'; //栈置初值for (i = 0; input[i] != '\0'; i++); //计算输入串的长度z = i--;//i = 0;while ((a = input[i]) != '\0')//a表示要输入的字符{if (terminal_symbol(s[k]))j = k;elsej = k - 1;x = location(s[j]);y = location(a);if (data[x][y] == '>'){if (lable[x] != ')')output[size++] = lable[x]; //将要规约的终结符存起来out(1, k, s);printf("%c", a);out(i + 1, z, input);printf("规约\n");do{q = s[j];if (terminal_symbol(s[j - 1]))j = j - 1;else j = j - 2;x = location(s[j]);y = location(q);} while (data[x][y] != '<');int m, n, N;for (m = j + 1; m <= k; m++){for (N = 0; N<r1; N++)for (n = 1; str[N][n] != '\0'; n++){if (!terminal_symbol(s[m]) && !terminal_symbol(str[N][n])){if(terminal_symbol(s[m + 1]) && terminal_symbol(str[N][n + 1]) && s[m + 1] == str[N][n + 1]){s[j + 1] = str[N][0];break;}}elseif (terminal_symbol(s[m]))if (s[m] == str[N][n]){s[j + 1] = str[N][0];break;}}}k = j + 1;if (k == 2 && a == '#'){out(1, k, s);printf("%c", a);out(i + 1, z, input);printf("结束\n");printf("规约成功!\n");return 1; //输入串符合文法的定义}}elseif (data[x][y] == '<' || data[x][y] == '='){ //移进out(1, k, s);printf("%c", a);out(i + 1, z, input);printf("移进\n");k++;s[k] = a;i++;}else{printf("\n规约失败\n");return 0;}}printf("\n规约失败\n");//return 0;}void out(int j, int k, char *s){int n = 0;int i;for (i = j; i <= k; i++){printf("%c", s[i]);n++;}for (; n<15; n++){printf(" ");}}int location(char c) //求字符c在算符优先关系表中的下标{int i;for (i = 0; lable[i] != '\0'; i++){if (c == lable[i])return i;}return -1;}int terminal_symbol(char c) //判断字符c是否是终极符{int i;for (i = 0; lable[i] != '\0'; i++){if (c == lable[i])return 1;}return 0;}。

编译原理语义分析实验报告

编译原理语义分析实验报告

编译原理语义分析实验报告编译原理语义分析实验报告引言编译原理是计算机科学的重要基础课程之一,它主要研究如何将高级语言转换为低级语言,使计算机能够理解和执行人类可读的代码。

语义分析是编译过程中的重要环节,它负责对代码进行语义检查和语义解释,以确保代码的正确性和可执行性。

本实验报告旨在介绍编译原理中语义分析的基本原理和实验过程。

一、实验目的本次实验的主要目的是通过实现一个简单的语义分析器,加深对编译原理中语义分析的理解。

具体来说,我们将实现以下功能:1. 识别并解析变量声明和赋值语句;2. 检查变量的重复声明和赋值类型的一致性;3. 计算并输出表达式的值。

二、实验环境和工具为了完成本次实验,我们需要准备以下环境和工具:1. 操作系统:Windows、Linux或MacOS;2. 编程语言:C++、Java或Python;3. 开发工具:编译器和调试器。

三、实验原理语义分析是编译过程中的重要环节,它主要负责对代码进行语义检查和语义解释。

在编译器中,语义分析器通常通过构建抽象语法树(AST)来实现。

AST是一种树状的数据结构,用于表示代码的语法结构和语义信息。

在语义分析的过程中,我们需要进行变量声明和赋值语句的解析和检查。

首先,我们需要识别代码中的变量声明和赋值语句,并将其转换成AST。

在解析过程中,我们需要检查变量的重复声明和赋值类型的一致性。

如果发现错误,我们需要报告相应的错误信息,并终止编译过程。

接下来,我们需要对表达式进行求值。

表达式是编程语言中的核心概念,它由操作数和运算符组成。

在求值过程中,我们需要考虑运算符的优先级和结合性。

为了实现这一功能,我们可以使用递归下降法或者使用运算符优先级算法。

四、实验过程1. 识别变量声明和赋值语句我们首先需要编写词法分析器,将代码中的字符序列转换成标记序列。

在词法分析的过程中,我们需要识别变量声明和赋值语句的关键字和标识符,并将其转换成相应的标记。

2. 构建抽象语法树在词法分析的基础上,我们可以构建抽象语法树。

编译原理课程设计教案

编译原理课程设计教案

编译原理课程设计教案一、课程简介1.1 课程背景编译原理是计算机科学与技术领域的基础课程,旨在培养学生对编译器设计和实现的理解。

通过本课程的学习,学生将掌握编译器的基本原理、构造方法和实现技巧。

1.2 课程目标(1)理解编译器的基本概念、工作原理和分类;(2)熟悉源程序的词法分析、语法分析、语义分析、中间代码、目标代码和优化等基本过程;(3)掌握常用的编译器构造方法和技术;(4)能够设计和实现简单的编译器。

二、教学内容2.1 词法分析(1)词法规则的定义和描述;(2)词法分析器的实现方法;(3)词法分析在编译器中的作用和重要性。

2.2 语法分析(1)语法规则的定义和描述;(2)语法分析树的构建方法;(3)常用的语法分析算法及其特点。

2.3 语义分析(1)语义规则的定义和描述;(2)语义分析的方法和技巧;(3)语义分析在编译器中的作用和重要性。

2.4 中间代码(1)中间代码的定义和表示;(2)中间代码的方法和策略;(3)中间代码在编译器中的作用和重要性。

2.5 目标代码和优化(1)目标代码的方法和技巧;(2)代码优化的方法和策略;(3)目标代码和优化在编译器中的作用和重要性。

三、教学方法3.1 讲授法通过讲解编译原理的基本概念、理论和方法,使学生掌握编译器的设计和实现技巧。

3.2 案例分析法分析实际编译器的设计和实现案例,使学生更好地理解编译原理的应用。

3.3 实验法安排实验课程,让学生动手设计和实现简单的编译器组件,提高学生的实际操作能力。

3.4 小组讨论法组织学生进行小组讨论,培养学生的团队合作精神和沟通能力。

四、教学评价4.1 平时成绩包括课堂表现、作业完成情况和小测验成绩,占总评的30%。

4.2 实验成绩包括实验报告和实验演示,占总评的30%。

4.3 期末考试包括理论知识考核和实际操作考核,占总评的40%。

五、教学资源5.1 教材推荐使用《编译原理》教材,为学生提供系统、全面的学习资料。

5.2 课件制作精美、清晰的课件,辅助课堂教学。

编译原理课程设计(词法分析,语法分析,语义分析,代码生成)

编译原理课程设计(词法分析,语法分析,语义分析,代码生成)

编译原理课程设计(词法分析,语法分析,语义分析,代码生成)#include<cstdio>#include<iostream>#include<cstdlib>#include<fstream>#include<string>#include<cmath>using namespace std;/************************************************/struct token// token {int code;//int num;//token *next;};token *token_head,*token_tail;//tokenstruct str// string {int num;//string word;//str *next;};str *string_head,*string_tail;//stringstruct ivan// {char left;//string right;//int len;// };ivan css[20];// 20 struct pank// action {char sr;//int state;// };pank action[46][18];//action int go_to[46][11];// go_to struct ike// {ike *pre;int num;//int word;//ike *next;};ike *stack_head,*stack_tail;// struct L//{int k;string op;//string op1;//string op2;//string result;//L *next;//L *Ltrue;//trueL *Lfalse;//false};L *L_four_head,*L_four_tail,*L_true_head,*L_false_head;//truefalse struct symb//{string word;//int addr;//symb *next;};symb *symb_head,*symb_tail;///************************************************/void scan();//void cifa_main();//int judge(char ch);// void out1(char ch);//token.txtvoid out3(char ch,string word);//string.txt void input1(token*temp);//token void input3(str *temp);//string void output();// void outfile();///************************************************/void yufa_main();//void yufa_initialize();// int yufa_SLR1(int a);// int ID1(inta);//action string ID10(int i);//int ID2(char ch);//go_toint ID20(char ch);//char ID21(int j);//void add(ike *temp);//ike void del();//ike/************************************************/void yuyi_main(int m);//void add_L_four(L *temp);// void add_L_true(L *temp);//true void add_L_false(L *temp);//false void add_symb(symb *temp);// void output_yuyi();// string newop(int m);//string id_numtoname(int num);// int lookup(string m);///************************************************/FILE *fp;//int wordcount;//int err;//int nl;//int yuyi_linshi;//stringE_name,T_name,F_name,M_name,id_name,id1_name,id2_name,errword;// int id_num,id1_num,id2_num,id_left,id_while,id_then,id_do;// /******************************************************/int main(){cout<<"************************"<<endl;cout<<"* *"<<endl;cout<<"* *"<<endl;cout<<"* *"<<endl;cout<<"* *"<<endl;cout<<"************************"<<endl;cifa_main();//yufa_main();//output_yuyi();//cout<<endl;system("pause");return(0);}/******************************************************/ void cifa_main(){token_head=new token;token_head->next=NULL;token_tail=new token;token_tail->next=NULL;string_head=new str;string_head->next=NULL;string_tail=new str;string_tail->next=NULL;//L_four_head=new L;L_four_head->next=NULL;L_four_tail=new L;L_four_tail->k=0;L_four_tail->next=NULL;L_true_head=new L;L_true_head->Ltrue=NULL;L_false_head=new L;L_false_head->Lfalse=NULL;symb_head=new symb;symb_head->next=NULL;symb_tail=new symb;symb_tail->next=NULL;yuyi_linshi=-1;id_num=0;wordcount=0;//err=0;//nl=1;//scan();if(err==0){char m;output();cout<<"!"<<endl<<endl<<" y";cin>>m;cout<<endl;if(m=='y'){outfile();cout<<"token.txtsting.txt"<<endl;cout<<endl;}}}void scan(){cout<<endl;system("pause");cout<<endl;char ch;string word;char document[50];int flag=0;cout<<":";cin>>document;cout<<endl;cout<<"************************"<<endl; cout<<"* *"<<endl;cout<<"************************"<<endl; if((fp=fopen(document,"rt"))==NULL) {err=1;cout<<"!"<<endl;return;}while(!feof(fp)){word="";ch=fgetc(fp);flag=judge(ch);if(flag==1)out1(ch);else if(flag==3)out3(ch,word);else if(flag==4 || flag==5 ||flag==6) continue;else{cout<<nl<<" "<<":! "<<ch<<endl;err=1;}}fclose(fp);}int judge(char ch){int flag=0;if(ch=='=' || ch=='+' || ch=='*' || ch=='>' || ch==':' || ch==';' || ch=='{' || ch=='}' || ch=='(' || ch==')')flag=1;//else if(('a'<=ch && ch<='z') || ('A'<=ch && ch<='Z'))flag=3;//else if(ch==' ')flag=4;//else if(feof(fp))flag=5;//else if(ch=='\n'){flag=6;//nl++;}elseflag=0;//return(flag);}void out1(char ch){int id;switch(ch){case '=' : id=1;break;case '+' : id=2;break;case '*' : id=3;break;case '>' : id=4;break;case ':' : id=5;break;case ';' : id=6;break;case '{' : id=7;break;case '}' : id=8;break;case '(' : id=9;break;case ')' : id=10;break;// default : id=0;}token *temp;temp=new token;temp->code=id;temp->num=-1;temp->next=NULL;input1(temp);return;}void out3(char ch,string word) {token *temp;temp=new token;temp->code=-1;temp->num=-1;temp->next=NULL;str *temp1;temp1=new str;temp1->num=-1;temp1->word="";temp1->next=NULL;int flag=0;word=word+ch;ch=fgetc(fp);flag=judge(ch);if(flag==1 || flag==4 || flag==5 || flag==6){if(word=="and" || word=="if" || word=="then" || word=="while" || word=="do" || word=="int"){if(word=="and")temp->code=31;else if(word=="if")temp->code=32;else if(word=="then")temp->code=33;else if(word=="while")temp->code=35;else if(word=="do")temp->code=36;else if(word=="int")temp->code=37;//input1(temp);if(flag==1)out1(ch);else if(flag==4 || flag==5 || flag==6) return;}else if(flag==1){wordcount++;temp->code=25;temp->num=wordcount;input1(temp);temp1->num=wordcount;temp1->word=word;input3(temp1);out1(ch);}else if(flag==4 || flag==5 || flag==6) {wordcount++;temp->code=25;temp->num=wordcount;input1(temp);temp1->num=wordcount;temp1->word=word;input3(temp1);}return;}else if(flag==2 || flag==3)out3(ch,word);//else{err=1;cout<<nl<<" "<<":! "<<ch<<endl; return;}}void input1(token *temp) {if(token_head->next == NULL) {token_head->next=temp;token_tail->next=temp;}else{token_tail->next->next=temp; token_tail->next=temp;}}void input3(str *temp) {if(string_head->next == NULL) {string_head->next=temp;string_tail->next=temp;}else{string_tail->next->next=temp; string_tail->next=temp;}}void output(){cout<<"token"<<endl;token *temp1;temp1=new token;temp1=token_head->next;while(temp1!=NULL){cout<<temp1->code;if(temp1->num == -1){cout<<endl;}else{cout<<" "<<temp1->num<<endl;}temp1=temp1->next;}cout<<""<<endl;str *temp3;temp3=new str;temp3=string_head->next;while(temp3!=NULL){cout<<temp3->num<<" "<<temp3->word<<endl; temp3=temp3->next;}}void outfile(){ofstream fout1("token.txt");//ofstream fout3("string.txt");token *temp1;temp1=new token;temp1=token_head->next;while(temp1!=NULL){fout1<<temp1->code;if(temp1->num == -1)fout1<<endl;elsefout1<<" "<<temp1->num<<endl;temp1=temp1->next;}str *temp3;temp3=new str;temp3=string_head->next;while(temp3!=NULL){fout3<<temp3->num<<" "<<temp3->word<<endl; temp3=temp3->next;}}/******************************************************/ void yufa_main(){if(err==0){system("pause");cout<<endl;cout<<"************************"<<endl;cout<<"* *"<<endl;cout<<"************************"<<endl;yufa_initialize();//token *temp;temp=new token;temp=token_head->next;int p,q;p=0;q=0;cout<<""<<endl;while(temp!=NULL){int w;w=ID1(temp->code);p=yufa_SLR1(w);if(p==1) break;if(p==0)temp=temp->next;if(temp==NULL) q=1;}//if(q==1)while(1){p=yufa_SLR1(17);if(p==3) break;}//$}}void yufa_initialize() { stack_head=new ike;stack_tail=new ike;stack_head->pre=NULL;stack_head->next=stack_tail; stack_head->num=0;stack_head->word='!';stack_tail->pre=stack_head; stack_tail->next=NULL;//css[0].left='Q';css[0].right="P";css[1].left='P';css[1].right="id()L;R"; css[2].left='L';css[2].right="L;D";css[3].left='L';css[3].right="D";css[4].left='D';css[4].right="id:int"; css[5].left='E';css[5].right="E+T";css[6].left='E';css[6].right="T";css[7].left='T';css[7].right="T*F";css[8].left='T';css[8].right="F";css[9].left='F';css[9].right="(E)";css[10].left='F';css[10].right="id";css[11].left='B';css[11].right="B and B"; css[12].left='B';css[12].right="id>id"; css[13].left='M';css[13].right="id=E";css[14].left='S';css[14].right="if B then M"; css[15].left='S';css[15].right="while B do M"; css[16].left='S';css[16].right="M";css[17].left='N';css[17].right="N;S";css[18].left='N';css[18].right="S";css[19].left='R';css[19].right="{N}";int i,j;for(i=0;i<20;i++){char *css_len;css_len=&css[i].right[0];css[i].len=strlen(css_len); }css[1].len=6;css[4].len=3;css[10].len=1;css[11].len=3;css[12].len=3;css[13].len=3;css[14].len=4;css[15].len=4;//for(i=0;i<46;i++){for(j=0;j<18;j++)action[i][j].sr='#';}//actionfor(i=0;i<46;i++){for(j=0;j<11;j++)go_to[i][j]=-1;}//go_to/****************************actiongo_to************************/ action[0][0].sr='s';action[0][0].state=2;action[1][17].sr='@';//action[2][1].sr='s';action[2][1].state=3;action[3][2].sr='s';action[3][2].state=4;action[4][0].sr='s';action[4][0].state=5;action[5][4].sr='s';action[5][4].state=6;action[6][11].sr='s';action[6][11].state=7;action[7][3].sr='r';action[7][3].state=4;action[8][3].sr='r';action[8][3].state=3;action[9][3].sr='s';action[9][3].state=10; action[10][0].sr='s';action[10][0].state=5; action[10][9].sr='s';action[10][9].state=13; action[11][17].sr='r';action[11][17].state=1; action[12][3].sr='r';action[12][3].state=2; action[13][0].sr='s';action[13][0].state=14; action[13][13].sr='s';action[13][13].state=23; action[13][15].sr='s';action[13][15].state=27; action[14][8].sr='s';action[14][8].state=15; action[15][0].sr='s';action[15][0].state=36; action[15][1].sr='s';action[15][1].state=41; action[16][6].sr='s';action[16][6].state=43; action[16][3].sr='r';action[16][3].state=13; action[16][10].sr='r';action[16][10].state=13; action[17][3].sr='s';action[17][3].state=19; action[17][10].sr='s';action[17][10].state=18; action[18][17].sr='r';action[18][17].state=19; action[19][0].sr='s';action[19][0].state=14; action[19][13].sr='s';action[19][13].state=23; action[19][15].sr='s';action[19][15].state=27; action[20][3].sr='r';action[20][3].state=17; action[20][10].sr='r';action[20][10].state=17; action[21][3].sr='r';action[21][3].state=18; action[21][10].sr='r';action[21][10].state=18;action[22][3].sr='r';action[22][3].state=16; action[22][10].sr='r';action[22][10].state=16; action[23][0].sr='s';action[23][0].state=31; action[24][12].sr='s';action[24][12].state=34; action[24][14].sr='s';action[24][14].state=25; action[25][0].sr='s';action[25][0].state=14; action[26][3].sr='r';action[26][3].state=14; action[26][10].sr='r';action[26][10].state=14; action[27][0].sr='s';action[27][0].state=31; action[28][12].sr='s';action[28][12].state=34; action[28][16].sr='s';action[28][16].state=29; action[29][0].sr='s';action[29][0].state=14; action[30][3].sr='r';action[30][3].state=15; action[30][10].sr='r';action[30][10].state=15; action[31][7].sr='s';action[31][7].state=32; action[32][0].sr='s';action[32][0].state=33; action[33][12].sr='r';action[33][12].state=12; action[33][14].sr='r';action[33][14].state=12; action[33][16].sr='r';action[33][16].state=12; action[34][0].sr='s';action[34][0].state=31; action[35][12].sr='r';action[35][12].state=11; action[35][14].sr='r';action[35][14].state=11; action[35][16].sr='r';action[35][16].state=11; action[36][2].sr='r';action[36][2].state=10;action[36][3].sr='r';action[36][3].state=10; action[36][5].sr='r';action[36][5].state=10; action[36][6].sr='r';action[36][6].state=10; action[36][10].sr='r';action[36][10].state=10; action[37][2].sr='r';action[37][2].state=8; action[37][3].sr='r';action[37][3].state=8; action[37][5].sr='r';action[37][5].state=8; action[37][6].sr='r';action[37][6].state=8; action[37][10].sr='r';action[37][10].state=8; action[38][2].sr='r';action[38][2].state=6; action[38][3].sr='r';action[38][3].state=6; action[38][5].sr='s';action[38][5].state=39; action[38][6].sr='r';action[38][6].state=6; action[38][10].sr='r';action[38][10].state=6; action[39][0].sr='s';action[39][0].state=36; action[39][1].sr='s';action[39][1].state=41; action[40][2].sr='r';action[40][2].state=7; action[40][3].sr='r';action[40][3].state=7; action[40][5].sr='r';action[40][5].state=7; action[40][6].sr='r';action[40][6].state=7; action[40][10].sr='r';action[40][10].state=7; action[41][0].sr='s';action[41][0].state=36; action[41][1].sr='s';action[41][1].state=41; action[42][2].sr='s';action[42][2].state=45;action[42][6].sr='s';action[42][6].state=43;action[43][0].sr='s';action[43][0].state=36;action[43][1].sr='s';action[43][1].state=41;action[44][2].sr='r';action[44][2].state=5;action[44][3].sr='r';action[44][3].state=5;action[44][5].sr='s';action[44][5].state=39;action[44][6].sr='r';action[44][6].state=5;action[44][10].sr='r';action[44][10].state=5;action[45][2].sr='r';action[45][2].state=9;action[45][3].sr='r';action[45][3].state=9;action[45][5].sr='r';action[45][5].state=9;action[45][6].sr='r';action[45][6].state=9;action[45][10].sr='r';action[45][10].state=9;go_to[0][0]=1;go_to[4][1]=8;go_to[4][9]=9;go_to[10][1]=12;go_to[10][ 2]=11;go_to[13][7]=22;go_to[13][8]=21;go_to[13][10]=17;go_to[15][3]=16;go_to[15][4]=38;go_to[15][5]=37;go_to[19][7]=20;go_t o[19][8]=20;go_to[23][6]=24;go_to[25][7]=26;go_to[27][6]=28;go_to[29][7]=30;go_to[34][6]=35;go_to[39][5]=40;go_to[41][3]=42;go_t o[41][4]=38;go_to[41][5]=37;go_to[43][4]=44;go_to[43][5]=37;/****************************actiongo_to************************/ }int ID1(int i)//action {int j;j=-1;if(i==25) {j=0;id_num++;}//if(i==1) {j=8,id_left=id_num;}//if(i==2) j=6;if(i==3) j=5;if(i==4) j=7;if(i==5) j=4;if(i==6) j=3;if(i==7) j=9;if(i==8) j=10;if(i==9) j=1;if(i==10) j=2;if(i==31) j=12;if(i==32) j=13;if(i==33) {j=14;id_then=L_four_tail->k+1;}//ifthenif(i==35) {j=15;id_while=L_four_tail->k+1;}//whilewhile if(i==36) {j=16;id_do=L_four_tail->k+1;}//whiledoif(i==37) j=11;return(j);}string ID10(int i)//{string ch;if(i==0) ch="id";if(i==1) ch="(";if(i==2) ch=")";if(i==3) ch=";";if(i==4) ch=":";if(i==5) ch="*";if(i==6) ch="+";if(i==7) ch=">";if(i==8) ch="=";if(i==9) ch="{";if(i==10) ch="}";if(i==11) ch="int";if(i==12) ch="and";if(i==13) ch="if";if(i==14) ch="then";if(i==15) ch="while"; if(i==16) ch="do";if(i==17) ch="$";return(ch);}int ID2(char ch)//go_to {int j;j=-1;if(ch=='P') j=0;if(ch=='D') j=1;if(ch=='R') j=2;if(ch=='E') j=3;if(ch=='T') j=4;if(ch=='F') j=5;if(ch=='B') j=6;if(ch=='M') j=7;if(ch=='S') j=8;if(ch=='L') j=9;if(ch=='N') j=10; return(j);}int ID20(char ch)// {int j;j=-1;if(ch=='P') j=100; if(ch=='D') j=101; if(ch=='R') j=102; if(ch=='E') j=103; if(ch=='T') j=104; if(ch=='F') j=105;if(ch=='B') j=106;if(ch=='M') j=107;if(ch=='S') j=108;if(ch=='L') j=109;if(ch=='N') j=1010;return(j);}char ID21(int j)//{char ch;if(j==100 || j==0) ch='P'; if(j==101 || j==1) ch='D'; if(j==102 || j==2) ch='R'; if(j==103 || j==3) ch='E'; if(j==104 || j==4) ch='T'; if(j==105 || j==5) ch='F'; if(j==106 || j==6) ch='B'; if(j==107 || j==7) ch='M'; if(j==108 || j==8) ch='S'; if(j==109 || j==9) ch='L'; if(j==1010 || j==10) ch='N'; return(ch);}void add(ike *temp)//{if(stack_head->next==stack_tail){temp->pre=stack_head;temp->next=stack_tail;stack_head->next=temp;stack_tail->pre=temp;}else{temp->pre=stack_tail->pre;temp->next=stack_tail;stack_tail->pre->next=temp;stack_tail->pre=temp;}}void del()//{stack_tail->pre->pre->next=stack_tail; stack_tail->pre=stack_tail->pre->pre; }int yufa_SLR1(int w){/*cout<<""<<ID10(w)<<" ";*/int i,flag=0,state_temp;//flag01,23char sr_temp;sr_temp=action[stack_tail->pre->num][w].sr;//state_temp=action[stack_tail->pre->num][w].state;// if(sr_temp=='#')//{flag=1;err=3;cout<<"!"<<endl;}else if(sr_temp=='s')//{ike *temp;temp=new ike;temp->next=NULL;temp->pre=NULL;temp->word=w;temp->num=state_temp;add(temp);cout/*<<""*/<<sr_temp<<state_temp<<" "/*<<""<<stack_tail->pre->num<<" "<<""<<ID10(stack_tail->pre->word)*/<<endl;flag=0;}else if(sr_temp=='r')//{int p=ID2(css[state_temp].left);int q=css[state_temp].len;for(i=0;i<q;i++)del();ike *temp;temp=new ike;temp->next=NULL;temp->pre=NULL;temp->word=ID20(css[state_temp].left);temp->num=go_to[stack_tail->pre->num][p];//go_toadd(temp);cout/*<<""*/<<sr_temp<<state_temp<<" "<<css[state_temp].left<<""<<css[state_temp].right<<" "/*<<""<<stack_tail->pre->num<<" "<<""<<ID21(stack_tail->pre->word)*/<<endl;flag=2;yuyi_main(state_temp);//}else if(sr_temp=='@')//{cout<<"END"/*<<""<<sr_temp<<state_temp*/<<""<<css[state_temp].left<<""<<css[state_temp].right<<" "/*<<""<<stack_tail->pre->num<<" "<<""<<ID21(stack_tail->pre->word)*/<<endl;flag=3;cout<<"!"<<endl;}else//{flag=1;err=3;cout<<"!"<<endl;}return(flag);}/******************************************************/ void yuyi_main(int m){L *temp;int k;k=1;temp=new L;temp->op=" ";temp->op1=" ";temp->op2=" ";temp->result="";temp->next=NULL;temp->Ltrue=NULL;temp->Lfalse=NULL;if(m==4)//{symb *Stemp;Stemp=new symb;id_name=id_numtoname(id_num); Stemp->word=id_name;Stemp->next=NULL;add_symb(Stemp);}if(m==5)//EE+T{temp->op="+";temp->op1=E_name;temp->op2=T_name;yuyi_linshi++;//E_name="t"+newop(yuyi_linshi); temp->result=E_name;add_L_four(temp);//}if(m==6)//ET{E_name=T_name;}if(m==7)//TT*F{temp->op="*";temp->op1=T_name;temp->op2=F_name;yuyi_linshi++;//T_name="t"+newop(yuyi_linshi); temp->result=T_name;add_L_four(temp);//}if(m==8)//TF{T_name=F_name;}if(m==9)//F(E){F_name=E_name;}if(m==10)//Fid{id_name=id_numtoname(id_num); F_name=id_name;k=lookup(id_name);//if(k==0){err=2;errword=id_name;return;}}if(m==12)//Bid>id{temp->op="J>";id1_num=id_num-1;id1_name=id_numtoname(id1_num); k=lookup(id1_name);//if(k==0){err=2;errword=id1_name;return;}id2_num=id_num;id2_name=id_numtoname(id2_num); k=lookup(id2_name);//if(k==0){err=2;errword=id2_name;return;}temp->result="-1";temp->op1=id1_name;temp->op2=id2_name;add_L_four(temp);//add_L_true(temp);//trueL *temp2;temp2=new L;temp2->op="J";temp2->op1=" ";temp2->op2=" ";temp2->result="-1";add_L_four(temp2);//add_L_false(temp2);//false}if(m==13)//Mid=E{temp->op="=";temp->op1=E_name;temp->op2=" ";id_name=id_numtoname(id_left);temp->result=id_name;add_L_four(temp);//yuyi_linshi=-1;//}if(m==14)//Sif B then M{int a;a=id_then;temp=L_true_head->Ltrue;while(temp!=NULL){temp->result="L"+newop(a);a=temp->k;temp=temp->Ltrue;}a=L_four_tail->k+1;temp=L_false_head->Lfalse;while(temp!=NULL){temp->result="L"+newop(a);temp=temp->Lfalse;}L_true_head->Ltrue=NULL;L_false_head->Lfalse=NULL;//truefalse}if(m==15)//Swhile B do M {int a;a=id_do;temp=L_true_head->Ltrue; while(temp!=NULL){temp->result="L"+newop(a); a=temp->k;temp=temp->Ltrue;}a=L_four_tail->k+2;temp=L_false_head->Lfalse; while(temp!=NULL){temp->result="L"+newop(a); temp=temp->Lfalse;}L *temp1;temp1=new L;temp1->op="J";temp1->op1=" ";temp1->op2=" ";temp1->next=NULL;temp1->result="L"+newop(id_while); add_L_four(temp1);//L_true_head->Ltrue=NULL;L_false_head->Lfalse=NULL;//truefalse }}string newop(int m)//{int shang,yushu;string chuan,chuan1;shang=m;chuan="";while(1){yushu=shang%10;chuan=chuan+char(48+yushu);shang=shang/10;if(shang==0)break;}int i;char *ch;ch=&chuan[0];chuan1="";for(i=strlen(ch)-1;i>=0;i--)chuan1=chuan1+chuan[i];return(chuan1);}void add_L_four(L *temp)//{temp->k=L_four_tail->k+1;if(L_four_head->next == NULL){L_four_head->next=temp;L_four_tail->next=temp;}else{L_four_tail->next->next=temp;L_four_tail->next=temp;}L_four_tail->k=L_four_tail->next->k; } void add_L_true(L *temp)//true{temp->Ltrue=L_true_head->Ltrue;L_true_head->Ltrue=temp;}void add_L_false(L *temp)//false {temp->Lfalse=L_false_head->Lfalse; L_false_head->Lfalse=temp;}void add_symb(symb *temp)//{if(symb_head->next == NULL){temp->addr=0;symb_head->next=temp;symb_tail->next=temp;}else{temp->addr=symb_tail->next->addr+4; symb_tail->next->next=temp;symb_tail->next=temp;}}void output_yuyi(){if(err==0)//{cout<<endl;system("pause");cout<<endl;cout<<"************************"<<endl;cout<<"* *"<<endl;cout<<"************************"<<endl;cout<<""<<endl;L *temp;temp=L_four_head->next;while(temp!=NULL){cout<<"L"<<temp->k<<": "<<temp->op<<", "<<temp->op1<<", "<<temp->op2<<","<<temp->result<<""<<endl;temp=temp->next;}cout<<""<<endl;symb *Stemp;Stemp=symb_head->next;cout<<"name"<<" type "<<" id "<<" identifer "<<"addr"<<endl;while(Stemp!=NULL){cout<<Stemp->word<<" int "<<" 25 "<<" sv "<<Stemp->addr<<endl;Stemp=Stemp->next;}}if(err==2)//{cout<<endl;system("pause");cout<<endl;cout<<"************************"<<endl; cout<<"* *"<<endl;cout<<"************************"<<endl; cout<<""<<errword<<"!"<<endl;}}string id_numtoname(int num)//{str *temp;string name;temp=string_head->next;while(temp!=NULL){if(num==temp->num){name=temp->word;break;。

(完整版)编译原理毕业课程设计(语法分析程序)

(完整版)编译原理毕业课程设计(语法分析程序)

编译原理实验报告题目:对下面的文法对象,使用c语言构造它的预测分析程序;并任意给一算术表达式进行分析测试.分析对象对象定义如下:算术表达式→项|算术表达式+项|算术表达式-项项→因式|项*因式|项因式因式→变量|(算术表达式)变量→字母字母→A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z一、分析语法分析部分我们我们采用ll(1)方法实现,采用ll(1)方法实现语法发分析要求文法满足以下要求:一个文法能否用确定的自顶向下分析与文法中相同左部的每个产生式右部的开始符号集合有关,当有右部能=*=>ε时则与其左部非终结符的后跟符号集合也有关,此外在产生式中不存在左递归即经过压缩,无左递归,无回溯。

它的基本思想是从左到右扫描源程序,同时从识别符号开始生成句子的最左推导,并只向前查看一个输入符号,便能唯一确定应选择的规则。

下面将确切地定义满足确定的自顶向下分析条件的文法即LL(1)文法及LL(1)文法的判别并介绍如何对非LL(1)文法进行等价变换问题,也就是消除一个文法中的左递归和左公共因子。

注意:一个文法中含有左递归和左公共因子绝对不是LL(1)文法,所以也就不可能用确定的自顶向下分析法,对此结论可以证明。

然而,某些含有左递归和左公共因子的文法在通过等价变换把它们消除以后可能变为LL(1)文法,但需要用LL(1)文法的定义判别,也就是说文法中不含左递归和左公共因子,只是LL(1)文法的必要条件。

LL(1) 文法的定义(5种定义):一个文法符号串的开始符号集合定义如下:定义 1. 设G=(VT,VN,S,P)是上下文无关文法,α是任意的文法符号串,FIRST(α)是从α推导出的串的开始符号的终结符集合。

FIRST(α)={a|α=*=>aβ,a∈VT,α,β∈V*}若α=*=>ε,则规定ε∈FIRST(α).当一个文法中相同左部非终结符的右部存在能=*=>ε的情况则必须知道该非终结符的后跟符号的集合中是否含有其它右部开始符号集合的元素。

语义分析程序的设计与实现

语义分析程序的设计与实现

syn=10;
for(n=0;n<6;n++)
if(strcmp(token,rwtab[n])==0)
{
syn=n+1;
三、实验要求:
1. 对语法规则有明确的定义;
2. 编写的分析程序能够对实验二的结果进行正确的语义分析;
3. *对于遇到的语法、语义错误,能够做出简单的错误处理,给出简单的错误提示,保证语义分析过程;
4. 实验报告要求用文法的形式对语义详细说明,说明语义分析程序的工作过程,说明相应翻译动作的实现*。
}
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{
m=0;
while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
default: syn=-1;break;
}
}
int lrparser()
{//cout<<"调用lrparser"<<endl;
int schain=0;
kk=0;
if(syn==1)
{
scaner();
}
break;
case'*':syn=13;token[0]=ch;break;

编译原理课程设计

编译原理课程设计

编译原理课程设计1. 引言编译原理是计算机科学与技术专业中的一门核心课程,它主要研究如何将高级语言程序转换为机器语言程序,从而实现程序的执行。

编译原理课程设计是这门课程中的重要环节,通过完成一个小型编译器的设计与实现,帮助学生深入理解编译原理的基本原理与技术,提高编程能力和解决实际问题的能力。

本文档将详细介绍一个基于编译原理的课程设计的要求、流程和一些实现细节,提供实践指导和参考。

2. 课程设计要求2.1 设计目标编译原理课程设计的设计目标是实现一个基于简单语言的编译器,能够将该语言的源代码转换为目标代码,并能正确运行。

2.2 设计任务本次课程设计的任务是设计并实现一个编译器,包括词法分析、语法分析、语义分析、中间代码生成和目标代码生成等模块。

具体任务包括:•设计并实现词法分析模块,将源代码转换为词法单元序列。

•设计并实现语法分析模块,根据语法规则将词法单元序列转换为语法树。

•设计并实现语义分析模块,对语法树进行语义检查,并生成中间代码。

•设计并实现中间代码生成模块,将语法树转换为中间代码。

•设计并实现目标代码生成模块,将中间代码转换为目标代码。

2.3 设计要求•设计的编译器语言可以是一种简单的面向过程语言,或是自行设计的一种简化语言,语法规则和语义规则要符合编译原理的基本原理。

•要求设计的编译器能处理基本的数据类型、变量定义、运算符和控制语句等。

•要求课程设计过程中进行充分的测试和调试,确保编译器能正确识别语法错误、类型错误等,并能生成正确的目标代码。

•要求课程设计实现过程中使用适当的工具和技术,如Lex和Yacc等。

3. 设计流程3.1 概述设计一个编译器是一个复杂的任务,需要进行多个步骤的设计与实现。

以下是一个典型的设计流程:1.确定设计目标,确定设计任务。

2.设计词法分析器。

3.设计语法分析器。

4.设计语义分析器。

5.设计中间代码生成器。

6.设计目标代码生成器。

7.测试、调试和优化。

3.2 设计步骤详解3.2.1 确定设计目标,确定设计任务在这一步骤中,需要明确设计的目标和任务,确定设计的编译器语言和功能要求。

语义分析程序的设计与实现

语义分析程序的设计与实现

语义分析程序的设计与实现一:实验内容: (1)二:实验要求: (2)三:实验方法: (2)◆由LEX建立YACC的词法分析程序 (2)◆yacc原理介绍 (3)◆词法分析 (4)◆解析器如何工作 (5)◆Yacc环境 (5)◆常用代码 (7)第四:YACC内部名称: (7)第五:运行结果(源代码见附录) (8)第六:实验总结 (8)第七:附录 (10)附录一:yacc程序,加注释 (10)附录二:词法分析器的工作原理 (16)一:实验内容:编写语法分析程序,实现对算术表达式的语法分析,要求所分析的算术表达式由如下的文法产生。

◆E->E+T|E-T|T◆T->T*F|T/F|F◆F->id|(E)|num二:实验要求:在对表达式进行分析的同时,输出所采用的产生式。

可以采用多种方法◆编写递归调用程序,实现自顶向下的分析。

◆编写LL(1)语法分析程序,要求:◇编程实现算法4.2,为给定的文法自动构造预测分析表◇编程实现算法4.1,构造LL(1)预测分析程序,◆编写语法分析程序,实现自底向上的分析,要求:◇构造识别所有活前缀的DFA◇构造LR分析表◇编程实现算法4.3,构造LR分析程序◆利用yacc自动生成语法分析程序,调用LEX自动生成的词法分析器程序三:实验方法:◆由LEX建立YACC的词法分析程序由LEX产生的词法分析程序可用于YACC,LEX编译程序根据LEX 源程序产生词法分析程序yylex(),这个名字就是YACC所需要的词法分析程序的名字。

如果YACC要调用LEX产生的词法分析程序,则在YACC源程序的第三部分用语句#include“lex.yy.c”代替函数yylex()的定义,这一yylex()就可以访问YACC中记号的名字,因为LEX的输出时候YACC输出文件的一部分,所有,每个LEX的动作都返回YACC 知道的终结符。

在UNIX的环境下,如果LEX源程序在first.l中,YACC的源程序在second.y中,可以使用以下命令得到所需要的分析程序。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

}quad;
char prog[80],token[12];
char ch;
int syn,p,m=0,n,sum=0,kk; //p是缓冲区prog的指针,m是token的指针
char *rwtab[6]={"begin","if","then","while","do","end"};
p--;
}
break;
case'>':m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=24;
token[m++]=ch;
case'=':syn=25;token[0]=ch;break;
case';':syn=26;token[0]=ch;break;
case'(':syn=27;token[0]=ch;break;
case')':syn=28;token[0]=ch;break;
case'#':syn=0;token[0]=ch;break;
while(syn==26)
{
scaner();
schain=statement();
}
}
else
{cout<<"缺begin!"<<endl;kk=1;}
return(schain);
}
int yucu()
{// cout<<"调用yucu"<<endl;
int schain=0;
schain=statement();
实验三 语义分析程序的设计与实现
一、实验目的:
加深对语法分析器工作过程的理解;能够采用一种编程语言实现简单的语义分析程序;能够使用自己编写的分析程序对简单的程序段进行语义分析,生成中间代码。
二、实验内容:
在实验2的基础上,用递归下降分析法编制语义分析程序,语义分析程序的实现可以采用任何一种编程工具。
四元式表的结构如下:
struct
{ char result[8];
char ag1[8];
char op[8];
char ag2[8];
}quad[20];
(2) char *newtemp()
该函数回送一个新的临时变量名,临时变量名产生的顺序为T1,T2,…
while((ch>='0'&&ch<='9'))
{
sum=sum*10+ch-'0';
ch=prog[p++];
else switch(ch)
{
case'<':m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='>')
{
syn=21;
token[m++]=ch;
break;
}
}
else if((ch>='0'&&ch<='9'))
{
{
sum=0;
strcpy(quad.op,op);
strcpy(quad.ag2,ag2);
cout<<quad.result<<"="<<quad.ag1<<quad.op<<quad.ag2<<endl;
} Leabharlann char *newtemp()
#include<string.h>
#include<iostream.h>
#include<stdlib.h>
struct
{
char result[12];
char ag1[12];
char op[12];
char ag2[12];
}
void scaner()
{
for(n=0;n<8;n++) token[n]=NULL;
ch=prog[p++];
while(ch==' ')
{
ch=prog[p];
p++;
{
char *p;
char m[12];
p=(char *)malloc(12);
k++;
itoa(k,m,10);
strcpy(p+1,m);
p[0]='t';
return (p);
default: syn=-1;break;
}
}
int lrparser()
{//cout<<"调用lrparser"<<endl;
int schain=0;
kk=0;
if(syn==1)
{
scaner();
}
else
{
if(kk!=1)
cout<<"缺end!"<<endl;
kk=1;
}
}
}
p--;
syn=11;
if(sum>32767)
syn=-1;
}
schain=yucu();
if(syn==6)
{
scaner();
if(syn==0 && (kk==0))
cout<<"success!"<<endl;
}
break;
case'*':syn=13;token[0]=ch;break;
case'/':syn=14;token[0]=ch;break;
case'+':syn=15;token[0]=ch;break;
case'-':syn=16;token[0]=ch;break;
char *newtemp(void)
{ char *p;
char m[8];
p=(char *)malloc(8);
k++;
itoa(k,m,10);
strcpy(p+1,m);
四、实验学时:4学时
五、实验步骤:
1. 定义语法规则;
2. 设置语义过程,插入语义动作;
3. *对遇到的语法、语义错误做出错误处理。
六、算法思想:
1、设置语义过程。
(1)emit(char *result,char *ag1,char *op,char *ag2)
该函数的功能是生成一个三地址语句送到四元式表中。
void scaner();
char *factor(void);
char *term(void);
char *expression_r(void);
int yucu();
void emit(char *result,char *ag1,char *op,char *ag2);
三、实验要求:
1. 对语法规则有明确的定义;
2. 编写的分析程序能够对实验二的结果进行正确的语义分析;
3. *对于遇到的语法、语义错误,能够做出简单的错误处理,给出简单的错误提示,保证语义分析过程;
4. 实验报告要求用文法的形式对语义详细说明,说明语义分析程序的工作过程,说明相应翻译动作的实现*。
char *newtemp();
int statement();
int k=0;
void emit(char *result,char *ag1,char *op,char *ag2)
{
strcpy(quad.result,result);
strcpy(quad.ag1,ag1);
}
else if(ch=='=')
{
syn=22;
token[m++]=ch;
}
else
{
syn=23;
syn=10;
for(n=0;n<6;n++)
if(strcmp(token,rwtab[n])==0)
{
syn=n+1;
}
else
{
syn=20;
p--;
}
break;
case':':m=0;token[m++]=ch;
ch=prog[p++];
}
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{
m=0;
while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
相关文档
最新文档