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

合集下载

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

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

编译原理语法分析实验报告第一篇:编译原理语法分析实验报告实验2:语法分析1.实验题目和要求题目:语法分析程序的设计与实现。

实验内容:编写语法分析程序,实现对算术表达式的语法分析。

要求所分析算术表达式由如下的文法产生。

E→E+T|E-T|TT→T*F|T/F|F F→id|(E)|num实验要求:在对输入表达式进行分析的过程中,输出所采用的产生式。

方法1:编写递归调用程序实现自顶向下的分析。

方法2:编写LL(1)语法分析程序,要求如下。

(1)编程实现算法4.2,为给定文法自动构造预测分析表。

(2)编程实现算法4.1,构造LL(1)预测分析程序。

方法3:编写语法分析程序实现自底向上的分析,要求如下。

(1)构造识别所有活前缀的DFA。

(2)构造LR分析表。

(3)编程实现算法4.3,构造LR分析程序。

方法4:利用YACC自动生成语法分析程序,调用LEX自动生成的词法分析程序。

实现(采用方法1)1.1.步骤:1)对文法消除左递归E→TE'E'→+TE'|-TE'|εT→FT'T'→*FT'|/FT'|εF→id|(E)|num2)画出状态转换图化简得:3)源程序在程序中I表示id N表示num1.2.例子:a)例子1 输入:I+(N*N)输出:b)例子2 输入:I-NN 输出:第二篇:编译原理实验报告编译原理实验报告报告完成日期 2018.5.30一.组内分工与贡献介绍二.系统功能概述;我们使用了自动生成系统来完成我们的实验内容。

我们设计的系统在完成了实验基本要求的前提下,进行了一部分的扩展。

增加了声明变量类型、类型赋值判定和声明的变量被引用时作用域的判断。

从而使得我们的实验结果呈现的更加清晰和易懂。

三.分系统报告;一、词法分析子系统词法的正规式:标识符(|)* 十进制整数0 |(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)* 八进制整数0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)* 十六进制整数0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)* 运算符和分隔符 +| * | / | > | < | = |(|)| <=|>=|==;对于标识符和关键字: A5—〉 B5C5 B5—〉a | b |⋯⋯| y | z C5—〉(a | b |⋯⋯| y | z |0|1|2|3|4|5|6|7|8|9)C5|ε综上正规文法为: S—〉I1|I2|I3|A4|A5 I1—〉0|A1 A1—〉B1C1|ε C1—〉E1D1|ε D1—〉E1C1|εE1—〉0|1|2|3|4|5|6|7|8|9 B1—〉1|2|3|4|5|6|7|8|9 I2—〉0A2 A2—〉0|B2 B2—〉C2D2 D2—〉F2E2|ε E2—〉F2D2|εC2—〉1|2|3|4|5|6|7 F2—〉0|1|2|3|4|5|6|7 I3—〉0xA3 A3—〉B3C3 B3—〉0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f C3—〉(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)|C3|εA4—〉+ |-| * | / | > | < | = |(|)| <=|>=|==; A5—〉 B5C5 B5—〉a | b |⋯⋯| y | z C5—〉(a | b |⋯⋯| y | z |0|1|2|3|4|5|6|7|8|9)C5|ε状态图流程图:词法分析程序的主要数据结构与算法考虑到报告的整洁性和整体观感,此处我们仅展示主要的程序代码和算法,具体的全部代码将在整体的压缩包中一并呈现另外我们考虑到后续实验中,如果在bison语法树生成的时候推不出目标的产生式时,我们设计了报错提示,在这个词的位置出现错误提示,将记录切割出来的词在code.txt中保存,并记录他们的位置。

编译原理实验报告3

编译原理实验报告3

编译原理实验报告——表达式语法分析 ——表达式语法分析表达式语法分析实验报告一、实验题目设计一个简单的表达式语法分析器 (采用递归下降方法设计实现)二、实验目的1、 了解形式语言基础及其文法运算; 2、 熟悉语法分析原理及 4 种常用的语法分析方法; 其中: 四种算法为 (1)设计算术表达式的递归下降子程序分析算法 (2)设计算术表达式的 LL(1) 分析算法 (3)设计算术表达式的简单优先分析算法 (4)设计算术表达式的 SLR(1) 分析算法 3、选择上述一种方法并设计一个表达式的语法分析器。

(本实验设计的是递归下降的表达式语法分析器)三、实验内容1.设计递归下降语法分析器算法; 2.编写代码并上机调试运行通过; 3、写出试验体会及心得。

四、实验要求1、 给出算术表达式文法 2、 进行适当的文法变换 3、 选择一种语法分析的方法,并说明其原理 4、 根据原理给出相应的算法设计,说明主要的数据结构并画出算法流 程图 5、 编写代码并上机调试运行通过 6、 写出程序运行结果 7、 写出相应的文档以及代码注释 8、输入——表达式; 输出——表达式语法是否正确。

五、递归下降的表达式语法分析器设计概要1.算术表达式文法 . G(E): E T F 2.文法变换: 文法变换: G’(E): E->TE' E'->+TE'|ε T->FT' T'->*FT'|ε F->(E)|I E +T | T T* F | F i | (E)3. 递归下降子程序框图: 递归下降子程序框图:六、实验设计源程序#include <iostream.h>char inputstream[50]; int temp=0; int right; void e(); void e1(); void t(); void t1(); void f(); void main() { right=1;//存储输入句子//数组下标 //判断输出信息cout<<"请输入您要分析的字符串以#结束(^为空字符):"<<endl; cin>>inputstream; e(); if((inputstream[temp]=='#')&&right) cout<<"分析成功"<<endl; else cout<<"分析失败"<<endl; } void e() { cout<<"E->TE'"<<endl; t(); e1(); } void e1() { if(inputstream[temp]=='+') { cout<<"E'->+TE'"<<endl; temp++; t();e1(); } else if (inputstream[temp]!='#'||inputstream[temp]!=')') { cout<<"T'->^"<<endl; return ; } else right=0; } void t() { cout<<"T->FT'"<<endl; f(); t1(); } void t1() { if(inputstream[temp]=='*') { cout<<"T'->*FT'"<<endl; temp++; f(); t1(); } else if (inputstream[temp]!='#'&&inputstream[temp]!=')'&&inputstream[temp ]!='+') { cout<<"T'->^"<<endl; right=0;} } void f() { if(inputstream[temp]=='i') { cout<<"F->i"<<endl; temp++; } elseif(inputstream[temp]=='(') { cout<<"F->(E)"<<endl; temp++; e(); if(inputstream[temp]==')') { cout<<"F->(E)"<<endl; temp++; } else right=0; } else right =0; }七、运行结果八、实验思考题语法分析的任务是什么? 语法分析的任务是什么? 答:语法分析器的任务是识别和处理比单词更大的语法单位,如:程序设 计语言中的表达式、各种说明和语句乃至全部源程序,指出其中的语法错误; 必要时,可生成内部形式,便于下一阶段处理。

实验2 语法分析(算符优先分析)

实验2 语法分析(算符优先分析)

实验2 语法分析(算符优先分析)一、实验任务:算术表达式的文法:E→ E+T | E-T | TT→ T*F | T/F | FF→(E)| i根据算符优先分析法,将表达式进行语法分析,判断一个表达式是否正确。

二、实验时间:上机2次。

三、实验过程和指导:(一)准备:1.确定算术表达式的文法,设计出算符优先关系表;2.考虑好设计方案,设计出模块结构、测试数据;3.初步编制好程序。

(二)上机实验:上机调试,发现错误,分析错误,逐渐修改完善。

(三)程序要求:程序输入/输出示例:如参考C语言的运算符。

输入如下表达式(以分号为结束)和输出结果:(1)10输出:正确(2)1+2*(15-6)输出:正确(3)(1+2)/3+4- (11+6/7)输出:正确(4)((1-2)/3+4输出:错误,出错位置是(5)1+2-3+(*4/5)输出:错误,出错位置是注意:1.为降低难度,表达式中不含变量(只含无符号整数);2.可以直接调用此法分析程序,取得单词;3.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好,最好有详细的出错位置和出错性质说明);4.测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。

同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照;5.对学有余力的同学,可增加功能:当判断一个表达式正确时,输出计算结果,计算过程用浮点表示,但要注意不要被0除。

(四)练习该实验的目的和思路:程序比较复杂,需要利用到大量的编译原理,也用到了大量编程技巧和数据结构,通过这个练习可极大提高编程能力。

程序规模大概为300行。

通过练习,掌握对表达式进行处理的一种方法。

(五)为了能设计好程序,注意以下事情:1.模块设计:将程序分成合理的多个模块(函数),每个模块做具体的同一事情。

2.写出(画出)设计方案:模块关系简图、流程图、全局变量、函数接口等。

3.编程时注意编程风格:空行的使用、注释的使用、缩进的使用、变量合理命名等。

编译实验报告(语法分析、词法分析)

编译实验报告(语法分析、词法分析)
search(digittp,3); //对该字符进行数字处理
printf("(3, %s)\n",digittp);










5、其他函数
char alphaprocess(char buffer)
char othertp [20];
othertp[0]=buffer;
othertp[1]='\0';
char *border[7]={",",";",".","(",")","{","}"}; //分格符
char *arithmetic[8]={"+","-","*","/","<",">","=","+="}; //运算符
////////////////////////////////////////////////////////////////////////////////////////
if (search(othertp,4)) do//判断字符是否是运算符
printf("(4, %s)\n",othertp);
buffer=fgetc(fp);
goto out;
if (search(othertp,5)) do //判断字符是否是分隔符
printf("(5, %s)\n",othertp);

编译原理语法分析试验报告

编译原理语法分析试验报告

二、语法分析(一)实验题目编写程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析。

(二)实验内容和要求1.要求程序至少能分析的语言的内容有:1)变量说明语句2)赋值语句3)条件转移语句4)表达式(算术表达式和逻辑表达式)5)循环语句6)过程调用语句2.此外要处理:包括依据文法对句子进行分析;出错处理;输出结果的构造。

3.输入输出的格式:输入:单词文件(词法分析的结果)输出:语法成分列表或语法树(都用文件表示),错误文件(对于不合文法的句子)。

4.实现方法:可以采用递归下降分析法,LL (1)分析法,算符优先法或LR分析法的任何一种,也可以针对不同的句子采用不同的分析方法。

(三)实验分析与设计过程1.待分析的C语言子集的语法:该语法为一个缩减了的C语言文法,估计是整个C语言所有文法的60% (各种关键字的定义都和词法分析中的一样),具体的文法如下:语法:100: program -> declaiationjist101: declarationjist -> declarationjist declaration declaration102: declaiation -> vai_declaiation|fijn_declaration103: vai.declaration -> type_specifier ID;|tvpe_specifier ID [NUM];104: typ Jsp亡cifki -> mt|void|float|chai-|long|double|105: fun_declaration -> type_specifier ID (params)|compound_stmt106: paranis -> params_list|void107: paramjist ->paiam_list.paiam|paiam108: param -> type-spectifier ED|type_specifier LD[]109: compound_stmt -> {locaLdeclaiations statementjist}110: locaLdeclarations -> local_declarations var_declaration|empty111: statementjist -> statementjist statement|emptv112: statement -> epiesion_stmt|conipound_stmtselection.stmt iteration_stmt|retuin_stmt113: expression^stmt -> expression;!;114: selection_stmt -> if{expressionjstatement if(expression)statement elsestatement115: iteration_stmt -> wliile{expression)statement116: return_stmt -> return;|return expression;117: expression -> var = expression|siinple-expression118: var -> ID | ID [expression]119: suuple_expression ->additive_expression relop additive_expression|additive_expression120: relop -> <=|<|>|>=|= =|!=121: additive_expression -> additive_expression addop term | term122: addop -> + | -123: term -> term mulop factor factor124: mulop -> *|/125: factor -> (expression)|var|call|NUM126: call -> ID(aigs)127: args -> aig_list|empty128: arg_list -> arg_list,expression|expression该文法满足了实验的要求,而且多了很多的内容,相当于一个小型的文法说明:把文法标号从100到128是为了程序中便于找到原来的文法。

语法分析_预测分析法_实验报告

语法分析_预测分析法_实验报告
ProcessT();
}
else if ( IsSymbolEnd(StackGet()) )
{
//栈顶为开始符
ProcessEnd();
}
else
{
//栈顶为非终结符
ProcessN();
}
}
void ProcessEnd()
{
if (StackGet() != ComingToken())
{
//非正常结尾
}
}
/*
*
*将产生式反向入栈
**/
void StackPushProfom(int buf[], int length)
{
int i;
_ASSERT(length > 0);
for (i = length - 1; i >= 0; i--)
{
StackPush(buf[i]);
}
}
/**
*由当前栈顶符及当前输入符取得产生式
}
}
void ProcessT()
{
if (StackGet() == ComingToken())
{
//match success, pop stack
StackPop();
//get next token
NextToken();
}
else
{
Leave(ANA_ERROR_UNEXPECTED_VALUE);
SELECT(F→( E )) SELECT(F→i)
= { ( } { i }
=
因而改写后的文法为LL(1)文法,可使用预测分析法自顶向下分析。
3)预测分析表
对每个表达式求其SELECT集。

C语言运算符和表达式-实验报告

C语言运算符和表达式-实验报告

中山大学南方学院电子通信与软件工程系课程名称:高级语言程序设计实践实验题目:运算符和表达式附:实验报告专业:年级:完成日期:学号:姓名:成绩:一、实验目的1、能够使用C语言进行简单的算术运算、关系运算和逻辑运算。

2、掌握不同的类型数据之间赋值的规律。

3、进一步熟悉C语言程序的编辑、编译和运行的过程。

二、实验原理1、用int定义整型变量来存放整数;2、用float定义浮点数变量来存放小数;3、使用scanf() 函数从键盘输入两个整型数据,并赋值给两个变量。

三、实验过程1、算术运算实验代码如下:#include <stdio.h>#include <stdlib.h>int main(){int a=2, b=3;float x=3. 9, y=2. 3;float result;result=(float) (a+b) /2+(int) x%(int) y;return result}输出结果如图:2、算术运算实验代码如下:#include <stdio.h>#include <stdlib.h>int main(){int number;int a1, a2, a3;printf("请输入一个三位数:");scanf("%d", &number) ;a1=number%10;number=number/10;a2=number%10;a3=number/10;printf("三位数%d的个位数字是%d,十位数字是%d,百位数字是%d\n",number,a1, a2, a3) ;return 0;}输出结果如图:3、关系运算与逻辑运算实验代码如下:#include <stdio.h>#include <stdlib.h>int main(){int x;printf("输入x的值:") ;scanf("%d", &x) ;printf("表达式(x>0)的值:%d\n", x>0) ;printf("表达式(x>=-20&&x<=-10)的值:%d\n", x>=-20&&x<=-10) ;printf("表达式(x>=100||x<10)的值:%d\n", x>=-20&&x<=-10) ;printf("表达式(x>20&&x%3==0的值:%d\n", x>20&&x%3==0) ;if(x%5==0&&x%3==0)printf("yes\n") ;elseprintf ("no\n") ;return 0;}输出结果如图:4、综合任务实验代码如下:#include <stdio.h>#include <stdlib.h>int main(){int grad1, grad2;scanf("%d%d", &grad1, &grad2) ;printf("表达式(grad1>=0&&grad1<=100)值:%d\n",grad1>=0&&grad1<=100);printf("表达式(grad2>=0&&grad2<=100)值:%d\n",grad2>=0&&grad2<=100);printf("%d", grad1>grad2? grad1:grad2) ;return 0;}输出结果如图:四、思考并回答以下问题1、举例说明逻辑运算符的短路特性。

语法分析实验报告

语法分析实验报告

语法分析实验报告一: 实验内容:编写语法分析程序, 实现对算术表达式的语法分析, 要求所分析的算术表达式由如下的文法产生。

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

1.编写LL(1)语法分析程序, 要求:编程实现算法4.2, 为给定的文法自动构造预测分析表编程实现算法4.1, 构造LL(1)预测分析程序,2.编写语法分析程序, 实现自底向上的分析, 要求:构造识别所有活前缀的DFA构造LR分析表编程实现算法4.3, 构造LR分析程序1.三: 实验分析:2.方法二(编写LL(1)语法分析程序)1.步骤:(1)根据题目所给出的文法构造相应的无左递归文法, 并求出该文法各非终结符的FIRST、FOLLOW集合;(2)构造文法的LL(1)分析表;(3)由此构造LL分析程序。

2.实现方法:1.输入缓冲区为一个字符型数组, 读入输入的算术表达式并保存在此, 以’$’结束;2.为构造文法的LL(1)分析表, 构建一个相对应的字符串数组;3.在实际程序中P代表E', Q代表T', e代表ε,i代表id, n代表num;4.处理输入表达式中代表id和num的子串, 分别将它们转化为'i'和'n'进行分析;5.LL(1)预测分析程序的总控程序在任何时候都是按STACK栈顶符号X和当前的输入符号a做哪种过程的。

对于任何(X,a),总控程序每次都执行下述三种可能的动作之一:(1)若X = a =‘$’, 则宣布分析成功, 停止分析过程。

(2)若X = a!=‘$’, 则把X从STACK栈顶弹出, 让a指向下一个输入符号。

①如果是终结符合, 则栈不加入新符号②如果是非终结符合, 则把表达式右边入栈(3)若M[A, a]中存放着“出错标志”, 则调用出错诊断程序ERROR。

编译原理实验——语法分析器报告

编译原理实验——语法分析器报告

组员学号姓名实验名称对各算术表达式进行语法分析实验室实验目的或要求实验目的:1、掌握语法分析器生成工具的使用和了解编译器的设计;2、了解自上而下语法分析器的构造过程;3、能够构造LR分析表,编写由该分析表驱动的语法分析器程序;4、借助语法制导翻译,可在语法分析的同时,完成对语义的翻译;5、借助语法分析,设计一个表达式的判断分析器,即从键盘上输入算术表达式,分析器将显示该表达式的正确与否。

实验原理(算法流程)实验算法流程图如下所示:开始输入表达式表达式保存到数ch第一个元素为)+-*/YCh[i]=’(’i++YNCh[i]=NULLNCh[i]是0~9i++YCh[i]是0~9Ch[i]=+ -*/)N多了+ -*/)Y其他错误NYCh[i]=* /Ni++YCh[i]=+ -*/NY多了+ -*/Ch[i]=+ -NNCh[i]=)Y少了)N错误首部多了) +-*/结束程序界面(效果图)实验结果界面:只选择几个典型的例子进行分析,可进行任意表达式输入。

1)未进行语法分析时的界面;2)输入正确的表达式(1+2)*(6-3)+1进行语法分析时的界面结果;3)输入错误的表达式1*2+(2+3并进行语法分析时的界面结果;程序界面(效果图)4)输入错误的表达式1+(+5+6)并进行语法分析时的界面结果;程序界面(效果图)程序代码 #include "stdafx.h"#include "grammer.h"#include "mfc_语法分析器.h"#include "mfc_语法分析器Dlg.h"int flag;int i,j;int length;CString string;int grammer(CString str){i=0;flag=0;char ch[MAX];length=str.GetLength();strcpy(ch,str);if(length!=0){F(ch);if(flag==0){MessageBox(NULL,"输入表达式符合文法","正确",MB_OK|MB_ICONINFORMATION);}//str=ch;//return flag;}else{MessageBox(NULL,"表达式为空","提示",MB_OK|MB_ICONW ARNING);//MessageBox(NULL,"表达式为空","提示",MB_OK|MB_ICONERROR);return -1;}return flag;}void F(char ch[]){if(ch[0]=='+'){程序代码flag=0;MessageBox(NULL,"输入表达式不符合文法0","错误",MB_OK|MB_ICONERROR); MessageBox(NULL,"开始处多了+","提示",MB_OK|MB_ICONINFORMA TION);flag=1;}elseif(ch[0]=='-'){flag=0;MessageBox(NULL,"输入表达式不符合文法0","错误",MB_OK|MB_ICONERROR);MessageBox(NULL,"开始处多了-","提示",MB_OK|MB_ICONINFORMA TION);flag=1;}elseif(ch[0]=='*'){flag=0;MessageBox(NULL,"输入表达式不符合文法0","错误",MB_OK|MB_ICONERROR);MessageBox(NULL,"开始处多了*","提示",MB_OK|MB_ICONINFORMA TION);flag=1;}elseif(ch[0]=='/'){flag=0;MessageBox(NULL,"输入表达式不符合文法0","错误",MB_OK|MB_ICONERROR);MessageBox(NULL,"开始处多了/","提示",MB_OK|MB_ICONINFORMA TION);flag=1;}elseif(ch[0]==')'){flag=0;MessageBox(NULL,"输入表达式不符合文法0","错误",MB_OK|MB_ICONERROR);MessageBox(NULL,"开始处多了)","提示",MB_OK|MB_ICONINFORMA TION);flag=1;}/*上述为对第一个字符的特殊处理*/elseif(ch[i]!=NULL){if(ch[i]=='('){i++;F(ch);程序代码if(ch[i]!=')'){if(flag==0){MessageBox(NULL,"输入表达式不符合文法1","错误",MB_OK|MB_ICONERROR);MessageBox(NULL,"少了')'","提示",MB_OK|MB_ICONINFORMATION);}flag=1;}else{i++;if(ch[i]!=NULL)T(ch);}}elseif(ch[i]<='9'&&ch[i]>='0'){while(ch[i]<='9'&&ch[i]>='0')i++;if(ch[i]!=NULL)T(ch);}else{if(flag==0){if(ch[i]!=NULL&&ch[i]!=')'){MessageBox(NULL,"输入表达式不符合文法2.1","错误",MB_OK|MB_ICONERROR);if(ch[i]==' ') MessageBox(NULL,"含有空格","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='+') {MessageBox(NULL,"多了'+'号","提示",MB_OK|MB_ICONINFORMA TION);}else if(ch[i]=='-') MessageBox(NULL,"多了'-'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='*') MessageBox(NULL,"多了'*'号","提示",MB_OK|MB_ICONINFORMA TION);程序代码else if(ch[i]=='/') MessageBox(NULL,"多了'/'号","提示",MB_OK|MB_ICONINFORMA TION);}else if(ch[i]==NULL){MessageBox(NULL,"输入表达式不符合文法2.2","错误",MB_OK|MB_ICONERROR);if(ch[i-1]==' ') MessageBox(NULL,"含有空格","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='+') MessageBox(NULL,"多了最后的'+'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='-') MessageBox(NULL,"多了最后的'-'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='*') MessageBox(NULL,"多了最后的'*'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='/') MessageBox(NULL,"多了最后的'/'号","提示",MB_OK|MB_ICONINFORMA TION);}else if(ch[i]!=NULL&&ch[i]==')'){MessageBox(NULL,"输入表达式不符合文法2.3","错误",MB_OK|MB_ICONERROR);if(ch[i-1]==' ') MessageBox(NULL,"含有空格","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='(') MessageBox(NULL,"含有一对空括号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='+') MessageBox(NULL,"多了最后的'+'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='-') MessageBox(NULL,"多了最后的'-'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='*') MessageBox(NULL,"多了最后的'*'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='/') MessageBox(NULL,"多了最后的'/'号","提示",MB_OK|MB_ICONINFORMA TION);}}flag=1;}}}void T(char ch[]){if(ch[i]=='*'||ch[i]=='/')程序代码{i++;if(ch[i]!=NULL&&ch[i]!='+'&&ch[i]!='-'&&ch[i]!='*'&&ch[i]!='/')F(ch);else{if(flag==0){MessageBox(NULL,"输入表达式不符合文法3","错误",MB_OK|MB_ICONERROR);if(ch[i]==' ') MessageBox(NULL,"含有空格","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='+') MessageBox(NULL,"多了'+'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='-') MessageBox(NULL,"多了'-'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='*') MessageBox(NULL,"多了'*'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='/') MessageBox(NULL,"多了'/'号","提示",MB_OK|MB_ICONINFORMA TION);}flag=1;}}elseE(ch);}void E(char ch[]){if(ch[i]=='+'||ch[i]=='-'){i++;if(ch[i]!=NULL&&ch[i]!='+'&&ch[i]!='-'&&ch[i]!='*'&&ch[i]!='/')F(ch);else{if(flag==0){if(ch[i]!=NULL){MessageBox(NULL,"输入表达式不符合文法4.1","错误",MB_OK|MB_ICONERROR);if(ch[i]==' ') MessageBox(NULL,"含有空格","提示",MB_OK|MB_ICONINFORMA TION);程序代码else if(ch[i]=='+') MessageBox(NULL,"多了'+'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='-') MessageBox(NULL,"多了'-'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='*') MessageBox(NULL,"多了'*'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i]=='/') MessageBox(NULL,"多了'/'号","提示",MB_OK|MB_ICONINFORMA TION);}else if(ch[i]==NULL){MessageBox(NULL,"输入表达式不符合文法4.2","错误",MB_OK|MB_ICONERROR);if(ch[i-1]==' ') MessageBox(NULL,"含有空格","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='+') MessageBox(NULL,"多了最后的'+'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='-') MessageBox(NULL,"多了最后的'-'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='*') MessageBox(NULL,"多了最后的'*'号","提示",MB_OK|MB_ICONINFORMA TION);else if(ch[i-1]=='/') MessageBox(NULL,"多了最后的'/'号","提示",MB_OK|MB_ICONINFORMA TION);}}flag=1;}}else if(ch[i]!=')'){if(flag==0){MessageBox(NULL,"输入表达式不符合文法5","错误",MB_OK|MB_ICONERROR);if(ch[i]=='('&&ch[i+2]==')') MessageBox(NULL,"含有一对多余的括号","提示",MB_OK|MB_ICONINFORMA TION);else MessageBox(NULL,"其他类型的错误","提示",MB_OK|MB_ICONINFORMA TION);}flag=1;}}实验结果分析及心得体会实验结果分析:本次实验借助语法分析,设计一个表达式的判断分析器,从键盘上输入算术表达式,分析器对该表达式的正确与否进行分析。

语法分析实验报告

语法分析实验报告

语法分析实验报告一、实验目的语法分析是编译原理中的重要环节,本次实验的目的在于深入理解和掌握语法分析的基本原理和方法,通过实际操作和实践,提高对编程语言语法结构的分析能力,为进一步学习编译技术和开发相关工具打下坚实的基础。

二、实验环境本次实验使用的编程语言为 Python,使用的开发工具为 PyCharm。

三、实验原理语法分析的任务是在词法分析的基础上,根据给定的语法规则,将输入的单词符号序列分解成各类语法单位,并判断输入字符串是否符合语法规则。

常见的语法分析方法有自顶向下分析法和自底向上分析法。

自顶向下分析法包括递归下降分析法和预测分析法。

递归下降分析法是一种直观、简单的方法,但存在回溯问题,效率较低。

预测分析法通过构建预测分析表,避免了回溯,提高了分析效率,但对于复杂的语法规则,构建预测分析表可能会比较困难。

自底向上分析法主要包括算符优先分析法和 LR 分析法。

算符优先分析法适用于表达式的语法分析,但对于一般的上下文无关文法,其适用范围有限。

LR 分析法是一种功能强大、适用范围广泛的方法,但实现相对复杂。

四、实验内容(一)词法分析首先,对输入的源代码进行词法分析,将其分解为一个个单词符号。

单词符号包括关键字、标识符、常量、运算符、分隔符等。

(二)语法规则定义根据实验要求,定义了相应的语法规则。

例如,对于简单的算术表达式,可以定义如下规则:```Expression > Term | Expression '+' Term | Expression ''TermTerm > Factor | Term '' Factor | Term '/' FactorFactor >'(' Expression ')'| Identifier | Number```(三)语法分析算法实现选择了预测分析法来实现语法分析。

首先,根据语法规则构建预测分析表。

然后,从输入字符串的起始位置开始,按照预测分析表的指导进行分析。

数据结构实验二——算术表达式求值实验报告

数据结构实验二——算术表达式求值实验报告

数据结构实验二——算术表达式求值实验报告算术表达式求值实验报告一、引言算术表达式求值是计算机科学中一个重要的基础问题,它涉及到了数据结构和算法的应用。

本实验旨在通过实现一个算术表达式求值的程序,加深对数据结构中栈的理解和应用,并掌握算术表达式的求值过程。

二、实验目的1. 理解算术表达式的基本概念和求值过程;2. 掌握栈的基本操作和应用;3. 实现一个能够正确求解算术表达式的程序;4. 进一步熟悉编程语言的使用。

三、实验内容1. 设计并实现一个栈的数据结构;2. 实现算术表达式求值的算法;3. 编写测试用例,验证程序的正确性;4. 进行性能测试,分析算法的时间复杂度。

四、实验方法与步骤1. 设计栈的数据结构在本实验中,我们选择使用数组来实现栈的数据结构。

栈的基本操作包括入栈(push)、出栈(pop)、判断栈空(isEmpty)和获取栈顶元素(top)等。

2. 算术表达式求值算法算术表达式求值的一种常用算法是通过后缀表达式进行求值。

具体步骤如下: - 将中缀表达式转换为后缀表达式;- 通过栈来求解后缀表达式;- 返回最终的计算结果。

3. 编写测试用例编写一系列测试用例,包括不同类型的算术表达式,以验证程序的正确性。

例如:- 简单的四则运算表达式:2 + 3 * 4 - 5;- 包含括号的表达式:(2 + 3) * (4 - 5);- 包含多位数的表达式:12 + 34 * 56;- 包含浮点数的表达式:3.14 + 2.71828。

4. 性能测试和时间复杂度分析针对不同规模的输入数据,进行性能测试,记录程序的运行时间。

同时,分析算法的时间复杂度,验证算法的效率。

五、实验结果与分析我们设计并实现了一个栈的数据结构,并成功地完成了算术表达式求值的程序。

通过对一系列测试用例的验证,我们发现程序能够正确地求解各种类型的算术表达式,并返回正确的计算结果。

在性能测试中,我们对不同规模的输入数据进行了测试,并记录了程序的运行时间。

算术表达式求值实验报告

算术表达式求值实验报告

算术表达式求值实验报告1. 背景算术表达式求值是计算机科学中的基本问题之一,涉及到对数学表达式的解析和计算。

在计算机编程中,经常需要对用户输入的数学表达式进行求值,以得到正确的计算结果。

因此,研究如何高效地求解算术表达式是非常重要的。

在本次实验中,我们将探索不同方法来求解算术表达式,并比较它们的性能和准确性。

我们将使用Python语言作为实现工具,并通过编写代码来实现不同方法。

2. 分析2.1 表达式解析在进行表达式求值之前,我们首先需要对输入的数学表达式进行解析。

解析过程主要包括以下几个步骤:1.去除空格:将输入的字符串中的空格字符去除。

2.分词:将字符串按照运算符和操作数进行分割,得到一个由标记组成的列表。

3.构建语法树:根据分词结果构建一个语法树,用于表示数学表达式的结构。

4.求值:通过遍历语法树并执行相应操作,最终得到表达式的值。

2.2 求值方法在本次实验中,我们将尝试以下两种不同的求值方法:1.递归求值:通过递归地遍历语法树来求解表达式。

递归求值的优点是简单易懂,但可能存在性能问题。

2.栈求值:使用栈数据结构来辅助求解表达式。

栈可以有效地处理运算符的优先级和括号的匹配问题。

2.3 性能评估为了评估不同方法的性能,我们将使用一组测试用例来对其进行比较。

测试用例包括不同长度和复杂度的数学表达式,以及各种运算符和括号的组合。

我们将使用Python内置的time模块来测量每种方法的执行时间,并比较它们之间的差异。

此外,我们还将检查每种方法是否能正确地计算出表达式的结果。

3. 实验结果3.1 表达式解析在实现表达式解析过程时,我们首先去除输入字符串中的空格,并将其转换为一个字符列表。

然后,我们使用递归下降法来构建语法树。

具体而言,我们定义了以下几个函数:1.parse_expression(tokens):该函数接受一个标记列表作为参数,并返回一个表示整个表达式的语法树。

2.parse_term(tokens):该函数接受一个标记列表作为参数,并返回一个表示项的语法树。

语法分析实验报告

语法分析实验报告

语法分析实验报告一、语法分析功能与目的语法分析是编译过程的核心部分,它的主要任务是按照程序语言的语法规则,从由词法分析输出的源程序符号串中识别出各类语法成分,同时进行语法检查,为语义分析和代码生成作准备。

执行语法分析任务的程序叫语法分析程序或语法分析器。

语法分析程序以词法分析输出的符号串作为输入,在分析过程中检查这个符号串是否为该程序语言的句子。

如是,则输出该句子的分析数,否则就表示源程序存在语法错误,需要报告错误的性质和位置。

二、TEST语法规则①<程序>∶∶={<声明序列><语句序列>}②<声明序列>∶∶=<声明序列><声明语句>|ε③<声明语句>∶∶=int <标识符>;④<语句序列>::=<语句序列><语句>|ε⑤<语句>::=<if语句>|<while语句>|<do语句>|<for语句>|<read语句>|<write语句>|<复合语句>|<表达式语句>⑥<if语句>::=if(<表达式>)<语句>[else<语句>]⑦<while语句>::=while(<表达式>)<表达式>⑧<for语句>:=for(<表达式>;<表达式>;<表达式>)<语句>⑨<write语句>::=write<表达式>;⑩<read语句>::=read<标识符>;⑴<复合语句>::={<语句序列>}⑵<表达式语句>:=<表达式>;|;⑶<表达式>::=<标识符>=<布尔表达式>|<布尔表达式>⑷<布尔表达式>:=<算术表达式>|<算术表达式>(>|<|>=|<=|==|!=)<算术表达式>⑸<算术表达式>::=<项>{(+|-)<项>}⑹<项>::=<因子>{(*|/)<因子>}⑺<因子>::=(<表达式>)|<标识符>|<无符号整数>⑻<do语句>::=do<语句>while(<表达式>);三、实验四要求及改进思路实验要求:修改词法分析程序TESTscan.c和语法分析程序TESTparse.c这二个文件,使该程序能分析:(1) do语句(有关文法规则参见P77的习题8。

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

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

编译原理语法分析实验报告编译原理实验报告二、语法分析(一) 实验题目编写程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析。

(二) 实验内容和要求1. 要求程序至少能分析的语言的内容有:1) 变量说明语句2) 赋值语句3) 条件转移语句4) 表达式(算术表达式和逻辑表达式)5) 循环语句6) 过程调用语句2. 此外要处理:包括依据文法对句子进行分析;出错处理;输出结果的构造。

3. 输入输出的格式:输入:单词文件(词法分析的结果)输出:语法成分列表或语法树(都用文件表示),错误文件(对于不合文法的句子)。

4. 实现方法:可以采用递归下降分析法,LL(1)分析法,算符优先法或LR分析法的任何一种,也可以针对不同的句子采用不同的分析方法。

(三) 实验分析与设计过程1. 待分析的C语言子集的语法:该语法为一个缩减了的C语言文法,估计是整个C语言所有文法的60%(各种关键字的定义都和词法分析中的一样),具体的文法如下:语法:100: program -> declaration_list101: declaration_list -> declaration_list declaration | declaration 102: declaration -> var_declaration|fun_declaration103: var_declaration -> type_specifier ID;|type_specifier ID[NUM]; 104: type_specifier -> int|void|float|char|long|double|105: fun_declaration -> type_specifier ID (params)|compound_stmt 106: params -> params_list|void107: param_list ->param_list,param|param108: param -> type-spectifier ID|type_specifier ID[]109: compound_stmt -> {local_declarations statement_list}110: local_declarations -> local_declarations var_declaration|empty 111: statement_list -> statement_list statement|empty11编译原理实验报告112: statement -> epresion_stmt|compound_stmt|selection_stmt|iteration_stmt|return_stmt113: expression_stmt -> expression;|;114: selection_stmt -> if{expression)statement|if(expression)statement else statement115: iteration_stmt -> while{expression)statement116: return_stmt -> return;|return expression;117: expression -> var = expression|simple-expression118: var -> ID |ID[expression]119: simple_expression ->additive_expression relop additive_expression|additive_expression 120: relop -> <=|<|>|>=|= =|!=121: additive_expression -> additive_expression addop term | term 122: addop -> + | -123: term -> term mulop factor | factor124: mulop -> *|/125: factor -> (expression)|var|call|NUM126: call -> ID(args)127: args -> arg_list|empty128: arg_list -> arg_list,expression|expression该文法满足了实验的要求,而且多了很多的内容,相当于一个小型的文法说明:把文法标号从100到128是为了程序中便于找到原来的文法。

数据类型、运算符和表达式实验报告

数据类型、运算符和表达式实验报告

广州大学实验报告学院商学院专业、班级姓名、学号课程名称C程序设计项目名称数据类型、运算符和表达式实验实验时间:2012 年 3 月20 日数据类型、运算符和表达式实验报告开课实验室:2012年3月20日d=5.670000,e=-6.780000f=1234.567890,g=0.123457m=50000,n=-600000p=32768,q=40000第3页四、实验结果及分析实验一输出结果为:a,b值互换。

分析:在C程序设计中,两个值互换需要一个中间变量来储存数据,如果直接交换会导致其中一个数据丢失。

实验二分析:实验二为自己设计的程序。

在设计这个程序是要注意scanf的用法。

Scanf 为格式输入符,在输入字符时要注意字符输入方式。

在本次实验中其调用格式为:scanf("<格式化字符串>",<地址表>);实验三分析:输出格式的不同会导致输出结果的不同。

将负数赋值给无符号变量时,无符号变量会将这个负值的符号也纳入计算范围从而返回一个正值,导致最后输出结果不正确。

这个实验让我认识到在设计程序时要注意输出格式的选择。

实验四分析:实验四更加强调个语句中在程序的含义。

程序为:printf("d=% f,e=% f\n",d,e);printf("f=% f,g=% f\n",f,g);输出结果为:当程序改为:printf("d=%-6.2f,e=%-6.2f\n",d,e);printf("f=%-15.6f,g=%-15.10f\n",f,g);输出结果为:继续将程序改边为:printf("d=%-6.2f\te=%-6.2f\n",d,e);printf("f=%-15.6f\tg=%-15.10f\n",f,g);输出结果为:以上3种都是改变了输出格式使输出数据的有效数字改变。

数据结构实验二——算术表达式求值实验报告

数据结构实验二——算术表达式求值实验报告

《数据结构与数据库》实验报告实验题目算术表达式求值学院:化学与材料科学学院专业班级:09级材料科学与工程系PB0920603姓名:李维谷学号:PB09206285邮箱:liwg@指导教师:贾伯琪实验时间:2010年10月10日一、需要分析问题描述:表达式计算是实现程序设计语言的基本问题之一,它的实现是栈的应用的一个典型例子。

设计一个程序,演示通过将数学表达式字符串转化为后缀表达式,并通过后缀表达式结合栈的应用实现对算术表达式进行四则混合运算。

问题分析:在计算机中,算术表达式由常量、变量、运算符和括号组成。

由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行。

因而在程序设计时,借助栈实现。

设置运算符栈(字符型)和运算数栈(浮点型)辅助分析算符优先关系。

在读入表达式的字符序列的同时完成运算符和运算数的识别处理,然后进行运算数的数值转换在进行四则运算。

在运算之后输出正确运算结果,输入表达式后演示在求值中运算数栈内的栈顶数据变化过程,最后得到运算结果。

算法规定:输入形式:一个算术表达式,由常量、变量、运算符和括号组成(以字符串形式输入)。

为使实验更完善,允许操作数为实数,操作符为(、)、.(表示小数点)、+、-、*、/、^(表示乘方),用#表示结束。

输出形式:演示表达式运算的中间结果和整个表达式的最终结果,以浮点型输出。

程序功能:对实数内的加减乘除乘方运算能正确的运算出结果,并能正确对错误输入和无定义的运算报错,能连续测试多组数据。

测试数据:正确输入:12*(3.6/3+4^2-1)#输出结果:194.4无定义运算:12*(3.6/(2^2-4)+1)# 输出结果:表达式出错,除数为0,无意义 错误输入:12+s# 输出结果:ERROR ! 二、 概要设计拟采用两种类型的展分别对操作数和操作符进行操作。

程序中将涉及下列两个抽象数据类型:1、设定“操作数”的栈的抽象数据类型定义: ADT SqStack_f{数据对象:D={i a },+∈∈N i R a i数据关系:R1={<1,-i i a a >|1-i a ,D a i ∈,i=2,…,n}约定n a 端为栈顶,i a 端为栈底。

算术表达式实验报告

算术表达式实验报告

本科学生综合性实验报告项目组长:学号:成员:专业:计算机科学与技术班级:B02实验项目名称算术表达式求值指导教师及职称:开课学期2011-2012学年第一学期上课时间2011年10月15日-2011年11月5日一、实验设方案实验名称:算术表达式求值实验时间:2010年10月15 日小组合作:是●否○小组成员:0103356吴荣福0103316 倪志鹏1、实验目的实验目的:写代码来计算算术表达式2、实验思路(实验内容、数据处理方法及实验步骤等)#include <stdio.h>#include <stdlib.h>#include <conio.h>#define size 100#define addsize 20typedef int selemtype;typedef int status;typedef struct{selemtype *base;selemtype *top;int stacksize;}sqstack;//构造空栈status initstack(sqstack &l){l.base=(selemtype *)malloc(size*sizeof(selemtype));if(!l.base) exit(0);l.top=l.base;l.stacksize=size;return 1;}//返回栈顶元素status gettop(sqstack s){selemtype e;if(!s.top) return 0;e=*(s.top-1);return e;;}//进栈status push(sqstack &l,selemtype e){if(l.top-l.base>=l.stacksize){l.base=(selemtype*)realloc(l.base,l.stacksize+addsize*sizeof(selemtype));if(!l.base) exit(0);l.top=l.base+l.stacksize;l.stacksize+=addsize;}*l.top++=e;return 1;}//出栈status pop(sqstack &l,selemtype &e){if(l.top==l.base) return 0;e=*--l.top;return e;}//判断是不是运算符status ischar(char c){if(c=='+'||c=='-'||c=='*'||c=='/'||c=='#'||c=='('||c==')')return 1;elsereturn 0;}//判断优先级char youxian(char m,char n){int a,b;switch(m){case '+':case '-':a=6; break;case '*':case '/':a=9; break;case '(':a=5; break;case '#':a=-1; break;}switch(n){case '+':case '-':b=7; break;case '*':case '/':b=8; break;case ')':b=5; break;case '(':b=7;break;case '#':b=-1;break;}if(a>b)return '>';if(a<b)return '<';elsereturn '=';}//计算函数selemtype operate(selemtype a,selemtype m,selemtype b){ selemtype s;switch(m){case '+':s=(a+b);break;case '-':s=(a-b);break;case '*':s=(a*b);break;case '/':s=(a/b);break;}return s;}//主函数void main(){char ch[5];ch[0]='Y';do{printf("输入:\n");sqstack a,b;char c;selemtype x,y,theta;initstack(a); push(a,'#');initstack(b); c=getchar();while(c!='#' || gettop(a)!='#'){if(!ischar(c)){push(b,c-'0');c=getchar();}else{switch(youxian(gettop(a),c)){case '<':push(a,c);c=getchar();break;case '=':pop(a,x);c=getchar();break;case '>':pop(a,theta);pop(b,y);pop(b,x);push(b,operate(x,theta,y));break;}}}getchar();printf("结果是:");printf("%d\n",gettop(b));printf("是否继续(Y/N):");gets(ch);}while(ch[0]=='Y'||ch[0]=='y');printf("*************************\n");}指导老师对实验设计方案的意见指导老师签名:年月日二、实验结果与分析1、实验目的、实验思路。

编译原理实验二LL(1)语法分析实验报告

编译原理实验二LL(1)语法分析实验报告

专题3_LL(1)语法分析设计原理与实现李若森 13281132 计科1301一、理论传授语法分析的设计方法和实现原理;LL(1) 分析表的构造;LL(1)分析过程;LL(1)分析器的构造。

二、目标任务实验项目实现LL(1)分析中控制程序(表驱动程序);完成以下描述算术表达式的 LL(1)文法的LL(1)分析程序。

G[E]:E→TE’E’→ATE’|εT→FT’T’→MFT’|εF→(E)|iA→+|-M→*|/设计说明终结符号i为用户定义的简单变量,即标识符的定义。

加减乘除即运算符。

设计要求(1)输入串应是词法分析的输出二元式序列,即某算术表达式“专题 1”的输出结果,输出为输入串是否为该文法定义的算术表达式的判断结果;(2)LL(1)分析程序应能发现输入串出错;(3)设计两个测试用例(尽可能完备,正确和出错),并给出测试结果。

任务分析重点解决LL(1)表的构造和LL(1)分析器的实现。

三、实现过程实现LL(1)分析器a)将#号放在输入串S的尾部b)S中字符顺序入栈c)反复执行c),任何时候按栈顶Xm和输入ai依据分析表,执行下述三个动作之一。

构造LL(1)分析表构造LL(1)分析表需要得到文法G[E]的FIRST集和FOLLOW集。

构造FIRST(α)构造FOLLOW(A)构造LL(1)分析表算法根据上述算法可得G[E]的LL(1)分析表,如表3-1所示:表3-1 LL(1)分析表主要数据结构pair<int, string>:用pair<int, string>来存储单个二元组。

该对照表由专题1定义。

map<string, int>:存储离散化后的终结符和非终结符。

vector<string>[][]:存储LL(1)分析表函数定义init:void init();功能:初始化LL(1)分析表,关键字及识别码对照表,离散化(非)终结符传入参数:(无)传出参数:(无)返回值:(无)Parse:bool Parse( const vector<PIS> &vec, int &ncol );功能:进行该行的语法分析传入参数:vec:该行二元式序列传出参数:emsg:出错信息epos:出错标识符首字符所在位置返回值:是否成功解析。

语法、语义分析实验报告

语法、语义分析实验报告

河海大学物联网工程学院编译原理课程实践学年学期2015-2016第二学期实验名称语法分析、语义分析作者1362810225刘云瞻组员刘云瞻华路授课班号6282506专业计算机科学与技术13级指导教师金永霞2016年6月目录1.引言 ..........................................................................................- 3 -1.1 实验目的 ..........................................................................- 3 -1.2 实践内容 ..........................................................................- 3 -2.算法设计.............................................................................- 3 -2.1 语法分析 ..........................................................................- 4 -2.1.1 生成(非)终结符表.............................................- 4 -2.1.2 构造FirstVT集和LastVT集...............................- 4 -2.1.4 算符优先分析.........................................................- 7 -2.2 语义分析 ....................................................................... - 10 -2.2.1 算术表达式和简单赋值语句的翻译 ................. - 10 -3. 运行结果与测试.................................................................... - 11 -3.1 运行结果 ........................................................................ - 11 -3.2 错误测试 ....................................................................... - 13 -4.心得体会.......................................................................... - 14 -1.引言1.1 实验目的通过使用高级语言实现部分算法加强对编译技术和理论的理解。

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

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

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

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

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

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

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

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

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

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

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

程序:(其余的你们自己写)void main() //主函数{int len;int f=1;cout<<endl<<"请输入一个算术表达式(请在一行内完成输入且每个项的长度不大于10):"<<endl;gets(str);len = strlen(str);str[len] = '^';cout<<endl;system("pause");cout<<endl;cout<<"***********************词法分析开始*****************"<<endl;f = cifa_main();if ( f == 0 ) return;cout<<endl;system("pause");cout<<endl;cout<<"***********************语法分析开始*****************"<<endl;f = yufa_main();if (f== 0) return;cout<<endl;system("pause");cout<<endl;}int F1() //F -> (E) | 标识符| 无符号整数{if ((strcmp(cifa_p->word,"(") == 0 ) ){advance();strcpy(F_name,cifa_p->word);strcpy(E_name,F_name);E1();if ((strcmp(cifa_p->word,")") == 0 ) ){advance();strcpy(F_name,E_name);return (1);}else{cout<<"ERROR"<<endl;return (0);}}else if ( cifa_p->type == 1 || cifa_p->type == 2) {strcpy(F_name,cifa_p->word);advance();return (1);}else return 0;}int T1() //T -> F*T | F/T | F{yuyi *p = new yuyi;F1();strcpy(p->op1,F_name);if (strcmp(cifa_p->word,"*") == 0) {advance();T1();p->next =NULL;p->op = '*';strcpy(p->op2,T_name);T_name[0] = 't';T_name[1] = ++count;T_name[2] = '\0';strcpy(p->result,T_name);yuyi_add(p);return(1);}else if (strcmp(cifa_p->word,"/") == 0) {advance();T1();p->next =NULL;p->op = '/';strcpy(p->op2,T_name);T_name[0] = 't';T_name[1] = ++count;T_name[2] = '\0';strcpy(p->result,T_name);yuyi_add(p);return(1);}else{strcpy(T_name,F_name);return(1);}}int E1() //E -> T+E | T-E | T {yuyi *p = new yuyi;T1();strcpy(p->op1,T_name);if (strcmp(cifa_p->word,"+") == 0) {advance();E1();p->next =NULL;p->op = '+';strcpy(p->op2,E_name);E_name[0] = 't';E_name[1] = ++count;E_name[2] = '\0';strcpy(p->result,E_name);yuyi_add(p);return (1);}else if (strcmp(cifa_p->word,"-") == 0){advance();E1();p->next =NULL;p->op = '-';strcpy(p->op2,E_name);E_name[0] = 't';E_name[1] = ++count;E_name[2] = '\0';strcpy(p->result,E_name);yuyi_add(p);return(1);}else{strcpy(E_name,T_name);return(1);}}int yufa_main() //语法分析主程序{int n;cifa *p = new cifa;strcpy(p -> word ,"#"); //对词法分析产生的结果链表进行处理p -> type =-1;p -> next = NULL;cifa_add(p);cifa_p = cifa_head;cout<<endl;yufa_zfc_disp(cifa_head->next);cout<<"的递归分析过程如下:"<<endl;cout<<endl<<"-------------------------------------------------"<<endl;cout<<'\t'<<"步骤\t"<<'\t'<<"产生式"<<endl;advance();n = E();if (n == 0){cout<<'\t'<<f<<'\t'<<'\t'<<"输入串不是该文法的一个句子!"<<endl;cout<<endl<<"------------------语法分析结束------------------"<<endl;return (0);}else if (n == 1){cout<<'\t'<<f<<'\t'<<'\t'<<"输入串是该文法的一个句子!"<<endl;cout<<endl<<"------------------语法分析结束--------------"<<endl;return (1);}}//**********************语义分析*************************************** yuyi *yuyi_add(yuyi *p) //在四元式链表末添加一个结点{yuyi_end->next = p ;yuyi_end = p;return yuyi_head;}void yuyi_sys_disp() //输出四元式链表{yuyi *p;p = yuyi_head->next;while(p!=NULL){ cout<<'('<<'\t'<<p->op<<','<<'\t'<<p->op1<<','<<'\t'<<p->op2<<','<<'\t'<<p->result<<'\t'<<')'< <endl;p = p->next;}cout<<endl;}int F() // F -> (E) | 标识符| 无符号整数子函数{int m;if ((strcmp(cifa_p->word,"(") == 0 ) ){cout<<'\t'<<f++<<'\t'<<'\t'<<"F -> (E)"<<endl;advance();m =E();if (m==0) return (0);if ((strcmp(cifa_p->word,")") == 0 ) ){advance();return (1);}else{cout<<"ERROR"<<endl;return (0);}}else if ( cifa_p->type == 1 || cifa_p->type == 2) //数字或是标识符{cout<<'\t'<<f++<<'\t'<<'\t'<<"F -> 标识符|无符号整数"<<endl; advance();return (1);}else return 0;}int S() // S -> *FS | /FS |ε子函数{int t,g;if (strcmp(cifa_p->word,"*") == 0){cout<<'\t'<<f++<<'\t'<<'\t'<<"S -> *FS"<<endl;advance();t = F();if (t== 0) return 0;g = S();if (g == 0) return 0;return(1);}else if (strcmp(cifa_p->word,"/") == 0){cout<<'\t'<<f++<<'\t'<<'\t'<<"S -> /FS"<<endl;advance();t = F();if (t== 0) return 0;g = S();if (g == 0) return 0;return(1);}else if (strcmp(cifa_p->word,"+") == 0 ||(strcmp(cifa_p->word,"-") == 0)||(strcmp(cifa_p->word,"#") == 0)||(strcmp(cifa_p->word,")") == 0)){cout<<'\t'<<f++<<'\t'<<'\t'<<"S -> ε"<<endl;return(1);}return (0);}int T() // T -> FS 子函数{int t,g;cout<<'\t'<<f++<<'\t'<<'\t'<<"T -> FS"<<endl;t = F();if (t== 0) return 0;g = S();if (g == 0) return 0;return(1);}int G() // G -〉+TG | -TG |ε子函数{int t,g;if (strcmp(cifa_p->word,"+") == 0){cout<<'\t'<<f++<<'\t'<<'\t'<<"G -> +TG"<<endl;advance();t=T();if (t == 0) return(0);g=G();if ( g== 0) return (0);return (1);}else if (strcmp(cifa_p->word,"-") == 0){cout<<'\t'<<f++<<'\t'<<'\t'<<"G -> -TG"<<endl;advance();t=T();if (t == 0) return(0);g=G();if (g == 0) return (0);return(1);}else if (strcmp(cifa_p->word,")") == 0 || strcmp(cifa_p->word,"#") == 0){cout<<'\t'<<f++<<'\t'<<'\t'<<"G -> ε"<<endl;return(1);}return (0);}int E() // E -> [+|-]TG 子函数{int t,g;if ((strcmp(cifa_p->word,"+") == 0)|| (strcmp(cifa_p->word,"-") == 0)) advance(); cout<<'\t'<<f++<<'\t'<<'\t'<<"E -> [+|-]TG"<<endl;t = T();if (t == 0) return (0);g = G();if (g == 0) return (0);else return (1);}void yufa_zfc_disp(cifa *p) //输出字符串{while(p!=NULL){cout<<p->word ;p = p->next;}// cout<<endl;}//************************语法分析部分***************************************void advance() //取词法分析产生列表中的结点作语法分析{cifa_p = cifa_p -> next;}int test(void) //识别相关符号{char temp[3];int i=0;int type;switch (ch){case ';' : //识别';'{temp[i++] = ch;GetChar();if (ch ==' ' ) temp[i++] =' ';temp[i] = '\0';type = 4;break;case '+' : //识别'+'{temp[i++] = ch;GetChar();if (ch ==' ' ) temp[i++] =' '; temp[i] = '\0';type = 3;break;}case '-' : //识别'-'{temp[i++] = ch;GetChar();if (ch ==' ' ) temp[i++] =' '; temp[i] = '\0';type = 3;break;}case '*' : //识别'*'{temp[i++] = ch;GetChar();if (ch ==' ' )temp[i++] =' ';temp[i] = '\0';type = 3;break;}case '/' : //识别'/'temp[i++] = ch; GetChar();if (ch ==' ' )temp[i++] =' '; temp[i] = '\0';type = 3;break;}case '(' : //识别'(' {temp[i++] = ch; GetChar();if (ch ==' ' )temp[i++] =' '; temp[i] = '\0';type = 4;break;}case ')' : // 识别')' {temp[i++] = ch; GetChar();if (ch ==' ' )temp[i++] =' ';temp[i] = '\0'; type = 4;break;}default :{ cout<<ch;cout<<"无法识别,出错!"<<endl;GetChar();if (ch == ' ') notock();return (0);}}if (ch == ' ') notock(); // 空格跳过cifa *p;p = new cifa;p -> next = NULL;p -> type = type;strcpy(p->word,temp);cifa_add(p);return (1);}int cifa_main() //词法分析主函数{int f;cifa_head = new cifa;cifa_head -> type = -1;cifa_head -> next = NULL;cifa_end = cifa_head;cout<<"单词种类定义如下:"<<endl<<endl;cout<<"标识符的种类编码1 :"<<endl<<endl;cout<<"常数的种类编码2 :"<<endl<<endl;cout<<"运算的种类编码3 :+ ,- ,* ,/ "<<endl<<endl; cout<<"界限符的种类编码4 : (,),;"<<endl; GetChar();notock();cout<<"--------------------------------------------------------"<<endl<<"词法分析结果如下:"<<endl;while ( nn < 100 && ch != '^'){if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') )f=alph(); //字母串else if (ch >= '0' && ch <= '9') f=number(); //数字串else f=test();//其他符号if (f == 0) return (0);}cifa_disp(cifa_head);cout<<endl<<"--------------词法分析结束---------------------"<<endl;return (1);}int number(void) //识别数字{int type=2;int i=0;char temp[10];while('0'<= ch && ch <= '9'){temp[i] = ch;i++;GetChar();}temp[i]='\0';if (ch == ' ') notock();else if (ch != '^' && ch != '+' && ch != '-' && ch != ';' && ch != '*' && ch != '/' && ch != '('&& ch != ')'){cout<<temp<<"接错误后缀,出错"<<endl;return (0);}if (ch == ' ') notock();cifa *p;p = new cifa;p -> next = NULL;p -> type = type;strcpy(p->word,temp);cifa_add(p);return (1);}int alph(void) //识别标识符{int i=0;char temp[10];int type = 1;temp[i] = ch;i++;GetChar();while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')){temp[i] = ch;i++;GetChar();}temp[i] = '\0';if (ch == ' ') notock();else if (ch != '^' && ch != '+' && ch != '-' && ch != ';' &&ch != '*' && ch != '/' && ch != '('&& ch != ')'){cout<<temp<<"接错误后缀,出错"<<endl;return 0;}cifa *p;p = new cifa;p -> next = NULL;p -> type = type;strcpy(p->word,temp);cifa_add(p);return (1);}cifa *cifa_add(cifa *p) //在分析结果列表尾添加一个新接点{cifa_end -> next = p;cifa_end = cifa_end -> next;return cifa_head;}void cifa_disp(cifa *cifa_head) //输出词法分析结果{cifa *p;p = cifa_head -> next ;while ( p != NULL){cout<<'('<<'\t'<<p->type<<'\t'<<','<<'\t'<<p->word<<'\t'<<')'<<endl; p = p ->next;}}void GetChar() //取字符{ch = str[nn];nn++;}void notock() //去掉空格{if ( ch == ' ' )while ( ch == ' ' )GetChar();}char E_name[10],T_name[10],F_name[10],temp_name[10];//在求四元式的时候用来传递信息yuyi *yuyi_add(yuyi *p); //在四元式链表末添加一个结点void yuyi_sys_disp(); //输出四元式链表int E1(); //E -> T+E | T-E | Tint T1(); //T -> F*T | F/T | Fint F1(); //F -> (E) | 标识符| 无符号整数void yuyi_main(); //语义分析主函数//**********************词法分析部分*********************************//***********************语义分析部分数据结构及函数定义***************** struct yuyi //语义结构体{char op; //操作符char op1[10]; //第一个操作数char op2[10]; //第二个操作数char result[10]; //结果yuyi *next;};yuyi *yuyi_head,*yuyi_end,*yuyi_q,*yuyi_vt; //yuyi队列//***********************语法分析部分函数定义***************** void advance(); //取词法分析产生列表中的结点作语法分析int E(); // E -> [+|-]TG 子函数int G(); // G -〉+TG | -TG |ε子函数int T(); // T -> FS 子函数int S(); // S -> *FS | /FS |ε子函数int F(); // F -> (E) | 标识符| 无符号整数子函数int yufa_main(); //语法分析主函数cifa *cifa_add(cifa *p); //在分析结果列表尾添加一个新接点void cifa_disp(cifa *cifa_head); //输出词法分析结果void GetChar(); //取字符void notock(); //去掉空格int alph(void); //识别标识符int number(void); //识别数字int test(void); //识别相关符号int cifa_main(); //词法分析主函数#include <stdio.h>#include <string.h>#include <ctype.h>#include <malloc.h>#include <math.h>#include <cstdio>#include <iostream.h>#include <cstdlib>#include <fstream>#include <cmath>char str[100]; //输入的算术表达式字符串char ch;int nn=0; //字符串计数器int f=0;算术表达式语法检查实验报告char count='0'; //四元式临时变量计数器//***********************词法分析部分数据结构及函数定义*****************struct cifa //词法结构体{int type; //类型char word[10]; //字符串内容cifa *next;};cifa *cifa_head,*cifa_end,*cifa_p; //cifa队列三、课程设计的进程安排1.2015年5月8日(第9周):布置并下达课程设计题目。

相关文档
最新文档