编译原理-逆波兰式的产生及计算 联系客服

发布时间 : 星期一 文章编译原理-逆波兰式的产生及计算更新完毕开始阅读8cbadb70393567ec102de2bd960590c69fc3d84d

学号

Word 资料

.

1406410107 成绩

编译原理上机报告

名 称: 逆波兰式的产生及计算 学 院: 信息与控制工程学院 专 业: 计算机科学与技术 班 级: 计算机1401班 姓

名: 叶达成

2016年 11月 4日

.

一、上机目的

通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。

1、选择最有代表性的语法分析方法,如LL(1) 语法分析程序、算符优先分析程序和LR分析分析程序,并至少完成两个题目。

2、选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。

⑴ 实验前的准备

按实验的目的和要求,编写语法分析程序,同时考虑相应的数据结构。 ⑵ 调试

调试例子应包括符合语法规则的算术表达式,以及分析程序能够判别的若干错例。 ⑶ 输出

对于所输入的算术表达式,不论对错,都应有明确的信息告诉外界。 ⑷ 扩充

有余力的同学,可适当扩大分析对象。譬如:

① 算术表达式中变量名可以是一般标识符,还可含一般常数、数组元素、函数调用等等。 ② 除算术表达式外,还可扩充分析布尔、字符、位等不同类型的各种表达式。③加强语法检查,尽量多和确切地指出各种错误。

二、基本原理和上机步骤 基本原理:

将运算对象写在前面,而把运算符号写在后面。用这种表示法表示的表达式也称做后缀式。逆波兰式的特点在于运算对象顺序不变,运算符号位置反映运算顺序。采用逆波兰式可以很好的表示简单算术表达式,其优点在于易于计算机处理表达式。

上机步骤:

(1)构造一个栈,存放运算对象。

(2)读入一个用逆波兰式表示的简单算术表达式。

(3)自左至右扫描该简单算术表达式并判断该字符,如果该字符是运算对象,则将该字符入栈。若是运算符,如果此运算符是二目运算符,则将对栈顶部的两个运算对象进行该运算,将运算结果入栈,并且将执行该运算的两个运算对象从栈顶弹出。如果该字符是一目运算符,则对栈顶部的元素实施该运算,将该栈顶部的元素弹出,将运算结果入栈。

(4)重复上述操作直至扫描完整个简单算术表达式的逆波兰式,确定所有字符都得到正确处理,我们便可以求出该简单算术表达式的值。

三、上机结果 程序清单:

#include #include

Word 资料

.

#include #include #include #include using namespace std;

char str[50]; int top;

char stack[50]; char ex[50]; int flag[50];

//生成逆波兰式 void NiBolan() {

memset(flag,0,sizeof(flag)); //flag初始值设为0 char ch=str[0]; int i=1,t=0; top=0;

while(ch!='#') {

switch(ch) { case '(': top++; stack[top]=ch; break; case ')':

while(stack[top]!='(') {

ex[t]=stack[top]; top--; t++; } top--; break; case '^':

while(stack[top]=='^') //设置^运算符优先级为最高 {

ex[t]=stack[top]; top--; t++;

//用于存放原来的表达式 //栈顶指针

//定义栈,用于计算逆波兰式 //定义栈,用于计算逆波兰式子 //存放后缀表达式

//用于区分+、-号的含义,0表示运算符,1表示正负号

double _stack[50];

Word 资料

.

} top++; stack[top]=ch; break; case '+': case '-':

//当ch为+、-号是,若前面相邻字符不是')'或数字且后面相邻字符是数字时表示正负号 if(isdigit(str[i]) && !isdigit(str[i-2]) && str[i-2]!=')') {

flag[t]=1; ex[t++]=ch; ch=str[i++];

while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||ch=='.'||ch=='+') //判别小数点

{

ex[t]=ch; t++; ch=str[i]; i++; } i--; ex[t]='&'; t++;} else

{ while(top!=0&&stack[top]!='('){ ex[t]=stack[top]; top--; t++;} top++;

stack[top]=ch;} break; case '*': case '/':

while(stack[top]=='*'||stack[top]=='/'||stack[top]=='^') //运算符^优先级高于*和/

{

ex[t]=stack[top]; top--; t++; } top++; stack[top]=ch; break; case ' ': break; default:

//标记符号为正负号

Word 资料