算法表达式语法检查(数据结构课程设计)

合集下载

算术表达式的求解-数据结构课程设计报告

算术表达式的求解-数据结构课程设计报告

课程设计报告题目:算术表达式求值一、需求分析1、设计要求:给定一个算术表达式,通过程序求出最后的结果1>、从键盘输入要求解的算术表达式;2>、采用栈结构进行算术表达式的求解过程;3>、能够判断算术表达式正确与否;4>、对于错误表达式给出提示;5>、对于正确的表达式给出最后的结果;2、设计构想:为了实现算符优先算法使用两个工作栈,一个称作OPTR,以寄存运算符;另一个称作OPND,用以寄存操作数或运算结果。

在操作数和操作符入栈前,通过一个函数来判别,输入的是操作数还是操作符,操作数入OPND,操作符入OPTR。

在输入表达式的最后输入‘#’,设定‘#’的优先级最低,代表表达式输入结束。

在表达式输入过程中,遇操作数则直接入栈,遇到运算符则与栈顶运算符比较优先级,若当前运算符优先级高,则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符与新栈顶运算符。

如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。

二、概要设计1、本程序包含的模块:(1)栈模块——实现栈抽象数据类型(2)运算模块——实现数据表达式的运算(3)主程序模块三、详细设计(1)栈模块1、定义栈结构struct Sqstack{elemtype *top;//栈顶元素elemtype *base; //栈底元素int stacksize;//栈的大小};2、栈的基本操作①初始化栈status initstack(struct Sqstack &s){s.base=(elemtype *)malloc(stack_size*sizeof(elemtype)); if(!s.base)return OVERFLOW;s.top=s.base;s.stacksize=stack_size;return OK;}②入栈status push(struct Sqstack &s,elemtype e){if(s.top-s.base>=s.stacksize){s.base=(elemtype*)realloc(s.base,(s.stacksize+stack_increase ment)*sizeof(elemtype));if(!(s.base))return OVERFLOW;s.top=s.base+s.stacksize;s.stacksize+=stack_increasement;}* s.top++=e;return OK;}③出栈elemtype pop(struct Sqstack &s){elemtype e;if(s.top= =s.base)return ERROR;e=*--s.top;return e;}④取栈顶元素elemtype gettop(struct Sqstack &s){elemtype e;if(s.top==s.base)return ERROR;e=*(s.top-1);return e;}(2)运算模块1、判断输入字符c是否为操作符:若是,则返回1;否则,返回0int In(int c){char p[10]="+-*/()#^";int i=0;while(p[i]!='\0'){if(p[i]==c)return 1;i++;}return 0;}2、判断运算符的优先级char precede(char top,char c)//该函数为判断当前运算符与前一个运算符的优先级,前一个运算符高于或等于当前运算符的优先级则返回‘>’,前一个运算符小于当前运算符的优先级则返‘<’,当前一个运算符为‘(’当前运算符为‘)’时返回‘=’,用于去除表达式的括号。

算术表达式的求解-数据结构课程设计报告

算术表达式的求解-数据结构课程设计报告

算术表达式的求解-数据结构课程设计报告课程设计报告题目:算术表达式求值一、需求分析 1、设计要求:给定一个算术表达式,通过程序求出最后的结果 1>、从键盘输入要求解的算术表达式; 2>、采用栈结构进行算术表达式的求解过程; 3>、能够判断算术表达式正确与否;4>、对于错误表达式给出提示;5>、对于正确的表达式给出最后的结果; 2、设计构想:为了实现算符优先算法使用两个工作栈,一个称作OPTR,以寄存运算符;另一个称作OPND,用以寄存操作数或运算结果。

在操作数和操作符入栈前,通过一个函数来判别,输入的是操作数还是操作符,操作数入OPND,操作符入OPTR。

在输入表达式的最后输入‘#’,设定‘#’的优先级最低,代表表达式输入结束。

在表达式输入过程中,遇操作数则直接入栈,遇到运算符则与栈顶运算符比较优先级,若当前运算符优先级高,则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符与新栈顶运算符。

如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。

二、概要设计1、本程序包含的模块:栈模块——实现栈抽象数据类型运算模块——实现数据表达式的运算主程序模块算术运算式的求解栈模块主函数模块main 运算模块定义栈结构初始化栈出栈入栈取栈顶元素判断输入字符类型判断符号优先级基础运算函数运算函数三、详细设计栈模块1、定义栈结构 struct Sqstack{elemtype *top;//栈顶元素 elemtype *base; //栈底元素 int stacksize;//栈的大小 };2、栈的基本操作①初始化栈status initstack(struct Sqstack &s) {=(elemtype *)malloc(stack_size*sizeof(elemtype)); if(!) return OVERFLOW; =;=stack_size; return OK; } ②入栈status push(struct Sqstack &s,elemtype e) {if(>=) {=(elemtype*)realloc(,(+stack_increasement)*sizeof(elemtype));if(! ) return OVERFLOW; =+; +=stack_increasement; } * ++=e; return OK; } ③出栈elemtype pop(struct Sqstack &s) {elemtype e; if(= =) return ERROR; e=*--;return e; }④取栈顶元素elemtype gettop(struct Sqstack &s) {elemtype e; if(==) return ERROR; e=* ; return e; } 运算模块1、判断输入字符c是否为操作符:若是,则返回1;否则,返回0 int In(int c) {char p[10]=\ int i=0;while(p[i]!='\\0') {if(p[i]==c) return 1;i++; } return 0; }2、判断运算符的优先级char precede(char top,char c)//该函数为判断当前运算符与前一个运算符的优先级,前一个运算符高于或等于当前运算符的优先级则返回‘>’,前一个运算符小于当前运算符的优先级则返‘'; break; case '+': case '-':if(top=='#'||top=='(')result=''; break; case '*': case '/':if(top=='*'||top=='/'||top=='^') result='>'; elseresult=''; elseresult=''; break;case '(': result='': theta=pop(optr); b=pop(opnd); a=pop(opnd); push(opnd,operate(a,theta,b)); break;// 若当前操作符的优先级低于操作符栈的栈顶元素,则将操作符栈栈顶元素出栈,并将操作数栈的栈顶两个元素出栈,计算两个元素间以操作符栈栈顶元素为运算符的数学运算}//switch }//if}//whilereturn pop(opnd); }主程序模块1、main函数void main(int argc,char *argv) {struct Sqstack opnd; //操作数栈 struct Sqstack optr;//操作符栈initstack(opdn); initstack(optr); elemtype result;printf(\ printf(\算术运算式的求解\printf(\ printf(\请输入算术运算表达式(以'#'结尾):\\n\ printf(\result=evaluate(opnd,optr);printf(\printf(\运算的结果是 :\\n \\n%d\\n\printf(\}四、调试分析 1、测试结果1> 测试数据:3+7*2-1# 测试结果:2> 测试数据:(3+7)*2-1# 测试结果:3> 测试数据: 1/0# 测试结果:2、程序时间复杂度为O;3、设计中出现的问题:在开始的设计中没有注意除数不能为0 ,后来加入if(b==0) {printf(\分母为0,the result is error\\n\ result=0; } elseresult=a/b;break;来判断除数是否为0 4、算法改进:1>输入的操作数和操作码于是字符串类型的,在原设计中实现的操作都是对个位数实现的,实用性不大,故在后来的设计中,通过一个标志flag实现了标志操作数的连续输入的判别,继而实现了多位数的表达式运算2>开始只实现了加、减、乘、除及带小括号的数学运算,考虑到实用性,在后来的设计中引入pow函数,实现了乘方的运算,调整结果如下:3>最初设计的运行界面过于单调,不够友好,改进时加入一些*调整调整结果如下:五、课程设计总结本学期是我第一次接触课程设计,发现了很多学习上的问题,也有很多收获。

算术表达式的求解-数据结构课程设计报告

算术表达式的求解-数据结构课程设计报告

算术表达式的求解-数据结构课程设计报告数据结构》课程设计报告书题目:算术表达式的求解系别:计算机科学与应用数据结构课程设计目录一、需求分析1、设计要求:本程序需要实现对算术表达式的求解功能,可以支持基本的四则运算,包括加、减、乘、除,同时还需要支持括号的使用。

2、设计构想:我们将使用栈来实现算术表达式的求解。

具体地,我们将把中缀表达式转换为后缀表达式,然后再利用栈来求解后缀表达式。

二、概要设计1、本程序包含的模块:本程序包含两个模块:中缀表达式转后缀表达式模块和后缀表达式求解模块。

三、详细设计1、定义栈结构我们定义一个栈结构,用来存储算术表达式中的运算符和操作数。

具体地,栈中的每个元素都包含两个属性:元素的值和元素的类型。

元素的值可以是一个数字或一个运算符,元素的类型可以是数字或运算符。

我们使用一个数组来实现栈的结构。

为了方便起见,我们还需要定义一些基本的栈操作,如入栈、出栈、判断栈是否为空等。

2、栈的基本操作栈是一种常见的数据结构,具有后进先出(LIFO)的特点。

栈的基本操作包括初始化栈、入栈、出栈、取栈顶元素和运算模块。

1) 初始化栈初始化栈是指将栈的各项属性设置为初始状态。

通常包括将栈顶指针设为-1,表示栈为空。

2) 入栈入栈是指将元素压入栈顶。

入栈操作需要将栈顶指针加1,并将元素存入栈顶位置。

3) 出栈出栈是指将栈顶元素弹出。

出栈操作需要将栈顶元素取出,并将栈顶指针减1.4) 取栈顶元素取栈顶元素是指获取栈顶元素的值,但不将其弹出。

取栈顶元素操作只需要返回栈顶元素的值即可。

5) 运算模块栈可以用于实现各种运算,例如中缀表达式的转换和计算、括号匹配等。

运算模块需要根据具体需求进行设计和实现。

3、判断运算符的优先级在进行中缀表达式的转换和计算时,需要判断运算符的优先级。

通常采用栈来实现这一功能。

具体实现方法是将运算符入栈,当遇到新的运算符时,将其与栈顶运算符进行比较,如果新运算符的优先级高于栈顶运算符,则将其入栈,否则将栈顶运算符弹出并输出,直到新运算符可以入栈为止。

算法分析与设计数据结构实践课程设计

算法分析与设计数据结构实践课程设计

算法分析与设计数据结构实践课程设计1. 课程简介本课程旨在让学生了解算法分析与设计的基本概念,理解数据结构的各种操作原理和实现方式,掌握基础的算法设计技巧和算法分析方法,并实践运用所学知识解决实际问题。

2. 课程设计要求2.1 实践项目本课程设计要求学生设计一个实践项目,项目内容可以是任何与数据结构相关的实际问题。

同时,要求学生采用所学的算法分析与设计方法,设计和实现一个高效、正确、可靠的解决方案,并进行评估和测试。

2.2 项目报告学生需要撰写一份详细的项目报告,内容包括但不限于:•项目背景和问题描述•解决方案设计思路和方法•程序实现细节和代码结构说明•性能测试和评估结果分析•可能的改进和优化建议2.3 课程答辩学生需要在课程结束前,进行项目答辩。

答辩内容包括但不限于:•项目背景和问题描述•解决方案设计思路和方法•程序实现细节和代码结构说明•性能测试和评估结果分析•学生自己的总结和评估3. 简要算法分析与设计3.1 算法分析算法分析是评估一个算法效率的方法,通常使用时间复杂度和空间复杂度等指标来衡量。

时间复杂度表示算法的运行时间和问题规模之间的关系,空间复杂度表示算法需要占用的内存空间大小和问题规模之间的关系。

常见的算法分析方法包括递归求解、迭代求解和分治法等。

3.2 算法设计算法设计是指解决问题的过程中,构建一个高效、正确、可靠的计算机程序的方法。

通常使用问题建模、设计思维和常用算法等工具来完成。

常见的算法设计方法包括贪心算法、动态规划、分支界定法等。

同时,为了有效提高算法效率,通常需要采用数据结构等相关工具。

4. 数据结构简介数据结构是计算机科学中的重要基础,它是指将数据和相应的操作进行组织的方法。

数据结构可以分为线性结构和非线性结构,线性结构包括栈、队列和链表等,非线性结构包括树和图等。

数据结构的选择通常依据问题的特点和算法需求来考虑。

常见的数据结构包括数组、链表、栈、队列、树、图等。

5. 结语算法分析与设计和数据结构实践是计算机科学中的重要基础,它们与计算机科学的其他领域息息相关。

算术表达式的求解-数据结构课程设计报告

算术表达式的求解-数据结构课程设计报告

《数据结构》课程设计报告书题目:算术表达式的求解系别:计算机科学与应用目录一、需求分析 (3)1、设计要求: (3)2、设计构想: (3)二、概要设计 (4)1、本程序包含的模块: (4)三、详细设计 (4)1、定义栈结构 (5)2、栈的基本操作 (5)(1)初始化栈 (5)(2)入栈 (5)(3)出栈 (6)(4)取栈顶元素 (6)(5)运算模块 (6)3、判断运算符的优先级 (7)4、运算函数 (8)(1) 基础运算函数: (8)(2)运算函数 (9)(3)主程序模块 (12)四、调试分析 (12)1、测试结果 (12)2、程序时间复杂度为O(n); (13)3、设计中出现的问题: (13)4、算法改进: (14)五、课程设计总结 (15)课程设计报告一、需求分析1、设计要求:给定一个算术表达式,通过程序求出最后的结果1>、从键盘输入要求解的算术表达式;2>、采用栈结构进行算术表达式的求解过程;3>、能够判断算术表达式正确与否;4>、对于错误表达式给出提示;5>、对于正确的表达式给出最后的结果;2、设计构想:为了实现算符优先算法使用两个工作栈,一个称作OPTR,以寄存运算符;另一个称作OPND,用以寄存操作数或运算结果。

在操作数和操作符入栈前,通过一个函数来判别,输入的是操作数还是操作符,操作数入OPND,操作符入OPTR。

在输入表达式的最后输入‘#’,设定‘#’的优先级最低,代表表达式输入结束。

在表达式输入过程中,遇操作数则直接入栈,遇到运算符则与栈顶运算符比较优先级,若当前运算符优先级高,则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符与新栈顶运算符。

如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。

二、概要设计1、本程序包含的模块:(1)栈模块——实现栈抽象数据类型(2)运算模块——实现数据表达式的运算(3)主程序模块三、详细设计(1)栈模块1、定义栈结构struct Sqstack{int *top;//栈顶元素int *base; //栈底元素int stacksize;//栈的大小};2、栈的基本操作(1)初始化栈int initstack(struct Sqstack &s){s.base=(int *)malloc(stack_size*sizeof(int));if(!s.base)return OVERFLOW;s.top=s.base;s.stacksize=stack_size;return OK;}(2)入栈int push(struct Sqstack &s,int e){if(s.top-s.base>=s.stacksize){s.base=(int*)realloc(s.base,(s.stacksize+stack_increasement)*sizeof(int));if(!(s.base))return OVERFLOW;s.top=s.base+s.stacksize;s.stacksize+=stack_increasement;}* s.top++=e;return OK;}(3)出栈int pop(struct Sqstack &s){int e;if(s.top==s.base)return ERROR;e=*--s.top;return e;}(4)取栈顶元素int gettop(struct Sqstack &s){int e;if(s.top==s.base)return ERROR;e=*(s.top-1);return e;}(5)运算模块1、判断输入字符c是否为操作符:若是,则返回1;否则,返回0int In(int c){char p[10]="+-*/()#^";int i=0;while(p[i]!='\0'){if(p[i]==c)return 1;i++;}return 0;}3、判断运算符的优先级char precede(char top,char c)//该函数为判断当前运算符与前一个运算符的优先级,前一个运算符高于或等于当前运算符的优先级则返回'>',前一个运算符小于当前运算符的优先级则返'<',当前一个运算符为'('当前运算符为')'时返回'=',用于去除表达式的括号。

数据结构课程设计-表达式求值【完整版】

数据结构课程设计-表达式求值【完整版】

XXXXXX大学《数据结构》课程设计报告班级:学号:姓名:指导老师:目录一算术表达式求值一、需求分析二、程序得主要功能三、程序运行平台四、数据结构五、算法及时间复杂度六、测试用例七、程序源代码二感想体会与总结算术表达式求值一、需求分析一个算术表达式就是由操作数(operand)、运算符(operator)与界限符(delimiter)组成得。

假设操作数就是正整数,运算符只含加减乘除等四种运算符,界限符有左右括号与表达式起始、结束符“#”,如:#(7+15)*(23—28/4)#。

引入表达式起始、结束符就是为了方便.编程利用“算符优先法”求算术表达式得值.二、程序得主要功能(1)从键盘读入一个合法得算术表达式,输出正确得结果。

(2)显示输入序列与栈得变化过程。

三、程序运行平台Visual C++6、0版本四、数据结构本程序得数据结构为栈。

(1)运算符栈部分:struct SqStack //定义栈{char *base; //栈底指针char *top; //栈顶指针intstacksize; //栈得长度};intInitStack (SqStack &s) //建立一个空栈S{if (!(s、base= (char *)malloc(50*sizeof(char))))exit(0);s、top=s、base;s、stacksize=50;return OK;}char GetTop(SqStack s,char &e) //运算符取栈顶元素{if (s、top==s、base) //栈为空得时候返回ERROR{ﻩ printf("运算符栈为空!\n");ﻩ return ERROR;}elsee=*(s、top-1); //栈不为空得时候用e做返回值,返回S得栈顶元素,并返回OK returnOK;}int Push(SqStack&s,char e) //运算符入栈{if (s、top—s、base >= s、stacksize)ﻩ{printf("运算符栈满!\n");ﻩs、base=(char*)realloc(s、base,(s、stacksize+5)*sizeof(char));//栈满得时候,追加5个存储空间if(!s、base)exit (OVERFLOW);s、top=s、base+s、stacksize;s、stacksize+=5;}ﻩ*(s、top)++=e;//把e入栈ﻩreturn OK;}int Pop(SqStack &s,char &e) //运算符出栈{if (s、top==s、base) //栈为空栈得时候,返回ERROR{printf("运算符栈为空!\n”);ﻩ return ERROR;}else{ﻩﻩe=*-—s、top;//栈不为空得时候用e做返回值,删除S得栈顶元素,并返回OK return OK;}}int StackTraverse(SqStack&s)//运算符栈得遍历{ﻩchar *t;ﻩt=s、base;ﻩif (s、top==s、base){ﻩ printf(”运算符栈为空!\n”); //栈为空栈得时候返回ERRORreturn ERROR;}while(t!=s、top){ﻩﻩprintf(" %c",*t); //栈不为空得时候依次取出栈内元素t++;ﻩ}return ERROR;}(2)数字栈部分:struct SqStackn//定义数栈{int *base; //栈底指针int*top; //栈顶指针int stacksize; //栈得长度};intInitStackn (SqStackn &s) //建立一个空栈S{s、base=(int*)malloc(50*sizeof(int));if(!s、base)exit(OVERFLOW);//存储分配失败s、top=s、base;s、stacksize=50;return OK;}int GetTopn(SqStackn s,int&e) //数栈取栈顶元素{if(s、top==s、base){printf("运算数栈为空!\n");//栈为空得时候返回ERRORﻩ return ERROR;}elseﻩe=*(s、top-1);//栈不为空得时候,用e作返回值,返回S得栈顶元素,并返回OKreturnOK;}int Pushn(SqStackn &s,int e) //数栈入栈{if(s、top—s、base>=s、stacksize){ﻩﻩprintf("运算数栈满!\n");//栈满得时候,追加5个存储空间ﻩs、base=(int*)realloc (s、base,(s、stacksize+5)*sizeof(int));if(!s、base) exit (OVERFLOW);ﻩs、top=s、base+s、stacksize;//插入元素e为新得栈顶元素s、stacksize+=5;}*(s、top)++=e; //栈顶指针变化returnOK;}int Popn(SqStackn &s,int &e)//数栈出栈{ﻩif (s、top==s、base){ﻩ printf("运算符栈为空!\n");//栈为空栈得视时候,返回ERRORﻩ return ERROR;ﻩ}else{ﻩﻩe=*—-s、top;//栈不空得时候,则删除S得栈顶元素,用e返回其值,并返回OK ﻩreturnOK;}}int StackTraversen(SqStackn &s)//数栈遍历{ﻩint*t;ﻩt=s、base ;ﻩif(s、top==s、base)ﻩ{printf("运算数栈为空!\n”);//栈为空栈得时候返回ERRORﻩ return ERROR;ﻩ}ﻩwhile(t!=s、top)ﻩ{printf(” %d”,*t); //栈不为空得时候依次输出t++;}return ERROR;}五、算法及时间复杂度1、算法:建立两个不同类型得空栈,先把一个‘#’压入运算符栈。

数据结构课程设计四则运算表达式求值(C语言版)

数据结构课程设计四则运算表达式求值(C语言版)

数据结构课程设计四则运算表达式求值(C语⾔版) 明⼈不说暗话,直接上,输⼊提取码z3fy即可下载。

⽂件中包含程序,程序运⾏⽂件,设计报告和测试样例,应有尽有,欢迎⼩伙伴们在中下载使⽤。

本课程设计为四则运算表达式求值,⽤于带⼩括号的⼀定范围内正负数的四则运算标准(中缀)表达式的求值。

注意事项:1、请保证输⼊的四则表达式的合法性。

输⼊的中缀表达式中只能含有英⽂符号“+”、“-”、“*”、“/”、“(”、“)”、“=”、数字“0”到“9”以及⼩数点“.”,输⼊“=”表⽰输⼊结束。

例如9+(3-1)*3.567+10/2=,特别是请勿输⼊多余空格和中⽂左右括号。

2、输⼊的中缀表达式默认限定长度是1001,可根据具体情况调整字符串数组的长度。

3、请保证输⼊的操作数在double数据类型范围内,单个数字有效数字长度不可超过15位。

本课程设计中操作数是C语⾔中的双精度浮点数类型。

4、本课程设计中的运算数可以是负数,另外如果是正数可直接省略“+”号(也可带“+”号)。

 下⾯的程序正常运⾏需要在上⾯的百度⽹盘中下载相应⽂件,否则⽆法正常使⽤哦。

1/*本程序为四则运算表达式求值系统,⽤于计算带⼩括号的四则运算表达式求值。

2具体算法:3先将字符串处理成操作单元(操作数或操作符),再利⽤栈根据四则运算4的运算法则进⾏计算,最后得出结果。

*/56 #include<stdio.h>7 #include<ctype.h>8 #include<stdlib.h>9 #include<string.h>10 #include<stdlib.h>11 #include<ctype.h>1213const int Expmax_length = 1001;//表达式最⼤长度,可根据适当情况调整14struct Ope_unit15 {//定义操作单元16int flag;//=1表⽰是操作数 =0表⽰是操作符 -1表⽰符号单元17char oper;//操作符18double real;//操作数,为双精度浮点数19 };2021void Display();//菜单22void Instru(); //使⽤说明23int Check(char Exp_arry[]);24void Evalua(); //先调⽤Conver操作单元化,再调⽤Calculate函数计算结果并输出25int Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[]);//将字符串处理成操作单元26int Isoper(char ch);//判断合法字符(+ - * / ( ) =)27int Ope_Compar(char ope1,char ope2);//操作符运算优先级⽐较28double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag);//⽤栈计算表达式结果29double Four_arithm(double x,double y,char oper);//四则运算3031int main()32 {33int select;34while(1)35 {36 Display();37 printf("请输⼊欲执⾏功能对应的数字:");38 scanf("%d",&select);39 printf("\n");40switch(select)41 {42case1: Evalua(); break;43case2: Instru(); break;44case0: return0;45default : printf("⽆该数字对应的功能,请重新输⼊\n");46 system("pause");47 }48 }49return0;50 }5152int Check(char Exp_arry[])53 {//检查是否有⾮法字符,返回1表⽰不合法,0表⽰合法54int Explength=strlen(Exp_arry),i;55for(i=0;i<Explength;i++)56 {57if(!Isoper(Exp_arry[i]) && Exp_arry[i] != '.' && !isdigit(Exp_arry[i]))58return1;59if(isdigit(Exp_arry[i]))60 {61int Dig_number=0,Cur_positoin=i+1;62while(isdigit(Exp_arry[Cur_positoin]) || Exp_arry[Cur_positoin]=='.')63 {64 Dig_number++;65 Cur_positoin++;66 }67if(Dig_number >= 16)//最多能够计算15位有效数字68return1;69 }70 }71return0;72 }7374void Evalua()75 {//先调⽤Conver函数将字符串操作单元化,再调⽤Calculate函数计算结果并输出76char Exp_arry[Expmax_length];77int flag=0;//假设刚开始不合法,1表达式合法,0不合法78struct Ope_unit Opeunit_arry[Expmax_length];7980 getchar();//吃掉⼀个换⾏符81 printf("请输⼊四则运算表达式,以=结尾:\n");82 gets(Exp_arry);83 flag=Check(Exp_arry);84if(flag)85 printf("该表达式不合法!\n");86else87 {88int Opeunit_count = Conver(Opeunit_arry,Exp_arry);89double ans = Calculate(Opeunit_arry,Opeunit_count,flag);90if(flag)91 {92 printf("计算结果为:\n");93 printf("%s%lf\n",Exp_arry,ans);94 }95else96 printf("该表达式不合法!\n");97 }98 system("pause");99 }100101int Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[])102 {//将字符串操作单元化103int Explength=strlen(Exp_arry);104int i,Opeunit_count=0;105for(i=0;i<Explength;i++)106 {107if(Isoper(Exp_arry[i]))//是操作符108 {109 Opeunit_arry[Opeunit_count].flag=0;110 Opeunit_arry[Opeunit_count++].oper=Exp_arry[i];111 }112else//是操作数113 {114 Opeunit_arry[Opeunit_count].flag=1;115char temp[Expmax_length];116int k=0;117for(; isdigit(Exp_arry[i]) || Exp_arry[i]=='.' ;i++)118 {119 temp[k++]=Exp_arry[i];120 }121 i--;122 temp[k]='\0';123 Opeunit_arry[Opeunit_count].real=atof(temp);//将字符转化为浮点数124125//负数126if(Opeunit_count == 1 && Opeunit_arry[Opeunit_count-1].flag==0127 && Opeunit_arry[Opeunit_count-1].oper=='-')128 {129 Opeunit_arry[Opeunit_count-1].flag = -1;130 Opeunit_arry[Opeunit_count].real *= -1;131 }// -9132if(Opeunit_count >= 2 && Opeunit_arry[Opeunit_count-1].flag==0133 && Opeunit_arry[Opeunit_count-1].oper=='-' && Opeunit_arry[Opeunit_count-2].flag==0 134 && Opeunit_arry[Opeunit_count-2].oper !=')')135 {136 Opeunit_arry[Opeunit_count-1].flag = -1;137 Opeunit_arry[Opeunit_count].real *= -1;138 }// )-9139140//正数141if(Opeunit_count == 1 && Opeunit_arry[Opeunit_count-1].flag==0142 && Opeunit_arry[Opeunit_count-1].oper=='+')143 {144 Opeunit_arry[Opeunit_count-1].flag = -1;145 }// +9146if(Opeunit_count >= 2 && Opeunit_arry[Opeunit_count-1].flag==0147 && Opeunit_arry[Opeunit_count-1].oper=='+' && Opeunit_arry[Opeunit_count-2].flag==0148 && Opeunit_arry[Opeunit_count-2].oper !=')')149 {150 Opeunit_arry[Opeunit_count-1].flag = -1;151 }// )+9152 Opeunit_count++;153 }154 }155/*for(i=0;i<Opeunit_count;i++)156 {//查看各操作单元是否正确,1是操作数,0是操作符157 if(Opeunit_arry[i].flag == 1)158 printf("该单元是操作数为:%lf\n",Opeunit_arry[i].real);159 else if(Opeunit_arry[i].flag == 0)160 printf("该单元是操作符为:%c\n",Opeunit_arry[i].oper);161 else162 printf("该单元是负号符为:%c\n",Opeunit_arry[i].oper);163 }*/164return Opeunit_count;165 }166167double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag)168 {//根据运算规则,利⽤栈进⾏计算169int i,dS_pointer=0,oS_pointer=0;//dS_pointer为操作数栈顶指⽰器,oS_pointer为操作符栈顶指⽰器170double Dig_stack[Expmax_length];//操作数栈(顺序存储结构)171char Ope_stack[Expmax_length];//操作符栈172173for(i=0;i<Opeunit_count-1;i++)174 {175if( Opeunit_arry[i].flag != -1 )176 {177if(Opeunit_arry[i].flag)//是操作数178 {179 Dig_stack[dS_pointer++]=Opeunit_arry[i].real;//⼊操作数栈180//printf("%lf\n",Digit[dS_pointer-1]);181 }182else//是操作符 + - * / ( )183 {184//操作符栈为空或者左括号⼊栈185if(oS_pointer==0 || Opeunit_arry[i].oper=='(')186 {187 Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;188//printf("%oS_pointer\Ope_u_count",Operator[oS_pointer-1]);189 }190else191 {192if(Opeunit_arry[i].oper==')')//是右括号将运算符⼀直出栈,直到遇见左括号193 {194 oS_pointer--;//指向栈顶195 dS_pointer--;//指向栈顶196while(Ope_stack[oS_pointer] != '(' && oS_pointer != 0)197 {198 Dig_stack[dS_pointer-1] = Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer], 199 Ope_stack[oS_pointer--]);//oS_pointer--为操作符出栈200201 dS_pointer--;//前⼀个操作数出栈202//printf("操作数栈顶元素等于%lf\n",Digit[dS_pointer]);203 }204 oS_pointer--;//左括号出栈205206 oS_pointer++;//恢复指向栈顶之上207 dS_pointer++;208 }209else if(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer-1]))//和栈顶元素⽐较210 {211 Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;212//printf("%oS_pointer\Ope_u_count",Operator[oS_pointer-1]);213 }214else//运算符出栈,再将该操作符⼊栈215 {216 oS_pointer--;//指向栈顶217 dS_pointer--;//指向栈顶218while(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer])==0 && oS_pointer != -1) 219 {//当前操作符⽐栈顶操作符优先级⾼220 Dig_stack[dS_pointer-1]=Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer], 221 Ope_stack[oS_pointer--]);222 dS_pointer--;223//printf("操作数栈顶元素等于%lf\n",Digit[dS_pointer]);224 }225 oS_pointer++;//恢复指向栈顶之上226 dS_pointer++;227 Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;228 }229 }230 }231 }232 }233/*for(i=0;i<oS_pointer;i++)234 printf("操作符栈%oS_pointer\Ope_u_count",Operator[i]);235 for(i=0;i<dS_pointer;i++)236 printf("操作数栈%lf\n",Digit[i]);*/237 oS_pointer--;//指向栈顶元素238 dS_pointer--;//指向栈顶元素239while(oS_pointer != -1)240 {241 Dig_stack[dS_pointer-1]=Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer], 242 Ope_stack[oS_pointer--]);//oS_pointer--为操作符出栈243 dS_pointer--;//前⼀个操作数出栈244//printf("操作数栈顶元素为%lf\Ope_u_count",Digit[dS_pointer]);245 }246//printf("%dS_pointer,%dS_pointer\n",oS_pointer,dS_pointer);247if(oS_pointer==-1 && dS_pointer==0)248 flag=1;//为1表⽰表达式合法249return Dig_stack[0];250 }251252int Ope_Compar(char ope1,char ope2)253 {//操作符运算优先级⽐较254char list[]={"(+-*/"};255int map[5][5]={//先⾏后列,⾏⽐列的运算级优先级低为0,⾼为1256// ( + - * /257/* ( */1,0,0,0,0,258/* + */1,0,0,0,0,259/* - */1,0,0,0,0,260/* * */1,1,1,0,0,261/* / */1,1,1,0,0 };262int i,j;263for(i=0;i<5;i++)264if(ope1==list[i]) break;265for(j=0;j<5;j++)266if(ope2==list[j]) break;267return map[i][j];268 }269270double Four_arithm(double x,double y,char oper)271 {//四则运算272switch(oper)//保证不含其它运算符273 {274case'+': return x+y;275case'-': return x-y;276case'*': return x*y;277case'/': return x/y;//y不能为0278default : return0;279 }280 }281282int Isoper(char ch)283 {//判断合法字符 + - * / ( ) =284if(ch=='+' || ch=='-' || ch=='*' || ch=='/' || ch=='(' || ch==')' || ch=='=')285return1;286return0;287 }288289void Display()290 {//打印菜单291 system("cls");292 printf("/******************************************************************************/\n");293 printf("\t\t 欢迎使⽤本四则运算表达式求值系统\n");294 printf("\n\t说明:建议请您先阅读使⽤说明,再输⼊相应的数字进⾏操作,谢谢配合!\n"); 295 printf("\n\t\t1 四则运算表达式求值\n");296 printf("\n\t\t2 使⽤说明\n");297 printf("\n\t\t0 退出\n");298 printf("/******************************************************************************/\n");299 }300301void Instru()302 {//打印使⽤说明303 FILE *fp;304char ch;305if( ( fp=fopen("使⽤说明.txt","r") ) == NULL)306 {307 printf("⽂件打开失败!\n");308 exit(0);309 }310for(; (ch = fgetc(fp)) != EOF; )311 putchar(ch);312 fclose(fp);313 printf("\n");314 system("pause");315 }。

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

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

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

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.选择算符优先分析法完成以上任务,中间代码选用逆波兰式。

《数据结构课程设计》表达式求值实验报告

《数据结构课程设计》表达式求值实验报告

实验课程名称专业班级学生姓名学号指导教师20 至 20 学年第学期第至周算术表达式求值演示一、概述数据结构课程设计.要求学生在数据结构的逻辑特性和物理表示、数据结构的选择和应用、算法的设计及其实现等方面.加深对课程基本内容的理解。

同时.在程序设计方法以及上机操作等基本技能和科学作风方面受到比较系统和严格的训练。

在这次的课程设计中我选择的题目是算术表达式求值演示。

表达式计算是实现程序设计语言的基本问题之一.也是栈的应用的一个典型例子。

设计一个程序.演示用算符优先法对算术表达式求值的过程。

深入了解栈和队列的特性.以便在解决实际问题中灵活运用它们.同时加深对这种结构的理解和认识。

二、系统分析1.以字符列的形式从终端输入语法正确的、不含变量的整数表达式。

利用已知的算符优先关系.实现对算术四则混合运算表达式的求值.并仿照教科书的例子在求值中运算符栈、运算数栈、输入字符和主要操作的变化过程。

2.一般来说.计算机解决一个具体问题时.需要经过几个步骤:首先要从具体问题抽象出一个适当的数学模型.然后设计一个解决此数学模型的算法.最后编出程序.进行测试.调试直至得到想要的答案。

对于算术表达式这个程序.主要利用栈.把运算的先后步骤进行分析并实现简单的运算!为实现算符优先算法.可以使用两个栈.一个用以寄存运算符.另一个用以寄存操作数和运算结果。

3.演示程序是以用户于计算机的对话方式执行.这需要一个模块来完成使用者与计算机语言的转化。

4.程序执行时的命令:本程序为了使用具体.采用菜单式的方式来完成程序的演示.几乎不用输入什么特殊的命令.只需按提示输入表达式即可。

(要注意输入时格式.否者可能会引起一些错误)5. 测试数据。

三、概要设计一个算术表达式中除了括号、界限符外.还包括运算数据和运算符。

由于运算符有优先级别之差.所以一个表达式的运算不可能总是从左至右的循序执行。

每次操作的数据或运算符都是最近输入的.这与栈的特性相吻合.故本课程设计借助栈来实现按运算符的优先级完成表达式的求值计算。

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

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

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

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;}。

算法表达式语法检查(数据结构课程设计)

算法表达式语法检查(数据结构课程设计)

中南民族大学计算机科学学院课程设计报告课程数据结构题目算法表达式语法检查年级 2014专业软件工程学生柳真学号 201421092073指导教师刘赛2015年12月20 日中南民族大学计算机科学学院本科课程设计任务书设计名称:算术表达式语法检查指导教师:下达时间: 2015-11-30 学生姓名:学号:年级专业: 2014级软件工程一、课程设计的基本要求利用《数据结构》课程的相关知识完成一个具有一定难度的综合设计题目,利用C/C++语言进行程序设计,并规范地完成课程设计报告。

通过课程设计,巩固和加深对线性表、栈、队列、字符串、树、图、查找、排序等理论知识的理解;掌握现实复杂问题的分析建模和解决方法(包括问题描述、系统分析、设计建模、代码实现、结果分析等);提高利用计算机分析解决综合性实际问题的基本能力。

具体要求如下:1、对现实复杂问题中的数据对象特性及组织方法进行分析和研究,设计适当的数据逻辑结构、存贮结构以及相应运算操作,把现实世界问题建模转化为计算机内部表示并进行处理。

2、采取模块化方式进行程序设计,要求程序的功能设计、数据结构设计及整体结构设计合理。

学生也可根据自己对题目的理解增加新的功能模块(视情况可另外加分)。

3、系统以菜单界面方式(至少采用文本菜单界面,如能采用图形菜单界面更好)工作,运行界面友好,演示程序以用户和计算机的对话方式进行,利用文件进行数据的提取与存储。

4、程序算法说明清晰,理论分析与计算正确,运行情况良好,实验测试数据无误,容错性强(能对错误输入进行判断控制)。

5、编程风格良好(包括缩进、空行、适当注释、变量名和函数名见名知意,程序容易阅读等);6、写出规范的课程设计报告,具体要求见相关说明文档。

二、课程设计的主要内容题目描述:算术表达式语法检查。

功能要求及说明:(1)键盘读入一个四则运算算术表达式,对其进行语法检查;(2)算术表达式允许嵌套,如果出错,指出出错位置;(3)不需要计算结果;(4)尽量不使用栈。

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

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

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

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

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

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

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

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

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

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

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

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

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

数据结构课程设计_算术表达式

数据结构课程设计_算术表达式

表达式求值一目的利用《数据结构》课程的相关知识完成一个具有一定难度的综合设计题目,利用C/C++语言进行程序设计,并规范地完成课程设计报告。

通过课程设计,巩固和加深对线性表、栈、队列、字符串、树、图、查找、排序等理论知识的理解;掌握现实复杂问题的分析建模和解决方法(包括问题描述、系统分析、设计建模、代码实现、结果分析等);提高利用计算机分析解决综合性实际问题的基本能力。

设计一个程序,演示以字符序列的形式输入不含变量的实数表达式求值的计算结果二需求分析设计一个程序,演示以字符序列的形式输入不含变量的实数表达式求值的计算结果。

对于这个程序我们从输入,输出,和功能三方面来分析。

1.程序输入:从键盘上输入表达式,一个算术表达式,由常量、运算符和括号组成(以字符串形式输入,不含变量)。

为了简化,操作数只能为浮点数,操作符为“ +”、“-”、“*”、“/”、“(”、“)”,用“#“表示结束。

2.程序输出:表达式运算结果,运算符栈、运算数栈、输入字符和主要操作变化过程,如运算符栈、运算数栈的出入记录,字符出入栈的过程,打印出完整的过程。

3.功能要求及说明:从键盘上输入表达式。

分析该表达式是否合法(包含分母不能为零的情况):(1)是数字,则判断该数字的合法性。

(2)是规定的运算符,则根据规则进行处理。

在处理过程中,将计算该表达式的值。

(3)若是其它字符,则返回错误信息。

若上述处理过程中没有发现错误,则认为该表达式合法,并打印处理结果。

三概要设计1.数据结构的选择:任何一个表达式都是由操作符,运算符和界限符组成的。

我们分别用顺序栈来寄存表达式的操作数和运算符。

栈是限定于紧仅在表尾进行插入或删除操作的线性表。

为了实现算符优先算法,可以使用两个工作栈。

一个称做SqStack1,用以寄存运算符;另一个称做SqStack2,用以寄存操作数或运算结果。

首先置操作数栈为空栈,表达式起始符“#”作为运算符栈的栈底元素,然后依次读入表达式的每个字符,若是操作数则进入SqStack2栈,若是运算符则和SqStack1栈的栈顶运算符比较优先权后做相应操作,直至整个表达式求值完毕。

算术表达式语法检查实验报告

算术表达式语法检查实验报告

中南民族大学计算机科学学院本科课程设计任务书设计名称:算术表达式语法检查指导教师:下达时间: 2015-5-8学生姓名:学号:专业:一、课程设计的基本要求根据所学知识,编写指定题目的C++语言程序,并规范地完成课程设计报告。

通过课程设计,加深对《C++面向对象程序设计》课程所学知识的理解,熟练掌握和巩固C++语言的基本知识和语法规范,掌握C++语言的基础知识,理解面向对象系统的封装性、继承性和多态性;熟练使用C语言中的函数、数组、指针、链表和字符串等基本知识;掌握类的定义、标准String类和向量;理解掌握友元函数和重载操作符,动态数组;理解掌握继承和多态性;掌握模版的使用;能够进行程序调试过程中的异常处理;进一步掌握利用C++进行类的定义和操作方法;进一步掌握类的继承和派生方法;进一步理解虚函数和多态;综合利用上述知识,学习设计并编写面向对象的C++简单应用程序;培养解决复杂任务功能分解方法(自顶向下逐步求精、模块化设计、信息隐藏等)。

学会编制结构清晰、风格良好、数据结构适当的C++语言程序,从而具备利用计算机编程分析解决综合性实际问题的初步能力。

具体要求如下:1、采取模块化方式进行程序设计,要求程序的功能设计、数据结构设计及整体结构设计合理。

学生也可根据自己对题目的理解增加新的功能模块(视情况可另外加分)。

2、系统以菜单界面方式(至少采用文本菜单界面,如能采用图形菜单界面更好)工作,运行界面友好,演示程序以用户和计算机的对话方式进行。

3、程序算法说明清晰,理论分析与计算正确,运行情况良好,实验测试数据无误,容错性强(能对错误输入进行判断控制)。

4、编程风格良好(包括缩进、空行、适当注释、变量名和函数名见名知意,程序容易阅读等);二、课程设计的主要内容【问题描述】算术表达式语法检查。

【功能要求】(1)键盘读入一个四则运算算术表达式,对其进行语法检查;(2)算术表达式允许嵌套,如果出错,指出出错位置;(3)不需要计算结果;(4)尽量不使用栈。

数据结构课程设计:算术表达式

数据结构课程设计:算术表达式

表达式求值一目的利用《数据结构》课程的相关知识完成一个具有一定难度的综合设计题目,利用C/C++语言进行程序设计,并规范地完成课程设计报告。

通过课程设计,巩固和加深对线性表、栈、队列、字符串、树、图、查找、排序等理论知识的理解;掌握现实复杂问题的分析建模和解决方法(包括问题描述、系统分析、设计建模、代码实现、结果分析等);提高利用计算机分析解决综合性实际问题的基本能力。

设计一个程序,演示以字符序列的形式输入不含变量的实数表达式求值的计算结果二需求分析设计一个程序,演示以字符序列的形式输入不含变量的实数表达式求值的计算结果。

对于这个程序我们从输入,输出,和功能三方面来分析。

1.程序输入:从键盘上输入表达式,一个算术表达式,由常量、运算符和括号组成(以字符串形式输入,不含变量)。

为了简化,操作数只能为浮点数,操作符为“ +”、“-”、“*”、“/”、“(”、“)”,用“#“表示结束。

2.程序输出:表达式运算结果,运算符栈、运算数栈、输入字符和主要操作变化过程,如运算符栈、运算数栈的出入记录,字符出入栈的过程,打印出完整的过程。

3.功能要求及说明:从键盘上输入表达式。

分析该表达式是否合法(包含分母不能为零的情况):(1)是数字,则判断该数字的合法性。

(2)是规定的运算符,则根据规则进行处理。

在处理过程中,将计算该表达式的值。

(3)若是其它字符,则返回错误信息。

若上述处理过程中没有发现错误,则认为该表达式合法,并打印处理结果。

三概要设计1.数据结构的选择:任何一个表达式都是由操作符,运算符和界限符组成的。

我们分别用顺序栈来寄存表达式的操作数和运算符。

栈是限定于紧仅在表尾进行插入或删除操作的线性表。

为了实现算符优先算法,可以使用两个工作栈。

一个称做SqStack1,用以寄存运算符;另一个称做SqStack2,用以寄存操作数或运算结果。

首先置操作数栈为空栈,表达式起始符“#”作为运算符栈的栈底元素,然后依次读入表达式的每个字符,若是操作数则进入SqStack2栈,若是运算符则和SqStack1栈的栈顶运算符比较优先权后做相应操作,直至整个表达式求值完毕。

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

《数据结构》课程设计中南民族大学计算机科学学院课程设计报告课程数据结构题目算法表达式语法检查年级2014专业软件工程学生柳真学号201421092073指导教师刘赛2015年12月20日中南民族大学计算机科学学院本科课程设计任务书设计名称:算术表达式语法检查指导教师:下达时间: 2015-11-30学生姓名:学号:年级专业:2014级软件工程一、课程设计的基本要求利用《数据结构》课程的相关知识完成一个具有一定难度的综合设计题目,利用 C/C++语言进行程序设计,并规范地完成课程设计报告。

通过课程设计,巩固和加深对线性表、栈、队列、字符串、树、图、查找、排序等理论知识的理解;掌握现实复杂问题的分析建模和解决方法(包括问题描述、系统分析、设计建模、代码实现、结果分析等);提高利用计算机分析解决综合性实际问题的基本能力。

具体要求如下:1、对现实复杂问题中的数据对象特性及组织方法进行分析和研究,设计适当的数据逻辑结构、存贮结构以及相应运算操作,把现实世界问题建模转化为计算机内部表示并进行处理。

2、采取模块化方式进行程序设计,要求程序的功能设计、数据结构设计及整体结构设计合理。

学生也可根据自己对题目的理解增加新的功能模块(视情况可另外加分)。

3、系统以菜单界面方式(至少采用文本菜单界面,如能采用图形菜单界面更好)工作,运行界面友好,演示程序以用户和计算机的对话方式进行,利用文件进行数据的提取与存储。

4、程序算法说明清晰,理论分析与计算正确,运行情况良好,实验测试数据无误,容错性强(能对错误输入进行判断控制)。

5、编程风格良好(包括缩进、空行、适当注释、变量名和函数名见名知意,程序容易阅读等);6、写出规范的课程设计报告,具体要求见相关说明文档。

二、课程设计的主要内容题目描述:算术表达式语法检查。

功能要求及说明:(1)键盘读入一个四则运算算术表达式,对其进行语法检查;(2)算术表达式允许嵌套,如果出错,指出出错位置;(3)不需要计算结果;(4)尽量不使用栈。

三、课程设计的进程安排1.2015 年 11 月 30 日:布置并下达课程设计题目。

2.2015 年 12 月 7 日之前:联系指导教师,理解课程设计题目及相关要求,查阅相关资料,进行课程设计(地点: 9-204, 9-206)。

3.2015 年 12 月 7 日至 12 月 31 日(第15周-第18周):课程设计源程序的调试、修改与检查,书写课程设计报告(地点:计算机科学学院实验机房)。

4.2016 年 12 月 31 日之前:上交、检查设计报告(地点:计算机科学学院实验机房)。

指导教师:2015 年 11 月 20日算术表达式语法检查一目的根据课题要求,完成算法表达式语法检查。

具体完成以下四点要求:( 1)键盘读入一个四则运算算术表达式,对其进行语法检查;(2)算术表达式允许嵌套,如果出错,指出出错位置;(3)不需要计算结果;(4)尽量不使用栈。

二需求分析1、选择存放算术表达式的数据结构本次课设,我选择了本学期数据结构中所学的栈来实现算术表达式中的字符存放。

2、运算符优先级划分一个完整的算术表达式中包含+、 -、 * 、 /、(、)六种运算符,当遇到这些字符时要确定其优先级的高低,并依次存放进栈或者出栈。

并且还可以进行发现输入错误提示判断,达到课题中相关要求。

三概要设计1、运算符优先级等级划分表+-*/()#+11-1-1-111-11-1-1-111*1111-111/1111-111 (-1-1-1-1-10-3)1111-111#-1-1-1-1-1-20上表中 1 代表栈中运算符出栈,进行运算;0 代表栈中运算符(‘(’或‘#’)出栈; -1 代表当前运算符进栈;-2 代表当前输入‘)’错误;-3 代表算术表达式末尾少输入‘)’。

2、程序流程图开始输入一个算术表达式定义一个栈 A ,用来存放数字;定义一个栈B用来存放运算符定义一个字符变量c,一个字符数组d[100]从表达式首字符开始,获取一个字符存放到 c 中,开始依次检查c!=’#’||GetTob(B)!= ’#’否是结束首字符是运算符是如果是’(’进栈,否则报错否是检查下一个字符字符是运算符否字符是数字是数字放入字符数组d[100]否是检查下一个字符字符是数字否将字符串数组d[100]转化为数字,存入栈A字符是运算符是字符是’(’是否报错判断运算符优先级,将结果否检查下一个字放入 b 中是字符是运算符否跳出本次循环,进行下一次循环b = 1是A 中最后进栈的两个数出栈,B中最后进栈的运算符出栈,进否行运算,运算结果存入栈A跳出本次循环,进行下一次循环b = -1是运算符进栈 B否进行下一个字符检查,若字符是‘)’,报错。

检查下一个字符否字符是’(’是否运算符进栈B进行下一个字符检报错字符是运算符是否跳出本次循环,进行下一次循环b = 0是否B 中运算符出栈否进行下一个字符检查跳出本次循环,进行下一次循环b = -2否b = -3是报错,输入’)’错误进行下一个字符检查跳出本次循环,进行下一次循环否是B 中运算符出栈,并报错。

第 i 位少输入’)’报错,输入非法字符跳出本次循环,进行下一次循环检查下一个字符跳出本次循环,进行下一次循环结束四详细设计1、栈的结构及相关功能函数构造伪代码typedef int SElemType;const int STACK_INIT_SIZE = 100; //存储空间初始分配量const int STACKINCREMENT = 10; //存储空间分配增量typedef struct{SElemType *base; // 栈底指针,在栈构造前和销毁后,其值均为空SElemType *top; // 栈顶指针int stacksize;// 当前已分配的存储空间}SqStack;//构造一个空栈void InitStack(SqStack &S);//若栈不为空,返回栈顶元素值SElemType GetTop(SqStack & S);//插入元素 e 为栈的新栈顶元素void push(SqStack &S,SElemType e);//用 e 返回栈顶元素,并删除栈顶元素void Pop(SqStack &S,SElemType &e);2、实现表达式语法检查功能函数构造伪代码//判定输入的运算符,并分类标记int judgePrecedence(char a){int i = 7;switch(a){case '+': i = 0; break;case '-': i = 1; break;case '*': i = 2; break;case '/': i = 3; break;case '(': i = 4; break;case ')': i = 5; break;case '#': i = 6; break;}return i;}//比较运算符的优先级,并标记分类int Precedence(char a,char b){根据 judgePrecedence()函数确定 a、b 的运算符种类,然后构建一个7*7 的二维数组表,依次填入优先级,并返回相应优先等级。

具体表格信息见概要设计中运算符优先等级划分表。

}//执行运算int Operate(int a,char b,int c){其中 a、c 是数字, b 是运算符( +、 -、 * 、 / ),实现具体运算操作,并返回运算结果值。

}//判断 c 是否是运算符int panduan(char c){根据 judgePrecedence()函数,判断 c 是否是运算符,如果是怎返回1,否则返回 0。

}// 具体应用操作void Yunsuan(){SqStack A,B;// 创建栈 A 、 Bpush(B,'#');// 栈 B 中栈底存入 #c = getchar();// 获取算术表达式中字符int i = 1;while(c !='#' || GetTop(B)!='#'){if(i == 1 && judgePrecedence(c) != 7)首字符是运算符,报错;if(c >= '0' && c <= '9')字符是数字,存放在数组d[100] 中,后转化为数字存入栈A中;else if(judgePrecedence(c) != 7)字符是运算符,进行判断,有错则报错,没有则进栈B;else报错,输入非法字符。

}}五调试分析1、算法逻辑问题及输出错误检查一个算术表达式错误时,要具体要第几位以及是哪些错误,在刚开始的检查功能检查设计的时候,我的代码只能检查到+、 -、 * 、 /相关输入错误,对于(、)运算符不能完全检查出输入错误,其中有关除数为0 的输入错误时,程序不能检查除数0 后面表达式中的错误,直接程序终止。

后来,我在程序加了一个条件关于除数为0 的运算限定,成功解决了除数为0 后面表达式的语法无法检查的问题。

其中,最为重要的是,通过设计不同类型的算术表达式进行语法检查,不断地发现程序设计过程中的逻辑错误,并不断修改,最后成功解决了本次课设中难点。

六测试结果1、设计输入的算术表达式(1)+-*/1+2/(4-4*2/4)(2)(3a+2b)*4-8/2(3)a!c1+2a*(3-4/2)(4)1++2 —3*(4//5)(5)1+2*(2*4/0-3)(6)1+2*(3-4/2(7)1-2/((3-4*2)(8)2*3+)(3/3-4)(9)2++4-5*(3+2+((2*1)(10) (2++4))-5/0*(3+2*(2+1)2、具体运算检查分析结果截图图一:上图一是设计输入的算术表达式(1) — (4)运行结果截图;图二:上图二是设计输入的算术表达式(5) — (8)运行结果截图;图三:上图三是输入设计的算术表达式(9) — (10)运行结果截图。

七用户使用说明1、输入规则输入一个算术表达式,其中对应的运算符是+、 -、 * 、 /、 (、 ) 表达的意思是加、减、乘、除、顺括号、反括号。

要求输入一个算术表达式完毕后,在输入一个‘#’结束输入,最后按enter 键即可得到算术表达式语法检查结果。

八课程设计总结在本次课程设计实施的过程中,遇到了很多问题,当然收获也很多。

起初,让我感觉很难的地方在于如何确定算术表达式错误的位置以及有哪些错误要确定。

相关文档
最新文档