编译原理课程设计——算术表达式、for、while语句转换为四元式

合集下载

写出如下语句的四元式序列

写出如下语句的四元式序列

写出如下语句的四元式序列1.引言1.1 概述在编程语言中,为了对程序进行分析和执行,我们需要将程序转换成计算机能够理解和执行的形式。

而四元式序列就是一种常用的表示方式之一。

四元式序列是由四个元素组成的元组,分别是操作符、操作数1、操作数2和结果。

它可以将复杂的程序语句拆分成更简单的操作,方便计算机进行处理。

在撰写四元式序列时,我们需要根据具体的语句来确定操作符、操作数1、操作数2和结果。

以以下语句为例:pythonx = y + z我们可以将这个语句转换成如下的四元式序列:1. (+, y, z, t1)2. (=, t1, "", x)在这个序列中,第一行的操作符是加号,操作数1和操作数2分别是变量y和z,结果是临时变量t1。

第二行的操作符是赋值号,操作数1是临时变量t1,操作数2为空,结果是变量x。

这样,通过四元式序列的表示,我们可以更清晰地描述程序的执行过程,方便后续的语义分析和执行。

总的来说,四元式序列在程序分析和执行中具有重要的作用,它可以将复杂的程序语句转换成更简单的操作,方便计算机进行处理。

在实际的编程中,我们可以根据具体的语句来编写相应的四元式序列,以达到更高效、更准确地执行程序的目的。

1.2文章结构文章1.2 文章结构文章结构是指文章整体的组织形式,包括各个部分之间的关系和排列顺序。

一个合理的文章结构能够使读者更好地理解文章的主题和内容,提高文章的可读性和逻辑性。

在本文中,我们将主要围绕三个部分展开,分别是引言、正文和结论。

引言部分作为文章的开端,其主要功能是引起读者的兴趣,明确文章的主题和目的。

在引言部分中,我们将对本文的概述进行介绍,简要说明文章的主要内容和结构,并阐述文章撰写的目的。

通过清晰明了地阐述引言部分的内容,能够让读者对后续的内容有一个整体的认识和预期,为接下来的阅读打下基础。

正文部分是文章的核心,也是作者表达观点和论证思路的主要部分。

在正文部分中,我们将围绕两个要点展开,分别是要点一和要点二。

编译原理课程设计WHILE循环语句的翻译程序设计(递归下降法、输出四元式)

编译原理课程设计WHILE循环语句的翻译程序设计(递归下降法、输出四元式)

学号:课程设计题目WHILE循环语句的翻译程序设计(递归下降法、输出四元式)学院计算机科学与技术专业计算机科学与技术班级计算机班姓名指导教师2012 年 1 月 6 日目录1.问题描述 (3)1.1问题描述 (3)1.2主要任务 (3)1.3测试数据 (3)2文法及属性文法的描述 (3)2.1文法的描述 (3)2.2 while-do循环语句的文法 (4)2.3递归文法的优化 (4)2.4属性文法的描述 (5)3.语法分析方法描述 (6)3.1程序设计对文法的要求 (6)3.2语法分析的思想 (7)3.3递归下降文法实现原理 (7)3.4中间代码形式 (8)4简要的分析与概要设计 (8)4.1全局程序的概要设计 (8)4.2词法分析 (9)4.3递归下降翻译器的设计 (9)4.4语法制导翻译 (10)5详细的算法描述 (10)5.1算法描述 (10)5.2运行结果 (14)6. 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等). 156.1研制过程 (15)6.2本设计的评价、特点 (16)6.3感受和体会 (16)6.4对程序改进的想法 (17)课程设计任务书学生姓名:专业班级:计算机班指导教师:工作单位:计算机科学与技术学院题目: WHILE循环语句的翻译程序设计(递归下降法、输出四元式)初始条件:理论:学完编译课程,掌握一种计算机高级语言的使用。

实践:计算机实验室提供计算机及软件环境。

如果自己有计算机可以在其上进行设计。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)(1)写出符合给定的语法分析方法的文法及属性文法。

(2)完成题目要求的中间代码四元式的描述。

(3)写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。

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

(5)设计报告格式按附件要求书写。

课程设计报告书正文的内容应包括:1 系统描述(问题域描述);2 文法及属性文法的描述;3 语法分析方法描述及语法分析表设计;4 按给定的题目给出中间代码形式的描述及中间代码序列的结构设计;5 编译系统的概要设计;6 详细的算法描述(流程图或伪代码);7 软件的测试方法和测试结果;8 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);9 参考文献(按公开发表的规范书写)。

编译原理四元式

编译原理四元式

编译原理四元式什么是编译原理四元式编译原理四元式是编译器中的一种数据结构,用于将源代码转化为计算机能够理解和执行的中间代码。

它由四个字段组成:操作符、操作数1、操作数2和结果。

四元式可以描述源代码中的各种数学和逻辑运算,以及赋值和控制流等操作。

四元式的优点1.易于生成:四元式的生成比解析源代码直接生成目标代码更容易,因为四元式是对源代码的直接翻译。

2.易于优化:通过对四元式进行优化,可以减少生成的目标代码的长度和运行时间。

3.易于理解:四元式是一种中间表示形式,可以帮助开发人员更好地理解和调试源代码。

4.易于扩展:可以通过添加新的操作符和操作数类型来扩展四元式的功能。

四元式的组成四元式由四个字段组成:操作符、操作数1、操作数2和结果。

操作符表示进行的操作,如加法、乘法等;操作数1和操作数2是参与操作的数值或变量;结果是操作的结果。

四元式的形式如下:<操作符, 操作数1, 操作数2, 结果>四元式的生成过程四元式的生成过程可以分为词法分析、语法分析和语义分析三个步骤。

1.词法分析:将源代码分割成一个个的词法单元,如标识符、关键字、操作符等。

2.语法分析:根据源代码的语法规则,生成语法树。

语法树是一个由节点和边组成的树状结构,每个节点表示一个语法单元,例如表达式、语句等。

3.语义分析:遍历语法树,并根据语义规则生成四元式。

语义规则定义了源代码中各个语法单元的含义和操作。

四元式的生成过程既可以手动实现,也可以通过编译器生成器生成。

四元式的应用四元式主要用于编译器的各个阶段,在优化和生成目标代码过程中起到关键作用。

1.优化:通过对四元式进行优化,可以减少生成的目标代码的长度和运行时间。

常见的优化技术包括常量折叠、公共子表达式消除和无用代码删除等。

2.目标代码生成:通过对四元式进行目标代码生成,可以将中间代码转化为目标机器代码。

目标机器代码是计算机能够直接执行的二进制指令。

四元式还可以用于源代码的调试和性能分析。

编译原理课后习题答案

编译原理课后习题答案

第一章1.典型的编译程序在逻辑功能上由哪几部分组成?答:编译程序主要由以下几个部分组成:词法分析、语法分析、语义分析、中间代码生成、中间代码优化、目标代码生成、错误处理、表格管理。

2. 实现编译程序的主要方法有哪些?答:主要有:转换法、移植法、自展法、自动生成法。

3. 将用户使用高级语言编写的程序翻译为可直接执行的机器语言程序有哪几种主要的方式?答:编译法、解释法。

4. 编译方式和解释方式的根本区别是什么?答:编译方式:是将源程序经编译得到可执行文件后,就可脱离源程序和编译程序单独执行,所以编译方式的效率高,执行速度快;解释方式:在执行时,必须源程序和解释程序同时参与才能运行,其不产生可执行程序文件,效率低,执行速度慢。

第二章1.乔姆斯基文法体系中将文法分为哪几类?文法的分类同程序设计语言的设计与实现关系如何?答:1)0型文法、1型文法、2型文法、3型文法。

2)2. 写一个文法,使其语言是偶整数的集合,每个偶整数不以0为前导。

答:Z→SME | BS→1|2|3|4|5|6|7|8|9M→ε | D | MDD→0|SB→2|4|6|8E→0|B3. 设文法G为:N→ D|NDD→ 0|1|2|3|4|5|6|7|8|9请给出句子123、301和75431的最右推导和最左推导。

答:N⇒ND⇒N3⇒ND3⇒N23⇒D23⇒123N⇒ND⇒NDD⇒DDD⇒1DD⇒12D⇒123N⇒ND⇒N1⇒ND1⇒N01⇒D01⇒301N⇒ND⇒NDD⇒DDD⇒3DD⇒30D⇒301N⇒ND⇒N1⇒ND1⇒N31⇒ND31⇒N431⇒ND431⇒N5431⇒D5431⇒75431N⇒ND⇒NDD⇒NDDD⇒NDDDD⇒DDDDD⇒7DDDD⇒75DDD⇒754DD⇒7543D⇒75431 4. 证明文法S→iSeS|iS| i是二义性文法。

答:对于句型iiSeS存在两个不同的最左推导:S⇒iSeS⇒iiSesS⇒iS⇒iiSeS所以该文法是二义性文法。

WHILE循环语句的翻译程序设计课设报告

WHILE循环语句的翻译程序设计课设报告

1.题目:将WHILE语句转换成四元式的程序实现设计内容及要求:设计一个语法制导翻译器,将WHILE语句翻译成四元式。

要求:先确定一个定义WHILE语句的文法,为其设计一个语法分析程序,为每条产生式配备一个语义子程序,按照一遍扫描的语法制导翻译方法,实现翻译程序。

对用户输入的任意一个正确的WHILE语句,程序将其转换成四元式输出(可按一定格式输出到指定文件中)。

1、系统描述通过设计、编制、调试一个WHILE循环语句的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。

用语法制导完成语义分析,并将形成的中间代码以四元式的形式输出。

2 、文法及属性文法的描述2.1 文法的描述该文法的产生式如下所示:(1)S->while(B){E}(2)E->AE(3)E->A(4)A->iPA(5)A->i(6)B->iTi(7)B->i其中while、( 、) 、{ 、} 、P、T 、;和i均为终结符,而S、A、B、E这些大写字母均为非终结符。

T表示比较运算符,P表示算术运算符,i表示合法标识符。

2.2 属性文法的描述对该文法的属性文法描述如下:(1) S->while(B){E} prinf(if B goto E else goto next)(2) E->AE print = ·(3) E->A print =(4) A->i P A print(A= P(5) A->i; = i;(6) B->i T i print(B = T(7) B->i = i3 、语法分析方法描述及语法分析表设计3.1 语法分析表设计3.1.1 文法的DFA3.1.2 LR(0)分析方法描述说明LR分析法的规约过程是规范推到的逆过程,所以LR分析过程是一种规范规约的过程。

其分析过程为:由文法构造出该文法项目集,再根据项目集构造该文法的DFA,再判断是否有移进-规约和规约-规约冲突,若没有冲突则该文法为LR(0)的,若有冲突则该文法是SLR(1)的,最后可以构造出LR(0)分析表。

编译原理课程设计——算术表达式、for、while语句转换为四元式

编译原理课程设计——算术表达式、for、while语句转换为四元式

计算机与信息学院《操作系统与编译原理联合课程设计报告》专题:编译原理部分学生姓名:学号:专业班级:指导教师:2014 年 7 月一、设计目标设计一个语法制导翻译器,将算术表达式、for语句、while语句翻译成四元式。

要求先确定一个定义算术表达式、for语句、while语句的文法,为其设计一个语法分析程序,为每条产生式配备一个语义子程序,按照一遍扫描的语法制导翻译方法,实现翻译程序。

对用户输入的任意一个正确的表达式,程序将其转换成四元式输出。

二、设计思路开发平台:Visual C++ MFC解决这个问题的方案分为以下几个步骤:1.将算数表达式、for语句、while语句转换为四元式的第一步为对读入的表达式进行处理,即删除不必要的空格、回车、换行等,保证之后的步骤能够顺利进行。

2.分析算术表达式、for语句、while语句的文法。

3.通过词法分析判断语句中的每个字符的类型,如:数字、字母、符号等。

4.建立每种文法的LR(0)分析表,通过每个文法的LR(0)分析表对相应的表达式进行语法分析。

5.在语法分析正确的情况下,通过语法分析的中间过程的符号栈输出四元式,四元式的形式为:(op arg1 arg2 result)。

(一)算术表达式转换为四元式将算术表达式转换为四元式首先考虑了括号的问题,对于不同的算术表达式第一步进行词法分析,即确定各种符号的位置。

而括号中的式子是优先级最高的,应该最先进行处理。

我使用了一个数组记录算术表达式中括号的位置,并且定义了first_cc和first_jj函数对括号内的乘除法和加减法分别进行处理。

后将括号内的式子以四元式的形式输出。

通过以上转换,已将原算术表达式中的括号中的内容使用大写字母’A’、’B’……等代替(其中定义声明了change函数,用来将括号部分替换为大写字母)。

新的式子中,只含有加减乘除以及赋值这四种运算,后根据优先级的不同,逐步生成四元式。

其算法流程图如右图所示。

布尔表达式到四元式的转换 -回复

布尔表达式到四元式的转换 -回复

布尔表达式到四元式的转换-回复
布尔表达式到四元式的转换可分为以下几个步骤:
1. 将布尔表达式化简,将每个运算符左右两边的操作数分别用变量或常量表示。

2. 对于每个子表达式,生成一个形如(操作符, 操作数1, 操作数2, 结果)的四元式。

3. 对于布尔运算符,需要特别处理。

例如,将'&&' 转换为'JZ'(跳转指令)和'&&'(取反操作),将' ' 转换为'JNZ' 和' '。

4. 如果表达式中含有括号,则需要按照括号的顺序来生成四元式,确保表达式的顺序正确。

5. 最后将所有生成的四元式按顺序输出即可。

举例说明:
假设需要将布尔表达式a && b (c !d) 转换成四元式。

首先化简该表达式,得到a, b, c, d 四个操作数。

然后对于子表达式a && b 和c !d 生成四元式:
①(&&, a, b, t1)
②(!, d, _, t2)
③(, c, t2, t3)
再对于整个表达式生成四元式:
④(, t1, t3, t4)
其中,t1, t2, t3, t4 是临时变量,用于储存子表达式的结果。

最终输出的四元式为:①、②、③、④。

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

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

编译原理课程设计_算术表达式的语法分析及语义分析程序设计(模版)第一篇:编译原理课程设计_算术表达式的语法分析及语义分析程序设计(模版)设计题一:算术表达式的语法分析及语义分析程序设计。

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

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

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

源代码#define _CRT_SECURE_NO_WARNINGS #include “stdio.h” #include “stdlib.h” #include using namespace std;char data[20][20];//算符优先关系char s[100];//模拟符号栈s char 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} for(i = 0;i} for(i = 0;ifor(j = 0;st[i][j]!= '';j++)if((st[i][j]'Z')&& st[i][j]!= '-'&&st[i][j]!= lable[k++] = st[i][j];for(j = 0;st[i][j]!= '';j++){ } if(st[i][0]'Z'){} 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);printf(“文法error!n”);exit(-1);scanf(“%s”, st[i]);//存储文法规则,初始化FIRSTVT集和LASTVT集*/first[i][0] = 0;/*first[i][0]和last[i][0]分别表示st[i][0]非终极符的last[i][0] = 0;FIRSTVT集和LASTVT集中元素的个数*/'>'&&st[i][j]!= '|')lable[k] = '#';lable[k + 1] = '';} table();//printf(“FIRST集为:n”);//输出每个非终结符的FIRST集for(i = 0;i} printf(“LAST集为:n”);//输出每个非终结符的LAST集for(i = 0;i} printf(“算符优先分析表如下:n”);for(i = 0;lable[i]!='';i++)printf(“t%c”, lable[i]);printf(“n”);for(i = 0;i} printf(“请输入文法输入符号串以#结束:”);scanf(“%s”, input);deal();cout << “逆波兰式为:”;for(i = 0;lable[i]!= '';i++)cout << output[i] << '';// cout << endl;printf(“%ct”, lable[i]);for(j = 0;jchar text[20][10];//存储改写后的文法int i, j, k, t, l, x = 0, y = 0;int m, n;x = 0;for(i = 0;ifirstvt(st[i][0]);lastvt(st[i][0]);} for(i = 0;i{text[x][y] = st[i][0];y++;for(j = 1;st[i][j]!= '';j++){if(st[i][j] == '|')//{text[x][y] = '';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] = '';x++;y = 0;} r1 = x;//printf(“转化后的文法为:n”);for(i = 0;iprintf(“%sn”, text[i]);} for(i = 0;i{//输出转化后的文法规则串/*求每个终结符的推导结果(去掉“->”后的} str[i][0] = text[i][0];for(j = 3, l = 1;text[i][j]!= '';j++, l++)str[i][l] = text[i][j];str[i][l] = '';for(i = 0;ifor(j = 1;text[i][j + 1]!= '';j++){if(terminal_symbol(text[i][j])&& terminal_symbol(text[i][j + 1])){} if(text[i][j + 2]!= ''&&terminal_symbol(text[i][j])&& {} if(terminal_symbol(text[i][j])&&!terminal_symbol(text[i][j + 1]))//终结{} if(!terminal_symbol(text[i][j])&& terminal_symbol(text[i][j + 1]))//非终{ for(k = 0;k} m = location(text[i][j]);for(t = 0;t} n = location(first[k][t + 1]);data[m][n] = 'break;m = location(text[i][j]);n = location(text[i][j + 2]);data[m][n] = '=';m = location(text[i][j]);n = location(text[i][j +1]);data[m][n] = '=';terminal_symbol(text[i][j +2])&&!terminal_symbol(text[i][j + 1]))符和非终结符相接,用后于关系填表结符和终结符相接,用先于关系填表if(st[k][0] == text[i][j])break;}n = location(text[i][j + 1]);for(t = 0;t{m = location(last[k][t + 1]);data[m][n] = '>';}}} } m = location('#');//#后于所有的终结符规约for(t = 0;tn = location(first[0][t + 1]);data[m][n] = 'for(t = 0;tm = location(last[0][t + 1]);data[m][n] = '>';} data[n][n] = '=';}void firstvt(char c){ int i, j, k, m, n;for(i = 0;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]))//求FIRSTVT集}}} {} else {} if(terminal_symbol(st[i][m + 2])){} if(st[i][m + 1]!= c){firstvt(st[i][m + 1]);for(j = 0;j}for(k = 0;k}int t;for(t = 0;t}if(t == n){}first[i][n] = first[j][k + 1];n++;if(first[i][t] == first[j][k + 1])break;if(st[j][0] == st[i][m + 1])break;first[i][n] = st[i][m + 2];n++;first[i][n] = st[i][m + 1];n++;m++;} while(st[i][m]!= '');first[i][n] = '';first[i][0] =--n;fflag[i] = 1;void lastvt(char c)//求LASTVT集 {int i, j, k, m, n;for(i = 0;i} if(lflag[i] == 0){n = last[i][0] + 1;m = 0;do {if(st[i][m + 1] == '' || st[i][m + 1] == '|'){if(terminal_symbol(st[i][m])){} else {if(terminal_symbol(st[i][m1];n++;last[i][n] = st[i][m];n++;if(st[i][0] == c)break;}}}}}}if(t == n){}last[i][n] = last[j][k + 1];n++;m++;} while(st[i][m]!= '');last[i][n] = '';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]!= '';i++);//计算输入串的长度z = i--;// i = 0;while((a = input[i])!= '')//a表示要输入的字符 {if(terminal_symbol(s[k]))j = k;j = k1]))j = j2;x = location(s[j]);y = location(q);} while(data[x][y]!= '} k = j + 1;if(k == 2 && a == '#'){out(1, k, s);printf(“%c”, a);out(i + 1, z, input);printf(“结束n”);for(N = 0;N} if(!terminal_symbol(s[m])&&!terminal_symbol(str[N][n])){} elseif(terminal_symbol(s[m]))if(s[m] == str[N][n]){}s[j + 1] = str[N][0];break;if(terminal_symbol(s[m + 1])&& terminal_symbol(str[N][n + 1]){}s[j + 1] = str[N][0];break;&& s[m + 1] == str[N][n + 1])}} printf(“规约成功!n”);return 1;//输入串符合文法的定义elseif(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){ int i;for(i = 0;lable[i]!= '';i++)//求字符c在算符优先关系表中的下标} {} return-1;if(c == lable[i])return i;int terminal_symbol(char c)//判断字符c是否是终极符 {} int i;for(i = 0;lable[i]!= '';i++){} return 0;if(c == lable[i])return 1;第二篇:编译原理语法分析实验报告实验2:语法分析1.实验题目和要求题目:语法分析程序的设计与实现。

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

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

课程设计任务书学生姓名:专业班级:指导教师:工作单位:题目: 算术表达式的语法分析及语义分析程序设计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,结果>`的中间代码表示。

入口语句是指在程序的执行过程中第一个执行的语句,它通常被用作程序的入口点。

在生成四元式的过程中,入口语句的处理是至关重要的。

三、四元式入口语句的生成过程1.词法分析在生成四元式之前,首先需要进行词法分析。

词法分析过程中,将源代码分解成一个个的记号(t ok en),并分类标记。

例如,将源代码中的`i nt a=10;`分解成`I NT`、`I DE NT IF IE R`、`E QU AL S`、`N U MB ER`、`S EM IC OL ON`等记号。

2.语法分析语法分析是基于词法分析的结果,将记号序列转化为语法树。

在语法分析阶段,我们使用上下文无关文法来描述语言的语法规则,并将其转化为语法树。

根据语法树的生成过程,可以生成对应的四元式。

3.生成四元式生成四元式的过程中,需要考虑入口语句的处理。

通常情况下,入口语句是程序的第一个可执行语句,例如`m a in`函数。

根据程序的逻辑结构,我们可以将入口语句设置为程序开始执行的地方,并生成相应的四元式。

4.优化和转换生成四元式之后,可以进行代码优化和转换的操作。

代码优化可以通过改变四元式的顺序,减少无用的计算和冗余的语句,提高程序的执行效率。

代码转换可以将高级语言的代码转化为目标代码,为编译器的后续工作做准备。

四、示例下面是一个简单的示例,演示了如何生成四元式入口语句:1)源代码:i n ta=10;2)词法分析:I N TI DE NT IF IE RE QUA L SN UM BE RS EM IC OLO N3)语法分析和生成四元式:T1=10a=T14)生成的四元式:(=,10,-,T1)(=,T1,-,a)五、总结本文介绍了编译原理中四元式入口语句的生成过程。

编译原理E课内实践报告:WHILE循环语句的翻译程序设计与实现,递归下降法,输出四元式

编译原理E课内实践报告:WHILE循环语句的翻译程序设计与实现,递归下降法,输出四元式

文法及属性文法的描述 ............................................................................................... 2 2.1 2.2 文法描述 ............................................................................................................. 2 属性文法描述 ..................................................................................................... 3
2.2 属性文法描述
形式上讲,属性文法是一个三元组 :A=(G,V,F), 其中: ➢ G:是一个上下文无关文法; ➢ V:有穷的属性集,每个属性与文法的一个终结符或非终结符相连 ,这些属性代表与 文法符号相关信息; ➢ F:关于属性的属性断言或一组属性的计算规则(称为语义规则) 。 断言或语义规则 与一个产生式相联,只引用该产生式左端或右端的终结符或非终结符相联的属性。 属性文法中的属性分成两类:继承属性和综合属性。 ➢ 综合属性(synthesized attribute) :如果 b 是 A 的属性,c1 , c2 , …, ck 是产生式右 部文法符号的属性或 A 的其它属性,则称 b 是文法符号 A 的综合属性。 ➢ 继承属性(inherited attribute):如果 b 是产生式右部某个文法符号 X 的属性,并且 c1,c2,…,ck 是 A 或产生式右部文法符号的属性, 则称 b 是文法符号 X 的继承属性。
3

c语言循环实现计算机的四则运算

c语言循环实现计算机的四则运算

一、概述计算机是现代社会不可或缺的工具,而计算机的运算能力是其重要的功能之一。

C语言作为一种通用的高级语言,具有广泛应用的特点,在计算机编程中也扮演着重要的角色。

本文将介绍如何利用C语言的循环结构,实现计算机的四则运算功能,以及对应的代码实现。

二、C语言循环结构C语言提供了多种循环结构,包括for循环、while循环和do...while循环。

这些循环结构可以帮助程序实现重复执行某段代码的功能,非常适合用于实现四则运算中的重复计算过程。

1. for循环for循环是C语言中最常用的一种循环结构,其语法形式为:```cfor (初始化表达式; 判断表达式; 更新表达式){循环体;}```其中初始化表达式用于初始化循环变量,判断表达式用于判断循环是否继续执行,更新表达式用于更新循环变量的值。

利用for循环结构,可以方便地实现对变量进行增减的操作,从而实现四则运算中的加减乘除功能。

2. while循环while循环是C语言中另一种常见的循环结构,其语法形式为:```cwhile (判断表达式){循环体;}```while循环会在每次执行循环体之前判断条件表达式的真假,只有在条件为真时才会执行循环体,因此适用于实现需要满足特定条件才能进行计算的四则运算。

3. do...while循环do...while循环是C语言中的另一种循环结构,其语法形式为:```cdo{循环体;} while (判断表达式);```do...while循环先执行一次循环体,然后再判断是否继续执行循环体,因此适用于需要至少执行一次计算过程的四则运算。

三、C语言实现四则运算利用上述介绍的C语言循环结构,可以方便地实现计算机的四则运算。

下面将分别介绍如何利用循环结构实现加法、减法、乘法和除法运算,并给出相应的代码实现。

1. 加法运算加法运算是最基本的四则运算之一,其实现可以利用C语言的循环结构来实现。

下面是利用for循环实现加法运算的示例代码:```c#include <stdio.h>int m本人n(){int a = 3;int b = 5;int sum = 0;for (int i = 0; i < b; i++){sum++;}printf("d + d = d\n", a, b, sum);return 0;}```在这段代码中,利用for循环结构对变量sum进行了累加操作,从而实现了加法运算。

编译原理LL1语法分析算法的实现(token转四元式)

编译原理LL1语法分析算法的实现(token转四元式)

编译原理LL1语法分析算法的实现(token转四元式)编译原理LL1语法分析算法的实现(token转四元式)博客分类:•c++/数据结构/算法算法F#J##include <stdio.h>#include <stack>#include <vector>#include <iostream>#include <fstream>#include <malloc.h>using namespace std;//token结构struct token {int code; //token的类别,code为1则是符号,为2则是数字char value; //token的值};typedef struct token tokens;vector<tokens> tokenBuffer; //用于存储token的缓冲区stack<tokens> tokenBuffers;//产生式结构struct formula {int id; //产生式编号char left; //产生式左部char right[256]; //产生式右部int r_length; //产生式右部长度};typedef struct formula formulas;formulas formulaBuffer[11]; //用于存储产生式的缓冲区//四元式结构struct expression {char symbol; //操作符char num1; //第一个操作数char num2; //第二个操作数char result; //结果变量};typedef struct expression expressions;vector<expressions> expressionBuffer; //用于存储四元式的缓冲区int expressionCount = 0; //四元式个数//分析表中每一项的结构struct analysisTable {char currentState; //分析栈的栈顶符号char currentToken; //当前字符int expressionNum; //对应的产生式编号};typedef struct analysisTable analysisT ables;vector<analysisTables> analysisTableBuffer; //LL1分析表的缓冲区stack<char> analysisStack; //分析栈stack<char> sematicStack; //语义栈//初始化LL1分析表void initialAnalysisTableBuffer() { analysisTables* temp1a = new analysisTable; analysisTables* temp1b = new analysisTable; analysisTables* temp1c = new analysisTable; analysisTables* temp2 = new analysisTable; analysisTables* temp3 = new analysisTable; analysisTables* temp4 = new analysisTable; analysisTables* temp5 = new analysisTable; analysisTables* temp6 = new analysisTable; analysisTables* temp7a = new analysisTable; analysisTables* temp7b = new analysisTable; analysisTables* temp7c = new analysisTable; analysisTables* temp8 = new analysisTable; analysisTables* temp9 = new analysisTable; analysisTables* temp10 = new analysisTable; analysisTables* temp11 = new analysisTable; analysisTables* temp12 = new analysisTable; analysisTables* temp13 = new analysisTable; analysisTables* temp14 = new analysisTable; analysisTables* temp15a = new analysisTable; analysisTables* temp15b = new analysisTable; analysisTables* temp15c = new analysisTable; analysisTables* temp16 = new analysisTable;temp1a->expressionNum = 1;temp1a->currentState = 'E';temp1a->currentT oken = 'a';temp1b->expressionNum = 1; temp1b->currentState = 'E'; temp1b->currentT oken = 'b';temp1c->expressionNum = 1; temp1c->currentState = 'E'; temp1c->currentT oken = 'c';temp2->expressionNum = 1; temp2->currentState = 'E'; temp2->currentToken = '(';temp3->expressionNum = 2; temp3->currentState = 'L'; temp3->currentToken = '+';temp4->expressionNum = 3; temp4->currentState = 'L'; temp4->currentToken = '-';temp5->expressionNum = 4; temp5->currentState = 'L'; temp5->currentToken = ')';temp6->expressionNum = 4; temp6->currentState = 'L'; temp6->currentToken = '#';temp7a->expressionNum = 5;temp7a->currentT oken = 'a';temp7b->expressionNum = 5; temp7b->currentState = 'T'; temp7b->currentT oken = 'b';temp7c->expressionNum = 5; temp7c->currentState = 'T'; temp7c->currentT oken = 'c';temp8->expressionNum = 5; temp8->currentState = 'T'; temp8->currentToken = '(';temp9->expressionNum = 8; temp9->currentState = 'M'; temp9->currentToken = '+';temp10->expressionNum = 8; temp10->currentState = 'M'; temp10->currentT oken = '-';temp11->expressionNum = 6; temp11->currentState = 'M'; temp11->currentT oken = '*';temp12->expressionNum = 7;temp12->currentT oken = '/';temp13->expressionNum = 8;temp13->currentState = 'M';temp13->currentT oken = ')';temp14->expressionNum = 8;temp14->currentState = 'M';temp14->currentT oken = '#';temp15a->expressionNum = 9;temp15a->currentState = 'F';temp15a->currentToken = 'a';temp15b->expressionNum = 9;temp15b->currentState = 'F';temp15b->currentToken = 'b';temp15c->expressionNum = 9;temp15c->currentState = 'F';temp15c->currentToken = 'c';temp16->expressionNum = 10;temp16->currentState = 'F';temp16->currentT oken = '(';analysisTableBuffer.push_back(*temp1a); analysisTableBuffer.push_back(*temp1b); analysisTableBuffer.push_back(*temp1c);analysisTableBuffer.push_back(*temp2);analysisTableBuffer.push_back(*temp3);analysisTableBuffer.push_back(*temp4);analysisTableBuffer.push_back(*temp5);analysisTableBuffer.push_back(*temp6);analysisTableBuffer.push_back(*temp7a);analysisTableBuffer.push_back(*temp7b);analysisTableBuffer.push_back(*temp7c);analysisTableBuffer.push_back(*temp8);analysisTableBuffer.push_back(*temp9);analysisTableBuffer.push_back(*temp10);analysisTableBuffer.push_back(*temp11);analysisTableBuffer.push_back(*temp12);analysisTableBuffer.push_back(*temp13);analysisTableBuffer.push_back(*temp14);analysisTableBuffer.push_back(*temp15a);analysisTableBuffer.push_back(*temp15b);analysisTableBuffer.push_back(*temp15c);analysisTableBuffer.push_back(*temp16);}//由于本次实验主要是考察语法分析和语义分析,所以为了节省时间不采用查表的方式获取token,而是直接初始化token的值。

编译原理课程设计-翻译成四元式

编译原理课程设计-翻译成四元式

编译原理课程设计一、课程设计题目:第(20)题:写一程序,演示对给定下标变量赋值语句文法,且已知建立内情向量,对给定的下标变量赋值语句翻译成四元式。

二、编程环境:在Turboc下编程运行,可随意输入数组维数,对输入的给定下标变量赋值语句翻译成四元式。

三、设计原理:一个含数组元素的赋值语句的文法模式可为下所示:A->V:=E V->i[elist]|i elist->elist,E|E E->E+E|(E)|V 即一个赋值语句A是一个V(指变量)后跟赋值号:=和一个算术表达式E。

为了计算数组元素的VARPART,需要把关于变量V的文法改写成:V->elist]|i elist->elist,E|i[E 把数组名i和最左的下标式写在一起的目的是使在整个下标串elist的翻译过程中随时都能知道数组名i的符号表入口,从而随时能够了解登记在符号表中的有关数i的全部信息。

为了计算VARPART的四元式序列,需要知道数组名的符号表入口,下标式的个数,将VARPART的中间结果单元名字在符号表中的位置等。

还要根据含有数组元素的赋值句的翻译规则进行翻译。

四、设计过程:数组元素a[i1,i2,…,in]地址D的计算公式为: D=CONSPART+VARPARTCONSPART=a-c ,其中c是常数(d2d3…dn+d3…dn+…+dn+1).由题目已知建立了内情向量表,但是为了方便起见还是要输入数组的维数以及是几乘几的数组。

为了计算常数c编了一个专门的函数Conspart(int a[],DIM);其核心是:for(j=1;j<DIM;j++)c=c*a[j]+1;为了将四元式的计算VARPART 的过程演示出来,知道其值为(i1d2d3…dn +i2d3d4…dn+…+in-1dn+in),即可通过一个循环来计算VARPART的值,如下VARPART:=VARPART*dk+1+ik+1因此也可通过循环来演示计算四元式VARPART的过程。

编译原理课程设计报告-简单文法的编译器的设计与实现

编译原理课程设计报告-简单文法的编译器的设计与实现

提供全套毕业论文,各专业都有课程设计报告设计题目:简单文法的编译器的设计与实现班级:计算机1206组长学号:20123966组长姓名:指导教师:设计时间:2014年12月摘要编译原理是计算机科学与技术专业一门重要的专业课, 它具有很强的理论性与实践性,目的是系统地向学生介绍编译系统的结构、工作原理以及编译程序各组成部分的设计原理和实现技术,在计算机本科教学中占有十分重要的地位。

计算机语言之所以能由单一的机器语言发展到现今的数千种高级语言,就是因为有了编译技术。

编译技术是计算机科学中发展得最迅速、最成熟的一个分支,它集中体现了计算机发展的成果与精华。

本课设是词法分析、语法分析、语义分析的综合,外加上扩展任务中间代码的优化和目标代码的生成,主要是锻炼学生的逻辑思维能力,进一步理解编译原理的方法和步骤。

关键词:编译原理,前端,目标代码,后端目录摘要 (3)1. 概述 (6)2. 课程设计任务及要求 (8)2.1 设计任务 (8)2.2 设计要求 (9)3. 算法及数据结构 (10)3.1算法的总体思想 (10)3.2 词法分析器模块 (11)3.2.1 功能 (11)3.2.2 数据结构 (11)3.2.3 算法 (12)3.3 语法分析器模块 (13)3.3.1功能 (13)3.3.2 数据结构 (13)3.3.3算法 (14)3.4 中间代码产生器模块 (24)3.4.1 功能 (24)3.4.2 数据结构 (24)3.4.3 算法 (25)3.5 优化器模块 (27)3.5.1 功能 (27)3.5.2 数据结构 (27)3.5.3 算法 (28)3.6 目标代码生成器模块 (30)3.6.1功能 (30)3.6.2 数据结构 (30)3.6.3 算法 (31)4. 程序设计与实现 (32)4.1 程序流程图 (32)4.2 程序说明 (33)4.3 实验结果 (35)5. 结论 (42)6. 参考文献 (43)7. 收获、体会和建议 (44)1 概述在计算机上执行一个高级语言程序一般要分为两步;第一步,用一个编译程序把高级语言翻译成机器语言程序;第二步,运行所得的机器语言程序求得计算结果。

编译原理四元式

编译原理四元式

编译原理四元式四元式是编译原理中重要的一个概念,它能将程序代码转化为一种中间语言,方便程序的执行和优化。

四元式是指由四个元素构成的序列,它们包括操作符、操作数1、操作数2和结果。

四元式的生成可以使用抽象语法树或者中间代码生成技术。

四元式的格式通常如下:(操作符,操作数1,操作数2,结果)其中,操作符表示进行的操作,比如加减乘除等;操作数1和操作数2是运算符需要的参数;结果是运算的结果或者是存储运算结果的地址。

四元式有许多应用,包括代码优化、语言翻译、解释器等。

在代码优化中,四元式被用来表示程序的行为,我们可以通过分析这些四元式,来确定程序中的热点等重要信息。

在语言翻译中,四元式被用来把源代码翻译成目标代码,这样更容易实现跨平台等要求。

在解释器中,四元式被用来执行代码,解释器负责读取四元式,并根据操作符执行相应的操作。

四元式的生成通常是编译器中的中间代码生成过程的一部分。

在编译过程中,语法分析器读取输入验证是否符合语言规范,然后创建抽象语法树(AST)来表示输入程序结构。

接着,中间代码生成器将抽象语法树转换为一连串四元式,利用其中间代码的优化进行进一步分析和优化。

最后,代码生成器将四元式转换为机器可执行的代码。

四元式的例子将有助于我们理解其应用。

考虑以下C语言代码:```if (a > 0) {b = a + 1;} else {b = a - 1;}```转换为四元式后,它看起来像这样:```(>, a, 0, label1)(+, a, 1, t1)goto label2(label1, _, _, _)(-, a, 1, t1)(label2, _, _, _)(=, t1, _, b)```这里的第一个四元式是比较运算,如果a>0,则跳转到Label1,否则跳转到Label2。

第二个四元式是加法操作a+1,并保存到t1,在跳转之前会执行这个操作。

第三个四元式是跳转到Label2,如果跳转到了Label1,则执行第四个四元式,否则执行第五个四元式。

WHILE循环语句的翻译程序设计(简单优先法、输出四元式)

WHILE循环语句的翻译程序设计(简单优先法、输出四元式)

WHILE循环语句的翻译程序设计(简单优先法、输出四元式)1 需求说明或问题描述1.1 问题描述对C++中while循环语句的理解及分析,通过编译中的词法分析、语法分析、语义分析及中间代码生成等编译过程,用简单优先分析法分析并翻译while语句。

1.2 需求说明1 写出符合给定的语法分析方法的文法及属性文法2 完成题目要求的中间代码四元式的描述3 写出给定的语法分析方法的思想,完成语法分析及语义分析程序设计4 设计若干用例,上机通过测试2 文法及语法设计2.1文法及属性文法:文法G=(V N ,V T ,P ,S)其中V N={S , B, E, C, A, B, P, T} V T={w, (, ), { ,}, i, ;}P={S -> w(B){E}E -> CC -> CAC -> AA -> iPAA -> i;P -> +|-|*|/B -> iTiB-> iT -> >|<|>=|<=|==}2.2 语法分析方法描述及语法分析表设计2.2.1 语法分析方法描述:简单优先分析法是按照文法符号(终极符和非终极符)的优先关系确定句柄的。

基本思想可设计如下,首先根据已知优先文法构造相应优先关系矩阵,并将文法的产生式保存,设置符号栈S,步骤如下:(1)将输入符号串a1a2…a n#依次逐个存入符号栈S中,直到遇到栈顶符号a i的优先性>下一个待输入符号a j为止。

(2)栈顶当前符号a i为句柄尾,由此向左在栈中找句柄的头符号a k,即找到a k-1<a k为止。

(3)由句柄a k...a i在文法的产生式中查找右部为a k…a i的产生式,若找到则用相应左部代替句柄,若找不到则为出错,这时可断定输入串不是该文法的句子。

(4)重复上述(1)、(2)、(3)步骤直到规约完输入符号串,栈中只剩文法的开始符号为止。

编译原理报告三四元式参考模板

编译原理报告三四元式参考模板

四元式生成一、目的和要求1、目的通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法范畴变换为某种中间代码的语义翻译方法。

2、要求(1)选用目前世界上普遍采用的语义分析方法──语法制导翻译技术。

(2)语义分析对象重点考虑经过语法分析后已是正确的语法范畴,实习重点是语义子程序。

(3)中间代码选用比较常见的形式,例如四元式。

二、背景知识属性文法:A=(G,V,F),其中:G:一个CFG, 属性文法的基础。

V:有穷的属性集:每个属性与一个文法符号相关联,这些属性代表与文法符号相关的语义信息,如:类型、地址、值、代码、符号表内容等等。

属性与变量一样,可以进行计算和传递,属性加工的过程即是语义处理的过程。

属性加工与语法分析同时进行。

属性的表示:标始符(或数),写在相应文法的下边,点记法:E.Val,E.Place,E.Type…。

F:关于属性的属性断言或一组属性的计算规则(称为语义规则)。

断言或语义规则与一个产生式相联,只引用该产生式左端或右端的终结符或非终结符相联的属性。

属性有两类:综合属性:归约型属性,用于“自下而上”传递信息。

继承属性:推导型属性,用于“自上而下”传递信息。

综合属性的例子:非终结符E、T及F都有一个综合属性val,符号digit有一个综合属性,它的值由词法分析器提供。

与产生式L→E对应的语义规则仅仅是打印由E产生的算术表达式的值的一个过程,我们可认为这条规则定义了L的一个虚属性。

某些非终结符加上标是为了区分一个产生式中同一非终结符多次出现。

设表达式为3*5+4,则语义动作打印数值19。

L-属性文法:一个属性文法称为L-属性文法,如果对于每个产生式A→X1X2…Xn,满足:1、Xj(1≤j≤n)的继承属性仅依赖于下述属性值中的一种:A的继承属性或产生式右部位v于Xj左边的符号X1,X2,…,Xj-1的属性。

2、A的综合属性,仅依赖于下述属性值中的一种:A的继承属性或产生式右部符号Xj (除自身外)的任意属性。

编译原理-语法分析生成四元式

编译原理-语法分析生成四元式

学号1406410107 成绩编译原理上机报告名称:语法分析生成四元式学院:信息与控制工程学院专业:计算机科学与技术班级:计算机1401班*名:***2016年11月11日一、上机目的(a)根据算符优先分析算法,编写一个分析对象的语法分析程序。

读者可根据自己的能力选择以下三项(由易到难)之一作为分析算法中的输入:Ⅰ:通过构造算符优先关系表,设计编制并调试一个算法优先分析程序Ⅱ:输入FIRSTVT,LASTVT集合,由程序自动生成该文法的算符优先关系矩阵。

Ⅲ:输入已知文法,由程序自动生成该文法的算符优先关系矩阵。

(b)程序具有通用性,即所编制的语法分析程序能够使用于不同文法以及各种输入单词串,并能判断该文法是否为算符文法和算符优先文法。

(c)有运行实例。

对于输入的一个文法和一个单词串,所编制的语法分析程序应能正确地判断,此单词串是否为该文法的句子,并要求输出分析过程。

二、基本原理和上机步骤1.借用实验二的结果,可将其中的取字符函数几乎原封不动地移植过来,其中的分割和分析单词的方法可借用过来分割现在这个实验的运算符、常量和变量。

2.模块结构:(1)初始化:设立算符优先关系表(或优先函数)、初始化变量空间(包括堆栈、结构体、数组、临时变量等);(2)控制部分:将一个表达式从文件中读出;(3)词法分析:将表达式分割成单词序列;(4)利用算符优先文法进行表达式处理:根据算符优先关系表(或优先函数)对表达式单词序列进行堆栈(或其他)操作,得到并保存四元组,如果遇到错误则显示错误信息;(5)输出四元组。

三、上机结果程序清单:#include<stdio.h>#include<stdlib.h>#define MAX 100void SET_Mul_Div(int i,int m);void SET_Add_Sub(int j,int m);void print();int m=0;int count=0;char tempvar='A';int temp;char string[MAX]; //用于存放表达式int main() {i nt p[MAX];c har ch;i nt c=-1,q=0;p rintf("请输入赋值语句:\n");w hile((ch = getchar())!='\n') {string[m++]=ch;if(ch=='='||ch=='+'||ch=='-'||ch=='*'||ch=='/')count++;else if(ch=='(') {p[++c]=m-1; }else if(ch==')'){q=m-1;SET_Mul_Div(p[c],q); //从左括号处理到又括号SET_Add_Sub(p[c],q);temp=(int)tempvar-1;tempvar=(char)temp;string[p[c]]=string[m-1]=tempvar;c--;temp=(int)tempvar+1;tempvar=(char)temp; }}/********调用生成四元式的函数********/p rint();/*********判断是否成功**********/i f(count==0)printf("Successful!\n");e lseprintf("Wrong!");p rintf("\n");s ystem("pause");}void SET_Mul_Div(int i,int m) //处理乘除运算{for(i++;i<=m-1;i++){i f(string[i]=='*'||string[i]=='/') {printf("(%c %c %c %c)\n",string[i],string[i-1],string[i+1], tempvar);string[i-1]=string[i]=string[i+1]=tempvar;count--;temp=(int)tempvar+1;tempvar=(char)temp;}}}void SET_Add_Sub(int j,int m) //处理加减运算{j++;for(;j<=m-1;j++){i f(string[j]=='+'||string[j]=='-') {printf("(%c %c %c %c)\n",string[j],string[j-1],string[j+1],tempvar);string[j-1]=string[j]=string[j+1]=tempvar;count--;temp=(int)tempvar+1;tempvar=(char)temp; }}}/*打印*/void print(){i nt i;f or(i=0;i<=m-1;i++)//处理乘除运算{if(string[i]=='*'||string[i]=='/'){printf("(%c %c %c %c)\n",string[i],string[i-1],string[i+1],tempvar);string[i-1]=string[i]=string[i+1]=tempvar;count--;temp=(int)tempvar+1;tempvar=(char)temp;}}i nt j;f or(j=0;j<=m-1;j++)//处理加减运算{if(string[j]=='+'||string[j]=='-'){printf("(%c %c %c %c)\n",string[j],string[j-1],string[j+1],tempvar);string[j-1]=string[j]=string[j+1]=tempvar;count--;temp=(int)tempvar+1;tempvar=(char)temp;}}i nt k;f or(k=0;k<=m-1;k++) //处理赋值运算{if(string[k]=='='){temp=(int)tempvar--;tempvar=(char)temp;printf("(%c %c %c) \n",string[k],string[k+1], string[k-1],tempvar);count--;string[k-1]=tempvar; }}}屏幕截图:四、讨论与分析通过本次实验我完成生成四元式的语法分析程序,掌握的结合语法分析实现翻译方案的思路和方法。

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

计算机与信息学院操作系统与编译原理联合课程设计报告》专题:编译原理部分学生姓名:学号:专业班级:指导教师:2014 年7 月一、设计目标设计一个语法制导翻译器,将算术表达式、for 语句、while 语句翻译成四元式。

要求先确定一个定义算术表达式、for 语句、while 语句的文法,为其设计一个语法分析程序,为每条产生式配备一个语义子程序,按照一遍扫描的语法制导翻译方法,实现翻译程序。

对用户输入的任意一个正确的表达式,程序将其转换成四元式输出。

二、设计思路开发平台:Visual C++ MFC 解决这个问题的方案分为以下几个步骤:1. 将算数表达式、for 语句、while 语句转换为四元式的第一步为对读入的表达式进行处理,即删除不必要的空格、回车、换行等,保证之后的步骤能够顺利进行。

2. 分析算术表达式、for 语句、while 语句的文法。

3. 通过词法分析判断语句中的每个字符的类型,如:数字、字母、符号等。

4. 建立每种文法的LR(0) 分析表,通过每个文法的LR(0) 分析表对相应的表达式进行语法分析。

5. 在语法分析正确的情况下,通过语法分析的中间过程的符号栈输出四元式,四元式的形式为:( op arg1 arg2 result )。

(一)算术表达式转换为四元式将算术表达式转换为四元式首先考虑了括号的问题,对于不同的算术表达式第一步进行词法分析,即确定各种符号的位置。

而括号中的式子是优先级最高的,应该最先进行处理。

我使用了一个数组记录算术表达式中括号的位置,并且定义了first_cc 和first_jj 函数对括号内的乘除法和加减法分别进行处理。

后将括号内的式子以四元式的形式输出。

通过以上转换,已将原算术表达式中的括号中的内容使用大写字母' A'、' B'⋯⋯等代替(其中定义声明了change 函数,用来将括号部分替换为大写字母)。

新的式子中,只含有加减乘除以及赋值这四种运算,后根据优先级的不同,逐步生成四元式。

其算法流程图如右图所示。

(二)for 语句转换为四元式1. For 语句的文法如下:S-> f ( E ; F ; G ){ H ;}S-> f ( E ; X ; Y ){ H ;}E-> id = cF-> id < cG-> id + +X-> id > cY-> id ––3. 基本算法流程:本算法定义声明了两个结构体:一个是Node 结构体,其中 char 型的 type 中存储当前符号的类型, CString 型的 sValue 中存储的为当前符号, int 型的 eValue 只有在符号类型 为数字的情况下才进行存储, 存储数字的大小; 另一个为 stack 结构体, 这个结构体是实现H-> id H-> H-> 其中id id= id 1= id 1232 + id 32+ = c+ id 表示常数 达式一般为算术表达式, 虑比较简单的情况。

2.for 语句的 LR(0) 分析表如下:const ,f 表示关键字 for , id 表示一般标识符。

for 循环体内部的表 而算术表达式转换为四元式的方法在第一部分已给出, 此处 H 只考语法分析中的符号栈和状态栈使用的,并未这两个栈分别定义了各自的pop 函数和push 函数。

除此之外,本算法中的LR(0) 分析表通过二维数组存储。

其中分为action 表和goto 表。

action 表中的状态转换符号,用2-44 表示,规约的符号,用101-110 表示。

三) while 语句转换为四元式1. while 语句的文法如下:(1) S->while(B){E}(2) E->AE(3) E->A(4) A->iPA(5) A->i(6) B->iTi(7) B->i其中while 、( 、) 、{、}、P、T 、;和i 均为终结符,而S、A、B、E 这些大写字母均为非终结符。

T 表示比较运算符,P 表示算术运算符,i 表示合法标识符。

2. While 语句的LR(0) 分析表如下:3. 基本算法流程:本算法的基本思想与for 语句转换成四元式的思想比较相似,都是对读入的语句进行词法分析,后再通过LR(0) 分析表对语句进行语法分析,并同时输出四元式。

与for 语句转换成四元式不同的是,while 语句转换为四元式在结构体定义等方面做了改进。

首先是LR(0) 分析表的存储方式进行了改进,本算法中为LR(0) 分析表定义了一个table 的结构体,将action 和goto 两个部分全部存入table 的结构体中,是查表的时候更加方便。

除此之外,还定义了obj 结构体,此结构体主要是为了存储所要输出的四元式,定义了此结构体之后,程序的调理变得更为清晰了。

本算法中符号栈以及状态栈的部分主要调用了c++中原有的stack 结构体,使用其本身定义的pop函数以及push 函数,简化的代码。

以下为算法的流程图:(四)输入、输出以及界面设计1. 输入:本程序的输入均为语句或表达式,若每次测试程序均输入表达式,则会输入大量式子,浪费时间。

所以本程序采用文件读入的形式,只需要在指定位置输入文件名即可。

2. 输出:本程序输出的四元式全部在MFC界面的文本框中显示。

可以复制,方便之后的使用。

3. 界面设计:本程序为了方便使用以及界面美观,使用了MFC中的TabControl 控件,界面设计如下:图中当前标签为“ while 语句”,显示的界面为“ while 语句转换为四元式”。

通过若点击其他标签按钮,界面也会切换到相应的界面。

每个界面都是一个对话框,如下图所示:(2)后在CompilerDesignDlg.h 文件中添加每个对话框的头文件,以及申明每个对话框,代码如下:#include "Dlg1.h"#include "Dlg2.h"#include "Dlg3.h"CDlg1 page1;CDlg2 page2;CDlg3 page3;(3)在初始化函数CCompilerDesignDlg::OnInitDialog()中编写相关代码:m_tabCtrl.InsertItem(0, " 算术表达式");( 1)CompilerDesignDlg.cpp 作为主要的文件,去调用其他的对话框。

首先对每一个对话框( IDD DIALOG1-3)进行设置,样式:下层;边框:无。

如下图所示:m_tabCtrl.InsertItem(1, "for 语句");m_tabCtrl.InsertItem(2, "while 语句");page1.Create(IDD_DIALOG1, &m_tabCtrl);page2.Create(IDD_DIALOG2, &m_tabCtrl);page3.Create(IDD_DIALOG3, &m_tabCtrl);CRect rc;m_tabCtrl.GetClientRect(&rc);rc.top += 22;rc.bottom -= 3;rc.left += 2;rc.right -= 3;// 设置子对话框尺寸并移动到指定位置page1.MoveWindow(&rc);page2.MoveWindow(&rc);page3.MoveWindow(&rc);page1.ShowWindow(true);page2.ShowWindow(false);page3.ShowWindow(false);m_tabCtrl.SetCurSel(0);(4)填写按钮响应函数,即实现点击按钮切换到相应界面的功能,双击Tab控件,创建函数,函数内代码实现如下:void CCompilerDesignDlg::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult){int CurSel = m_tabCtrl.GetCurSel();switch (CurSel){case 0:page1.ShowWindow(true);page2.ShowWindow(false);page3.ShowWindow(false);break;case 1:page1.ShowWindow(false);page2.ShowWindow(true);page3.ShowWindow(false);break;case 2:page1.ShowWindow(false);page2.ShowWindow(false);page3.ShowWindow(true);break;}*pResult = 0;}三、核心代码(一)算术表达式转化为四元式1. first_cc 函数:对括号中的乘除法进行处理。

void CDlg1::first_cc(int i, int m){i++;for (; i <= m - 1; i++)// 处理乘除运算{if (str[i] == '*' || str[i] == '/'){CString str00;CString strget;GetDlgItemText(IDC_OUT, strget);CString str01 = str[i];CString str02 = str[i - 1];CString str03 = str[i + 1];CString str04 = JG;str00 = str0 + str01 + str1 + str02 + str1 + str03 + str1 + str04 + str2;SetDlgItemText(IDC_OUT, strget + str00);change(i - 1);str[i - 1] = str[i] = str[i + 1] = JG;sum--;JG = (char)(int)JG++;}}}2. first_jj 函数:对括号内的加减法进行处理。

void CDlg1::first_jj(int j, int m){j++;for (; j <= m - 1; j++)// 处理加减运算{if (str[j] == '+' || str[j] == '-'){CString str00;CString strget;GetDlgItemText(IDC_OUT, strget);CString str01 = str[j];CString str02 = str[j - 1];CString str03 = str[j + 1];CString str04 = JG;str00 = str0 + str01 + str1 + str02 + str1 + str03 + str1 + str04 + str2;SetDlgItemText(IDC_OUT, strget + str00);change(j - 1);str[j - 1] = str[j] = str[j + 1] = JG;sum--;JG = (char)(int)JG++;}}}3. scan 函数:用于从文件中读入表达式,并处理空格、回车、换行等。

相关文档
最新文档