TEST语言-语法分析,词法分析实验报告

合集下载

词法分析实验报告

词法分析实验报告

词法分析实验报告词法分析实验报告引言词法分析是自然语言处理中的一个重要环节,它负责将输入的文本分割成一个个的词语,并确定每个词语的词性。

本次实验旨在通过实现一个简单的词法分析器,来探索词法分析的原理和实践。

实验内容本次实验中,我们使用Python编程语言来实现词法分析器。

我们选取了一段简单的英文文本作为输入,以便更好地理解和演示词法分析的过程。

1. 文本预处理在进行词法分析之前,我们首先需要对输入文本进行预处理。

预处理的目的是去除文本中的标点符号、空格和其他无关的字符,以便更好地进行后续的分词操作。

2. 分词分词是词法分析的核心步骤之一。

在这个步骤中,我们将文本分割成一个个的词语。

常见的分词方法包括基于规则的分词和基于统计的分词。

在本次实验中,我们选择了基于规则的分词方法。

基于规则的分词方法通过事先定义一系列的分词规则来进行分词。

这些规则可以是基于语法的,也可以是基于词典的。

在实验中,我们使用了一个简单的基于词典的分词规则,即根据英文单词的常见前缀和后缀来进行分词。

3. 词性标注词性标注是词法分析的另一个重要步骤。

在这个步骤中,我们为每个词语确定其词性。

词性标注可以通过事先定义的规则和模型来进行。

在本次实验中,我们使用了一个简单的基于规则的词性标注方法。

基于规则的词性标注方法通过定义一系列的词性标注规则来进行词性标注。

这些规则可以是基于词法的,也可以是基于语法的。

在实验中,我们使用了一个简单的基于词法的词性标注规则,即根据英文单词的后缀来确定其词性。

实验结果经过实验,我们得到了输入文本的分词结果和词性标注结果。

分词结果如下:- I- love- natural- language- processing词性标注结果如下:- I (代词)- love (动词)- natural (形容词)- language (名词)- processing (名词)讨论与总结通过本次实验,我们深入了解了词法分析的原理和实践。

语法法分析实验报告

语法法分析实验报告

一、实验目的1. 理解语法分析的基本概念和原理。

2. 掌握语法分析器的构建方法。

3. 培养实际操作能力,提高编程水平。

二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.83. 开发工具:PyCharm三、实验内容1. 语法分析概述2. 词法分析3. 语法分析4. 实验实现四、实验步骤1. 语法分析概述(1)了解语法分析的定义、作用和意义。

(2)掌握语法分析的基本原理和流程。

2. 词法分析(1)编写词法分析器代码,将源代码分解成单词序列。

(2)实现词法分析器的各个功能,如:识别标识符、关键字、运算符等。

3. 语法分析(1)设计语法分析器,将单词序列转换为抽象语法树(AST)。

(2)实现语法分析器的各个功能,如:识别表达式、语句、函数等。

4. 实验实现(1)创建Python项目,导入相关库。

(2)编写词法分析器代码,实现单词序列的分解。

(3)编写语法分析器代码,实现抽象语法树的构建。

(4)测试语法分析器,验证其正确性。

五、实验结果与分析1. 词法分析结果实验中,我们成功地将源代码分解成单词序列,包括标识符、关键字、运算符等。

词法分析器的输出结果如下:```identifier: akeyword: intoperator: +identifier: boperator: =integer: 5```2. 语法分析结果通过语法分析器,我们将单词序列转换成抽象语法树。

以下是一个示例的抽象语法树:```Program├── Declaration│ ├── Type│ │ ├── Identifier│ │ └── Integer│ └── Identifier│ └── a└── Statement├── Expression│ ├── Identifier│ └── a└── Operator└── =└── Expression├── Identifier└── b└── Integer└── 5```从实验结果可以看出,我们的语法分析器能够正确地将源代码转换为抽象语法树。

语法分析实验报告(1)

语法分析实验报告(1)

语法分析实验报告一.实验目的1. 在语法分析器原理学习和词法分析器实验基础上,自行实现一个高级语言语法分析器,通过实验能够把原理和实现方法应用到如描述语言语法分析等词法分析器的设计中去。

2. 利用c语言编制递归下降分析程序,并对简单语言进行语法分析。

二.实验原理1. 待分析的简单语言的语法:0.txt:ghy.txt2. TEST语法规则:(1)<program>::={<declaration_list><statement_list>}(2) <declaration_list>::=<declaration_list><declaration_stat>|ε(3) <declaration_stat>::=int ID;(4) <statement_list>::=<statement_list><statement>|ε(5)<statement>::=<if_stat>|<while_stat>|<for_stat>|<compound_stat>|<expression_stat>(6) <if_stat>::=if(<expression>)<statement>[else<statement>](7) <while_stat)::=while(<expr>)<statement>(8)<for_stat>::=for(<expression>;<expression>;<expression>)<statement>(9) <write_stat>::=write<expression>(10) <read_stat>::=read<ID>(11) <compound_stat>::={<statement_list>}(12) <expression_stat>::=<exxprssion>;|;(13) <expression>::=ID=<bool_expr>|<bool_expr>(14)<bool_expr>::=<additive_expr>|<additive_expr>(<|>|<=|>=|==|!=)<additive_expr >(15) <additive_expr>::=<term>{+|-)<term>}(16) <term>::=<factor>{*|/)<factor>)(17) <factor>::=(<expression>)|ID|NUM三.实验步骤:1.用VC++编辑、编译和运行教材P221~230的语法分析程序。

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

编译实验报告(语法分析、词法分析)
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.手动编写正则表达式;2.确定有限自动机的状态转移函数;3.实现词法分析程序。

三、实验过程1.手动编写正则表达式对于给定的源程序,我们首先需要根据其语法规则手动编写正则表达式。

例如,对于一个简单的算术表达式,其正则表达式可以如下所示:i. 数字(0-9):[0-9]+ii. 加号(+):\+iii. 减号(-):-iv. 乘号(*):\*v. 除号(/):/vi. 左括号(():\(vii. 右括号()):\)2.确定有限自动机的状态转移函数根据正则表达式,我们可以确定有限自动机的状态转移函数。

例如,对于上述算术表达式的正则表达式,其有限自动机的状态转移函数如下所示:i. 初始状态(S):判断下一个字符,如果是数字则进入数字状态,如果是左括号则进入左括号状态;ii. 数字状态(D):继续判断下一个字符,如果是数字则保持在数字状态,如果是运算符则输出数字记号,返回初始状态,如果是右括号则输出数字记号,返回初始状态;iii. 左括号状态(L):输出左括号记号,返回初始状态;iv. 右括号状态(R):输出右括号记号,返回初始状态。

3.实现词法分析程序根据以上的正则表达式和有限自动机的状态转移函数,我们可以编写一个简单的词法分析程序。

该程序的主要流程如下所示:i. 读取源程序的字符序列;ii. 根据有限自动机的状态转移函数,逐个字符进行状态转移;iii. 如果当前状态为接受状态,则输出相应的记号;iv. 继续进行状态转移,直至读取完整个源程序。

四、实验结果通过以上步骤,我们成功完成了对给定源程序的词法分析。

词法分析器语法分析器实验报告(编译原理超实用)

词法分析器语法分析器实验报告(编译原理超实用)

山东大学编译技术课程设计班级软件一班学号**********XX姓名软件一班万岁指导老师贺老师二零一一年三月一、目的<<编译技术>>是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。

从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。

二、任务及要求基本要求:1.词法分析器产生下述小语言的单词序列这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表:对于这个小语言,有几点重要的限制:首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。

所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。

例如,下面的写法是绝对禁止的:IF(5)=x其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。

也就是说,对于关键字不专设对应的转换图。

但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。

当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。

再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。

例如,一个条件语句应写为IF i>0 i= 1;而绝对不要写成IFi>0 i=1;因为对于后者,我们的分析器将无条件地将IFI看成一个标识符。

这个小语言的单词符号的状态转换图,如下图:2.语法分析器能识别由加+ 减- 乘* 除/ 乘方^ 括号()操作数所组成的算术表达式,其文法如下:E→E+T|E-T|TT→T*F|T/F|FF→P^F|Pp→(E)|i使用的算法可以是:预测分析法;递归下降分析法;算符优先分析法;LR分析法等。

3.中间代码生成器产生上述算术表达式的中间代码(四元式序列)三、实现过程说明给出各题目的详细算法描述,数据结构和函数说明,流程图。

语法分析实验报告

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

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。

语法分析-实验报告

《编译系统设计实践》实验项目二:语法分析指导老师:**组长:030902336组员:030902246030902335一、实验目的根据给出的文法编制LR(1)分析程序,以便对任意输入的符号串进行分析。

本次实验的目的主要是加深对LR(1)分析法的理解。

二、实验内容对已给语言文法,构造LR(1)分析表,编制语法分析程序,要求将错误信息输出到语法错误文件中,并输出分析句子的过程(显示栈的内容)。

三、程序设计与实现1.功能描述:根据给定的文法,由程序生成项集族和语法分析表,对输入的源程序进行词法分析,得到语法分析的输入串,经过语法分析后得到三个栈,它们分别是状态栈,字符栈,输入栈,从而分析出输入的源程序是否有语法错误。

2.重要过程描述:1)本实验有两个输入文件:一个为源代码输入文件“in_code.txt”,一个为文法的输入文件“in_gram.txt”,三个输出文件:一个为词法的输出和语法的输入文件“out_in.txt”,一个为项目集族和分析表的输出文件“out_items.txt”一个为语法分析结果的输出即栈的输出“result.txt”。

2) 重要数据结构:typedef struct production{//产生式char suf[25]; //搜索符char rear[30]; //产生式后部char front; //产生式头部unsigned point; //小圆点的位置short seq;}prod;typedef struct statement{//状态iprod p[50];//产生式int num; //产生式数量}state; typedef struct collection{/状态集state i[300];int num; //状态个数}coll;struct fstruct{ //first集char str[50];//first符号串int num;//first符号串字符个数bool blank;//是否包含空符号}firstx;short int anatab[300]34. 重要函数说明find(state &unclosure,int n)函数:功能:判断是否已包含某一产生式。

语法分析实验报告

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

实现词法分析实验报告

实现词法分析实验报告一、实验目的本次实验的目的是通过编写代码实现一个简单的词法分析器,可以对一段输入的代码进行词法分析,识别出其中的各种标识符、关键字、常数和运算符等。

二、实验原理词法分析是编译过程中的第一个阶段,它负责将源代码按照规定的规则划分为一个个的单词(Token),每个单词代表一个最基本的语法单元。

在词法分析中,我们通过预先定义好的正则表达式规则来描述各个单词类型,并自动从源代码中提取出这些单词。

本次实验采用基于正则表达式的文法描述方式,针对不同的单词类型,使用不同的正则表达式来匹配。

通过遍历源代码字符串,逐一尝试匹配各个正则表达式,从而实现对单词的划分。

在匹配过程中,我们使用一个状态机来记录当前的匹配状态,以便处理不同的情况。

三、实验过程1. 定义Token的数据结构,包括单词类型和单词值两个字段。

使用枚举类型来表示所有的单词类型,如关键字、标识符、常数等。

2. 编写正则表达式的匹配函数,用于判断给定的字符串是否符合某个模式。

在这个函数中,使用系统提供的正则表达式库或者手动实现正则表达式匹配算法。

3. 设计一个状态机,用于记录当前匹配的状态。

状态机的状态包括开始、正在匹配、匹配成功和匹配失败等。

在状态机中,根据当前字符和当前状态进行不同的处理。

4. 在状态机中,当一个完整的Token被匹配出时,根据其类型和值创建一个Token对象,并将其添加到Token列表中。

5. 将源代码字符串按照换行符划分成多行,逐行进行处理。

对于每一行,调用状态机进行匹配,将得到的Token添加到Token列表中。

6. 输出Token列表,观察结果。

四、实验结果经过实验,我们成功实现了一个简单的词法分析器。

通过对输入的代码进行词法分析,我们可以得到每个单词的类型和值。

在本次实验中,我们测试了一段C语言代码,并成功提取出其中的关键字、标识符、常数和运算符等。

五、实验总结本次实验让我初步了解了词法分析的原理和过程。

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

编译原理实验报告实验名称:分析调试语义分析程序TEST抽象机模拟器完整程序保证能用!!!!!一、实验目的通过分析调试TEST语言的语义分析和中间代码生成程序,加深对语法制导翻译思想的理解,掌握将语法分析所识别的语法范畴变换为中间代码的语义翻译方法。

二、实验设计程序流程图extern int TESTScan(FILE *fin,FILE *fout);FILE *fin,*fout; //用于指定输入输出文件的指针int main(){char szFinName[300];char szFoutName[300];printf("请输入源程序文件名(包括路径):");scanf("%s",szFinName);printf("请输入词法分析输出文件名(包括路径):");scanf("%s",szFoutName);if( (fin = fopen(szFinName,"r")) == NULL){printf("\n打开词法分析输入文件出错!\n");return 0;}if( (fout = fopen(szFoutName,"w")) == NULL){printf("\n创建词法分析输出文件出错!\n");return 0;}int es = TESTScan(fin,fout);fclose(fin);fclose(fout);if(es > 0)printf("词法分析有错,编译停止!共有%d个错误!\n",es);else if(es == 0){printf("词法分析成功!\n");int es = 0;es = TESTparse(szFoutName); //调语法分析if(es== true) printf("语法分析成功!\n");else printf("语法分析错误!\n");}elseprintf("词法分析出现未知错误!\n");}Parse.cpp#include<stdio.h>#include<string.h>#include<ctype.h>#include<conio.h>#include<vector>// functionbool TESTparse();bool compound_Stat();bool program();bool statement();bool expression_stat();bool expression();bool bool_expr();bool additive_expr();bool term();bool factor();bool if_stat();bool while_stat();bool for_stat();bool write_stat();bool read_stat();bool declaration_stat();bool declaration_list();bool statement_list();bool compound_stat();char token[20],token1[40]; //token保存单词符号,token1保存单词值FILE *fp; //用于指向输入文件的指针int EsLine = 0;typedef struct{int es;int line;}EsInf;std::vector<EsInf> StackEs;//语法分析程序void ProcessError(int es){EsInf temp;temp.es = es;temp.line = EsLine;StackEs.push_back(temp);}bool ReadFile(char *tok, char *tok1){if(feof(fp))return false;fscanf(fp,"%s\t%s\n",tok,tok1);printf("%s\t%s\n",tok,tok1);EsLine++;return true;}bool TESTparse(char *pFileName){bool es = true;if((fp=fopen(pFileName,"r"))==NULL){printf("\n打开%s错误!\n",pFileName);return false;}elseprogram();if(!feof(fp))ProcessError(9);fclose(fp);printf("=====语法分析结果!=====\n");if(StackEs.size() == 0){printf("语法分析成功!\n");return true;}else{int i;for(i = 0; i < StackEs.size(); i++){printf("在第%d行",StackEs[i].line);switch(StackEs[i].es){case 1:printf("缺少{!\n");break;case 2:printf("缺少}!\n");break;case 3:printf("缺少标识符!\n");break;case 4:printf("缺少分号!\n");break;case 5:printf("缺少(!\n");break;case 6:printf("缺少)!\n");break;case 7:printf("缺少操作数!\n");break;case 8:printf("文件为空!\n");break;case 9:printf("文件尾有多余字符!\n");break;case 10:printf("\n打开%s错误!\n",pFileName);break;}}return false;}}//《程序》::={<声明序列><语句序列>}//program::={<declaration_;list><statement_list>}bool program(){bool es = true;if( ReadFile(token,token1) == false ){ProcessError(8); // 文件结束return false;}if(strcmp(token,"{")) //判断是否为‘{’ProcessError(1);if( ReadFile(token,token1) == false ) // 文件中仅有{ProcessError(2);es = declaration_list();if(es == false)return false;es = statement_list();if(es == false)return false;if(strcmp(token,"}")) //判断是否为‘}’ProcessError(2);return true;}//<声明序列>::=<声明序列><声明语句>|<声明语句>//<declaration>::=//<declaration_list><declaration_stat>|ε//改成<declaration_list>::={<declaration_stat>}bool declaration_list(){bool es = true;while (strcmp(token,"int")==0){es = declaration_stat();if(es == false)return false;}return es;}//<声明语句>::=int<变量>;//<declaration_stat>::=int ID;bool declaration_stat(){bool es = true;if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}if(strcmp(token,"ID"))ProcessError(3); //不是标识符if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}if(strcmp(token,";"))ProcessError(4);if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}return(es);}//<语句序列>::=<语句序列><语句>|ε//<statement_list>::=<statement_list><statement>|ε//改成<statement_list>::={<statement>}bool statement_list(){bool es = true;if(feof(fp))return false;while(strcmp(token,"}")){es = statement();if(es == false)return(es);}return(es);}//<语句>::=<if语句>|<while语句>|<for语句>|<read语句>// |<write语句>|<复合语句>|<表达式语句>//<statement>::=<if_sttat>|<while_stat>|<for_stat>// |<compound_stat>|<expression_stat>bool statement(){bool es = true;if(strcmp(token,"if")==0 )es=if_stat(); //<if语句>else if(strcmp(token,"while")==0 )es=while_stat(); //<while语句>else if(strcmp(token,"for")==0 )es=for_stat(); //<for语句>else if(strcmp(token,"read")==0 )es=read_stat(); //<read语句>else if(strcmp(token,"write")==0 )es=write_stat(); //<write语句>else if(strcmp(token,"{")==0 )es=compound_stat(); //<复合语句>else if(strcmp(token,"ID")==0 || strcmp(token,"NUM")==0 || strcmp(token,"(")==0 )es=expression_stat(); //<表达式语句>return(es);}//<if语句>::=if(<表达式>)<语句>[else<语句>]//<if_stat>::=if(<expressiion>)<statement>[else<statement>] bool if_stat(){bool es = true; //ifif( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}if(strcmp(token,"("))ProcessError(5); //少左括号if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es = expression();if(es == false)return(es);if(strcmp(token,")"))ProcessError(6); //少右括号if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es=statement();if(es == false)return(es);if(strcmp(token,"else")==0) //else部分处理{if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es=statement();if(es == false)return(es);}return(es);}//<while语句>::=while(<表达式>)<语句>//<while_stat>::=while<espr><statement>bool while_stat(){bool es = true;if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}if(strcmp(token,"("))ProcessError(5); //少左括号if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es = expression();if(es == false)return(es);if(strcmp(token,")"))ProcessError(6); //少右括号if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es = statement();if(es == false)return es;return(es);}//<for语句>::=for(<表达式>;<表达式>;<表达式>)<语句>//<for_stat>::=for(<expression>;<expression>;<expression>)<statement> bool for_stat(){bool es = true;if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}if(strcmp(token,"(")) ProcessError(5); //少左括号if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es=expression();if(es == false) return (es);if(strcmp(token,";")) ProcessError(4); //少分号if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es=expression();if(es == false) return (es);if(strcmp(token,";")) ProcessError(4); //少分号if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es=expression();if(es == false) return (es);if(strcmp(token,")")) ProcessError(6); //少右括号if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es=statement();if(es == false) return (es);return es;}//<write_语句>::=write<表达式>;//<write_stat>::=write<expression>bool write_stat(){bool es = true;if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es=expression();if(es == false) return (es);if(strcmp(token,";")) ProcessError(4); //少分号if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}return es;}//<read_语句>::=read<变量>//<read_stat>::=read Id;bool read_stat(){bool es = true;if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}if(strcmp(token,"ID")) ProcessError(3); //少标识符if(strcmp(token,";")) ProcessError(4); //少分号if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}return es;}//<复合语句>::{<语句序列>}//<compound_stat>::={<statement_list>}bool compound_stat() //复合语句函数{bool es = true;if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es = statement_list();if(es == false)return es;// -------------- new----------if(strcmp(token1,"}") != 0)ProcessError(2);else{if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}}// --------------- new ----------return es;}//<表达式语句>::=<<表达式>;|;//<expression_stat>::=<expression>;|;bool expression_stat(){bool es = true;if(strcmp(token,";")==0){if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束return es;}es=expression();if(es == false) return es;if(strcmp(token,";")==0){if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}return es;}else{ProcessError(4); //少分号}return es;}//<表达式>::=<标识符>=<布尔表达式>|<布尔表达式>//<expression>::=ID=<bool_expr>|<bool_expr>bool expression(){bool es = true;int fileadd;char token2[20],token3[40];if(strcmp(token,"ID")==0){fileadd=ftell(fp); //记住当前文件位置if( ReadFile(token2,token3) == false ){ProcessError(2); // 缺少}return false; // 文件结束if(strcmp(token2,"=")==0) //'='{if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es=bool_expr();if(es == false) return es;}else{fseek(fp,fileadd,0); //若非‘=’,则文件指针回到‘=’前的标识符EsLine--;es=bool_expr();if(es == false) return es;}}else{es=bool_expr();if(es == false) return es;}return es;}//<布尔表达式>::= <算术表达式>[(>|<|>=|<=|==|!=)<算数表达式>]//<bool_expr>::= <additive_expr> [(>|<|>=|<=|==|!=)<additive_expr>]bool bool_expr(){bool es = true;es=additive_expr();if(es == false) return es;if(strcmp(token,">")==0||strcmp(token,">=")==0 ||strcmp(token,"<")==0||strcmp(token,"<=")==0||strcmp(token,"!=")==0||strcmp(token,"==")==0) {if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es=additive_expr();if(es == false) return es;}return es;}//<算数表达式>::=<项>{(+|-)<项>}//<additive_expr>::=<term>{(+|-)<term>}bool additive_expr(){bool es = true;es=term();if(es == false) return es;while(strcmp(token,"+")==0||strcmp(token,"-")==0){if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es=term();if(es== false) return es;}return es;}//<项>::=<因子>{(*|/)<因子>}//<term>::=<factor>{(*|/)<factor>}bool term(){bool es = true;es=factor();if(es == false) return es;while(strcmp(token,"*")==0||strcmp(token,"/")==0){if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es=factor();if(es == false) return es;}return es;}//<因子>::=(<表达式>)|<标识符>|<无符号整数>//<factor>::=(<expression>)|ID|NUMbool factor(){bool es = true;if(strcmp(token,"(")==0){if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}es=expression();if(es==false) return es;if(strcmp(token,")")) ProcessError(6); //少右括号if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}}else{if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0){if( ReadFile(token,token1) == false ){ProcessError(2); // 缺少}return false; // 文件结束}return es;}else{ProcessError(7); //缺少操作数}}return es;}Scan.cpp#include<ctype.h>#include<cstring>#include<stdio.h>// 保留字#define KEYWORDNUM 8char *pKeyword[KEYWORDNUM] = {"if", "else", "for", "while", "do", "int", "read", "write"};// 单分界符char szSingleWord[50] = "+-(){};,:";// 双分界符char szDoubleWord[10] = "<>!";// 其他符char *szDivide = "/";char *szStar = "*";char *szEqual = "=";#define STATUSNUM 16 //状态个数#define DATANUM 10 // 数据流个数// 数据流类型typedef unsigned int DATA;#define OTHER 0 // wrong input#define LETTER 1 // 字母#define DIGIT 2 // 数字#define SINGLEWORD 3 // 单分界符#define DOUBLEWORD 4 // 双分界符#define DIVIDE 5 // /#define EQUAL 6 // =#define STAR 7 // *#define SPACE 8 // 空白#define FILEOVER 9// 状态类型typedef unsigned int STATUS;#define NOSTATUS 0 // wrong input#define START 1#define CASE_ID 2#define END_ID 3#define CASE_NUM 4#define END_NUM 5#define CASE_SINGLE 6#define END_SINGLE 7#define CASE_DOUBLE 8#define CASE_DOUBLE2 9#define END_DOUBLE 10#define CASE_DIVIDE 11#define CASE_NOTE 12#define END_NOTE 13#define CASE_ERROR 14#define END_ERROR 15// 状态转换表// :到达终结状态的数据不保存在输出串中int reflect[STATUSNUM][DATANUM] ={ //OTHER LETTER DIGIT SINGLEWORD DOUBLEWORD DIVIDE EQUAL STAR SPACE FILEOVER/*NOSTATUS*/ {NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS},/*START*/ {CASE_ERROR,CASE_ID, CASE_NUM,CASE_SINGLE,CASE_DOUBLE,CASE_DIVIDE,CASE_DOUBLE,CASE_SINGLE,START, START},/*CADE_ID*/ {END_ID, CASE_ID, CASE_ID, END_ID, END_ID, END_ID, END_ID, END_ID, END_ID, END_ID},/*END_ID*/ {NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS},/*CASE_NUM*/ {END_NUM, END_NUM, CASE_NUM, END_NUM, END_NUM, END_NUM, END_NUM, END_NUM, END_NUM, END_NUM},/*END_NUM*/ {NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS},/*CASE_SINGLE*/ {END_SINGLE,END_SINGLE, END_SINGLE, END_SINGLE, END_SINGLE, END_SINGLE, END_SINGLE, END_SINGLE, END_SINGLE, END_SINGLE},/*END_SINGLE*/ {NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS},/*CASE_DOUBLE*/ {END_SINGLE,END_SINGLE, END_SINGLE, END_SINGLE, END_SINGLE, END_SINGLE, CASE_DOUBLE2,END_SINGLE,END_SINGLE, END_SINGLE},/*CASE_DOUBLE2*/{END_DOUBLE,END_DOUBLE, END_DOUBLE, END_DOUBLE, END_DOUBLE, END_DOUBLE, END_DOUBLE, END_DOUBLE, END_DOUBLE, END_DOUBLE},/*END_DOUBLE*/ {NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS},/*CASE_DIVIDE*/ {END_SINGLE,END_SINGLE, END_SINGLE, END_SINGLE, END_SINGLE, END_SINGLE, END_SINGLE, CASE_NOTE, END_SINGLE, END_SINGLE},/*CASE_NOTE*/ {END_NOTE, END_NOTE, END_NOTE, END_NOTE, END_NOTE, END_NOTE, END_NOTE, END_NOTE, END_NOTE, END_NOTE},/*END_NOTE*/ {NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS},/*CASE_ERROR*/ {END_ERROR, END_ERROR, END_ERROR, END_ERROR, END_ERROR, END_ERROR, END_ERROR, END_ERROR, END_ERROR, END_ERROR},/*END_ERROR*/ {NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS, NOSTATUS}};// 若在pString中找到 word 则返回 true,否则,返回 falsebool SearchChar(char word,const char *pString){int n = strlen(pString);for(int i = 0; i < n; i++){if( word == pString[i])return true;}return false;}// 得到word的数据流类型DATA GetDataByword(char word){if(word == EOF)return FILEOVER;if(isalpha(word))return LETTER;if(isdigit(word))return DIGIT;if(SearchChar(word,szSingleWord))return SINGLEWORD;if(SearchChar(word,szDoubleWord))return DOUBLEWORD;if(SearchChar(word,szDivide))return DIVIDE;if(SearchChar(word,szEqual))return EQUAL;if(SearchChar(word,szStar))return STAR;if(isspace(word))return SPACE;return OTHER;}// 得到从status状态输入word后到达的状态STATUS GetNextStatus(STATUS status, DATA word){return reflect[status][word];}// 返回值表示错误个数。

相关文档
最新文档