词法分析报告程序设计与实现

合集下载

词法分析器实验报告

词法分析器实验报告

词法分析器实验报告实验名称: 编写词法分析器实验类型: 验证型实验指导教师:专业班级:姓名:学号:电子邮件:实验地点:实验成绩:日期: 2012 年3 月 22 日目录一、实验目的。

2 二、实验过程。

21、背景知识。

22、程序总体设计。

23、各种类型表。

4、程序流程图。

5 4三、试验结果。

5 四、讨论与分析。

6 五、附录。

7 六、试验者自评。

131一、实验目的通过设计、调试词法分析程序,实现从源程序中分出各种单词的方法;熟悉词法分析程序所用的工具自动机,进一步理解自动机理论。

掌握文法转换成自动机的技术及有穷自动机实现的方法。

确定词法分析器的输出形式及标识符与关键字的区分方法。

加深对课堂教学的理解;提高词法分析方法的实践能力。

通过本实验,掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法以及掌握词法分析的实现方法,并可以成功的上机调试编出的词法分析程序。

二、实验过程我们在设计词法分析器时,应该首先对词法分析器相关的背景知识有足够的了解以及熟练的掌握。

从而在脑海里形成词法分析的一般方案,根据方案一步步所要实现的目的,形成对词法分析器程序的模块划分和整体规划。

1、背景知识词法分析是作为相对独立的阶段来完成的(对源程序或中间结果从头到尾扫描一次,并作相应的加工处理,生成新的中间结果或目标程序)。

在词法分析过程中,编译程序是通过操作系统从外部介质中读取源程序文件中的各个字符的。

同时,为正确地识别单词,有时还需进行超前搜索和回退字符等操作。

因此,为了提高读盘效率和便于扫描器进行工作,通常可采用缓冲输入的方案,即在内存中设置一个适当大小的输入缓冲区,让操作系统直接将磁盘上的源程序字符串分批送入此缓冲区中,供扫描器进行处理。

程序总体设计 2、主程序的说明部分为各种表格和变量安排空间。

二维数组k:关键字表,采用定长的方式,较短的关键字后面补空格。

一维数组p:分界符表。

一维数组s: 运算符表。

二维数组id:存放标识符,在程序运行中,产生标示符表二维数组ci:存放常数。

词法分析及词法分析程序

词法分析及词法分析程序
语义加工过程:
– w,p,n初值为0,e初值为1;
– 处理整数部分时,对于每个di ,令w=w10+di ; – 处理小数部分时,对于每个di ,令w=w10+di ;及n++;
– 处理指数时,E后若有‘-’号,令e=-1;计算指数值 p=p10+d;
– 在出口处,令ICON=w或FCON=w10^(e(p-n)).
(2)设当前处在Ai状态,所扫描的字符为ai+1,在结点Ai所 射出的诸矢线中,寻找标记为ai+1的矢线(若不存在,则 表明w有语法错误),读入ai+1,并进入状态Ai+1;
(3)重复(2),直到w中所有字符被读完且恰好进入终态F 时,宣告整个识别结束,w可被接受.
28
例:G[Z]:
状态转换图:
Z→0U∣1V
{return ( ICON= w ); {n++; w=w*10+d;}
{return (FCON =w*pow(10,e*p-n) ) ;} {n++;w=w*10+d;} error {p=p*10+d;}
e=-1; error {p=p*10+d;} error {p=p*10+d;} {return (FCON=w*pow(10,e*p-n) );
(1)对于G中形如Aa 的产生式,引矢线RA,且标记
为a;
(2)对于G中形如ABa 的产生式,引矢线 BA,且标
记为a。
34
由左线性文法构造状态转换图
已给文法G=({S,U},{0,1},{SS1 |U1, UU0 | 0},S)
R0
0
1
U1 S

XML词法分析的C语言设计与实现

XML词法分析的C语言设计与实现
【关键词】XM L C 语言; 词法分析 Design and Im plem ent of XM L’s Lexical Analysis by C L anguage L IU Xi gu
( Postgr adu at e Team 1 ICE PLAUST, Nan ji ng 210007 ) 【Ab str act 】This arti cle introduces the advantage of XML and the functi on of l exical analysis in bri ef, designs t he flow of XML’s lexi cal analysi s by constructing DFE, and impl ement s it by C language. 【Key wor ds 】XML; C language; lexi cal anal ysis
// 滤掉前导空格
L1: while (IsSpace(m_SourceDocument[m_Pos ForGetToken]))
{ m_PosForGet Token++; / /读取指针往后移 }
if (m_SourceDocument[m_PosForGetToken]==0)
{ return m_Thi sTokenCode=XMLTOKEN_EOF; // 遇到末尾了 } // 把注释滤掉
科技信息
○I T 技术论坛○
SCIE NCE & TE CHNO LO GY INFORM ATION
2008 年 第 27 期
XML 词 法 分 析 的 C 语 言 设 计 与 实 现
刘 喜古 王 炼 陈 涛 ( 解放 军理 工大 学通 信工 程学 院研究 生一 队 江苏 南 京 210007)

编译原理词法分析及词法分析程序

编译原理词法分析及词法分析程序
∴M能识别出L(G)中的全部句子。
状态图=>右线性文法
文法G[0] 0->a1
d 0
S->aA A->dA A->b
a c
1 2
b
d
3
1->d1 1->b
0->c
0->c2 2->d
S->c
S->cB,2有出弧 B->d
左线性文法=>状态转换图
设G=(VN,VT,P,S)是一左线性文法,令|VN|=K, 1) 则所要构造的状态转换图共有K+1个状态. 2) VN中的每个符号分别表示K个状态 2.1) G的开始符S为终止状态 3) 起始状态,用R(VN)标记
识别符号串与归约
S





从初态R到下一状态A对应Ba,即终结 符a归约成非终结符B; U 从状态B转换到状态A对应ABa,即将 Ba归约为A; 状态A转换到状态S(终态)对应S Aa,即 U 将Aa归约为开始符S. 归约成功,恰好进入终态,即状态转换图识 U 别了(或接受)该符号串. 识别00011的例子的归约过程
f是转换函数,是在K×Σ →K上的映像,即:如果f(ki,a)=kj, (ki,kj∈K)意味着,当前状态为ki,输入字符为a时,将转换 为下一个状态kj,我们把kj称作ki的一个后继状态;
1.确定的有限自动机
通常把这五要素组成的五元式M=(K,∑,f, S0,Z)称为确定的 有限自动机(DFA),它是相应的状态转化图的一种形式描 述,或者说,是状态转换矩阵的另一种表示。 在状态转换的每一步,据DFA当前所处状态及扫视的输入 字符,能唯一确定下一状态。

例:文法G=({S,U},{0,1},{SS1 |U1,

实验1:词法分析程序

实验1:词法分析程序

实验1 词法分析程序一、实验目的与要求1.复习正规文法、正规式、有限自动机之间的相互转换的原理及技术;2.学会使用Visual C++等高级语言编程实现上述转换,并能合理显示结果;3.以C++的一个真子集为案例,具体分析词法分析程序的设计步骤、基本架构及代码编制,并通过一定实例验证其可行性,以加深对词法分析原理的理解;4.通过本次实验,使学生理解模块化程序设计的思想,从而从全局角度领会一个完整软件的设计精髓,为后续试验的顺利完成奠定坚实的基础。

二、实验仪器及设备1.微型电子计算机80台2.配置Windows 2000及以上版本操作系统3.安装Visual C++6.0/Visual C#2000/Delphi6.0等以上版本的开发环境三、实验内容及步骤(一)正规文法与有限自动机的相互转换1.正规文法⇒有限自动机已知某正规文法G[S]如下:S→aAS→bBS→εA→aBA→bAB→aSB→bAB→ε请编程实现:(1)将G[S]转换为NFA;(2)将上述得到的NFA确定化为DFA;(3)再将DFA最简化为MFA。

2.有限自动机⇒正规文法已知某有限自动机NFA M=(Q,∑,f,q0,Z)如下:状态集:Q={1,2,3,4,5,6,7,8,9}字母表:∑={a,b}转移函数:f(1,a)=5f(1,ε)=2f(1,a)=4f(5,ε)=6f(2,b)=3f(4,ε)=7f(6,ε)=2f(6,b)=9f(3,ε)=8f(8,a)=9f(7,b)=9初态:q0=1终态集:Z={6,7,9}请编程实现:(1)首先将此NFA确定化为DFA;(2)再将得到的DFA最简化为MFA;(3)最后,将MFA转化为正规文法(左线性或右线性均可)。

(二)编程实现MiniC++的词法分析这里的MiniC++为C++语言的一个真子集,其语法结构与C++类似。

基本组成如下:(1)关键字有18个,分别为:void、int、char、bool、float、double、if、else、switch、case、default、break、continue、do、while、for、return以及struct等。

(完整版)词法分析器(c语言实现)

(完整版)词法分析器(c语言实现)

词法分析c实现一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

二、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。

(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。

空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。

2.2 各种单词符号对应的种别码:输入:所给文法的源程序字符串。

输出:二元组(syn,token或sum)构成的序列。

其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。

例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的C语言程序源代码:#include <stdio.h>#include <string.h>char prog[80],token[8],ch;int syn,p,m,n,sum;char *rwtab[6]={"begin","if","then","while","do","end"};scaner();main(){p=0;printf("\n please input a string(end with '#'):/n");do{scanf("%c",&ch);prog[p++]=ch;}while(ch!='#');p=0;do{scaner();switch(syn){case 11:printf("( %-10d%5d )\n",sum,syn);break;case -1:printf("you have input a wrong string\n");getch();exit(0);default: printf("( %-10s%5d )\n",token,syn);break;}}while(syn!=0);getch();}scaner(){ sum=0;for(m=0;m<8;m++)token[m++]=NULL;ch=prog[p++];m=0;while((ch==' ')||(ch=='\n'))ch=prog[p++];if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))){ while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) {token[m++]=ch;ch=prog[p++];}p--;syn=10;for(n=0;n<6;n++)if(strcmp(token,rwtab[n])==0){ syn=n+1;break;}}else if((ch>='0')&&(ch<='9')) { while((ch>='0')&&(ch<='9')) { sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=11;}else switch(ch){ case '<':token[m++]=ch;ch=prog[p++];if(ch=='='){ syn=22;token[m++]=ch;}else{ syn=20;p--;}break;case '>':token[m++]=ch;ch=prog[p++];if(ch=='='){ syn=24;token[m++]=ch;}else{ syn=23;p--;}break;case '+': token[m++]=ch;ch=prog[p++];if(ch=='+'){ syn=17;token[m++]=ch;}else{ syn=13;p--;}break;ch=prog[p++];if(ch=='-'){ syn=29;token[m++]=ch;}else{ syn=14;p--;}break;case '!':ch=prog[p++];if(ch=='='){ syn=21;token[m++]=ch;}else{ syn=31;p--;}break;case '=':token[m++]=ch;ch=prog[p++];if(ch=='='){ syn=25;token[m++]=ch;}else{ syn=18;p--;}break;case '*': syn=15;token[m++]=ch;break;case '/': syn=16;token[m++]=ch;break;case '(': syn=27;token[m++]=ch;break;case ')': syn=28;break;case '{': syn=5;token[m++]=ch;break;case '}': syn=6;token[m++]=ch;break;case ';': syn=26;token[m++]=ch;break;case '\"': syn=30;token[m++]=ch;break;case '#': syn=0;token[m++]=ch;break;case ':':syn=17;token[m++]=ch;break;default: syn=-1;break;}token[m++]='\0';}四、结果分析:输入begin x:=9: if x>9 then x:=2*x+1/3; end # 后经词法分析输出如下序列:(begin 1)(x 10)(:17)(= 18)(9 11)(;26)(if 2)……如图5-1所示:。

编译原理词法分析和语法分析报告+代码(C语言版)

分数:编译原理实验报告系别:计算机科学系专业:计算机科学与技术学号:20091080605007姓名:李周平指导教师:张莉词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

二、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。

(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。

空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。

2.2 各种单词符号对应的种别码:表2.1 各种单词符号对应的种别码单词符号种别码单词符号种别码bgin 1 :17If 2 := 18Then 3 < 20wile 4 <> 21do 5 <= 22end 6 > 23lettet(letter|digit)* 10 >= 24 dight dight* 11 = 25 + 13 ;26—14 ( 27* 15 ) 28/ 16 # 02.3 词法分析程序的功能:输入:所给文法的源程序字符串。

输出:二元组(syn,token或sum)构成的序列。

其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。

例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

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

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

二、实验设计程序流程图.Statement_list()开始es=0读入一个token=}符号 es=0Y{Nes=1Tooken=ifToken=ifNYToken=whilees=0NNToken=for declaration_list()NYes=0Token=readNN N Statement_list()Token=writeNY es=0Token={ YNN}N es=2Token=ID|NUM|(Y N返回token=}YReturn(es)语法分析YYYYYYYIf_stat()while_stat()for_stat()read_stat()N write_stat()Compound_state()expression_stat()开始Es=0词法分析输出词法Es>0Y分析失败N输出词法分析成功语法分析输出语法Es=0Y分析成功N输出语法分析错误结束程序代码:Main.cpp#include<stdio.h>#include<ctype.h>extern bool TESTparse(char *pFileName);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 STATUSNUM16// 状态个数#define DATANUM10//数据流个数// 数据流类型typedef unsigned int DATA;#define OTHER0// wrong input#define LETTER1//字母#define DIGIT2//数字#define SINGLEWORD3//单分界符#define DOUBLEWORD4//双分界符#define DIVIDE5// /#define EQUAL6// =#define STAR7// *#define SPACE8//空白#define FILEOVER9//状态类型typedef unsigned int STATUS;#define NOSTATUS0// wrong input#define START1#define CASE_ID2#define END_ID3#define CASE_NUM4#define END_NUM5#define CASE_SINGLE6#define END_SINGLE7#define CASE_DOUBLE8#define CASE_DOUBLE29#define END_DOUBLE10#define CASE_DIVIDE11#define CASE_NOTE12#define END_NOTE13#define CASE_ERROR14#define END_ERROR15//状态转换表//: 到达终结状态的数据不保存在输出串中int reflect[STATUSNUM][DATANUM] ={//OTHER LETTER DIGIT SINGLEWORDDOUBLEWORD 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 ,否则,返回 false boolSearchChar(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];}// 返回值表示错误个数。

词法分析器实验报告

词法分析器实验报告一、实验内容设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

1.待分析的简单词法(1)关键字:所有的关键字都是小写begin if then while do end(2)运算符和界符: := + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。

空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。

2. 各种单词符号对应的种别码:表1 各种单词符号对应的种别码3. 词法分析程序的功能:输入:所给文法的源程序字符串。

输出:二元组(syn,token或num)构成的序列。

其中:syn为单词种别码;token为存放的单词自身字符串;num为整型常数。

例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin) (10,x) (18,:=) (11,9) (26,;) (2,if)……二、实验设计和实现关键字:定义全局字符串型数组key[6]={"begin","if","then","while","do","end"},字符串与关键字匹配成功即为关键字。

判断关键字的函数及代码如下:bool isKey(string str,int &syn){int i;for(i=0;i<6;i++){if(str==key[i]){syn=i+1;return true;}}return false;}判断字母函数:bool isLetter(char c){if((c>='A'&&c<='Z')||(c>='a'&&c<='z')){return true;}else{return false;}}判断数字函数:bool isDigit(char c){if(c>='0'&&c<='9'){return true;}else{return false;}}词法判断流程简略图:继续②、③、④↑空格↑①NUM(数字)←读入字符不为空→字母→包括普通字母构成的字符串,ID以及关键字②↓④③运算符和界符三、实验结果与分析判断词法的具体代码:void analyse(FILE *fileP){int n;char c;string str="";while((c=fgetc(fileP))!=EOF){loop: if(c==' '||c=='\t'||c=='\n')//空格{continue;}else if(isDigit(c))//数字{while(isDigit(c)){str+=c;c=fgetc(fileP);if(isLetter(c)){while(isLetter(c)){str+=c;c=fgetc(fileP);}cout<<"(error,"<<str<<")"<<endl;str="";goto loop;}}fseek(fileP,-1,SEEK_CUR);cout<<"(11,"<<str<<")"<<endl;str="";}else if(isLetter(c))//字母开头{while(isDigit(c)||isLetter(c)){str+=c;c=fgetc(fileP);}fseek(fileP,-1,SEEK_CUR);if(isKey(str,n))//关键字的情况{cout<<"("<<n<<","<<str<<")"<<endl;}else//标识符{cout<<"(10,"<<str<<")"<<endl;}str="";}else//运算符和界符{switch(c){case '+':cout<<"(13,+)"<<endl;break;case '-':cout<<"(14,-)"<<endl;break;case '*':cout<<"(15,*)"<<endl;break;case '/':cout<<"(16,/)"<<endl;break;case ':':{c=fgetc(fileP);if(c=='='){cout<<"(18,:=)"<<endl;}else{cout<<"(17,:)"<<endl;fseek(fileP,-1,SEEK_CUR);}}break;case '<':{c=fgetc(fileP);if(c=='='){cout<<"(22,<=)"<<endl;}else if(c=='>'){cout<<"(21,<>)"<<endl;}else{cout<<"(20,<)"<<endl;fseek(fileP,-1,SEEK_CUR);}}break;case '>':{c=fgetc(fileP);if(c=='='){cout<<"(24,>=)"<<endl;}else{cout<<"(23,>)"<<endl;fseek(fileP,-1,SEEK_CUR);}}break;case '=':cout<<"(25,=)"<<endl;break;case ';':cout<<"(26,;)"<<endl;break;case '(':cout<<"(27,()"<<endl;break;case ')':cout<<"(28,))"<<endl;break;case '#':cout<<"(0,#)"<<endl;break;}}}}主函数部分:int main(){char filec[30];FILE *fileP;cout<<"input the name of your file:"<<endl;for(;;){cin>>filec;if((fileP=fopen(filec,"r"))!=NULL)break;elsecout<<"error input,input once more!"<<endl;}cout<<endl;cout<<"output the result:"<<endl;analyse(fileP);fclose(fileP);return 0;}结果:测试数据1:begin x:=9; if x>9 then x:=2*x+1/3; end #测试数据2:begin 9xy:=+9; if x>9 then x:=2*x+1/3; end #四、实验总结和体会通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,根据识别语言单词的状态转换图,使用某种高级语言(例如C++语言)直接编写此法分析程序。

词法分析实验报告(实验一)

编译原理词法分析实验报告软工082班兰洁200831104044一、实验内容二、实验目的三、实验预期四、程序规定五、实验原理●程序流程图●判别浮点功能扩展流程图●状态转换图六、程序代码与浮点判别功能扩展七、测试用例●扩展功能测试用例;●普通功能测试用例八、输出结果九、实验心得一、实验内容:词法分析:1、识别简单语言的单词符号;2、识别关键字、标识符、数字、运算符等。

并扩展浮点识别功能。

二、实验目的调试词法分析程序,加深对词法分析原理的理解,掌握编写简单词法分析程序的一般步骤。

三、实验预期结果:经过调试源代码程序,程序能够成功运行编译,对输入的简单字符串,能够别关键字、标识符、数字、运算符等,并且给出单词符号的对应编码。

四、程序规定:1、关键字:"function","if","then","while","do","endfunc";2、算术运算符:”+”,”-”,”*”,”/”,”=”;3、关系运算符:"<" ">" "<=" ">=" "==" "!=";4、界符:"(" ")" ";" "#";5、标识符规定以字母开头,字母均为小写;6、空格和换行符跳过;7、单词对应编码:十、实验原理:输入串--------------------〉词法分析程序————————〉单词符号串输入:字符串以#结束。

输出:单词的二元组(syn,token/sum)程序流程图分析浮点数功能扩展部分流程图:shuzi()函数状态转换图六、程序代码:备注:红色字体部分为程序功能的功能扩展,使程序能够分析浮点数!我把浮点数的syn设置为80!/*词法分析源代码*/#include<stdio.h>#include<string.h>scaner();char prog[80],token[8];char ch;int syn,p,m,n,sum;char * rwtab[6]={"function","if","then","while","do","endfunc"}; int i=0,k,c,sumint,f;char fenshu[80],sum1[80];double sumf=0,fudian;int shuzi(){if(ch>='0' && ch<='9')syn=80;elsesyn=-2;return syn;}main(){p=0;printf("\n please input string :\n");do{scanf("%c",&ch);prog[++p]=ch;}while(ch!='#');p=0;do{scaner();switch(syn){ case 11:printf("\n(%d,%d)",syn,sum);break;case -1:printf("\n error");break;case 80:printf("\n(%d,%f)",syn,fudian);break; default:printf("\n(%d,%s)",syn,token);}}while(syn!=0);}scaner(){for(n=0;n<8;n++)token[n]=NULL;//if(1+2!=3)ch=prog[++p];while(ch==' ' || ch=='\n')ch=prog[++p];//跳过空格if(ch>='a' && ch<='z'){m=0;while(ch>='a' && ch<='z' || ch>='0' && ch<='9') {token[m++]=ch;//token[0]=f,m=1ch=prog[++p];}token[m]='\0';ch=prog[--p];syn=10;for(n=0;n<6;n++){if(strcmp(token,rwtab[n])==0){syn=n+1;break;}}}elseif(ch>='0' && ch<='9'){c=p;k=0;do{ sum1[k]=ch;ch=prog[++c]; //ch取后一个数字k++;shuzi();//这个函数用来分析浮点数的整数部分是否已经输入到数组里f=syn;} while(f==80)if(ch=='.'){for(n=0;n<k;n++){sumint=sumint*10+sum1[n]-'0';} //计算整数部分i=0;do{ch=prog[++c];fenshu[i]=ch;i++;shuzi();//这个函数用来分析浮点数的小数部分是否已经输入到数组里} while(syn==80);sumf=0;for(k=i-2;k>=0;k--){sumf=sumf*0.1+(fenshu[k]-'0')*0.1;} //计算浮点数的小数部分fudian=sumint+sumf; //浮点数计算syn=80;p=--c;}else{ch=prog[p];//若是整数,ch等于原来的值 sum=0;while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=prog[++p];}ch=prog[--p];syn=11;}}elseswitch(ch){case'<':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){syn=22;token[m++]=ch;}elseif(ch=='>'){syn=21;token[m++]=ch;}else{syn=20;ch=prog[--p];}break;case'>':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){syn=24;token[m++]=ch;}else{syn=23;ch=prog[--p];}break;case'=':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){syn=25;token[m++]=ch;}else{syn=18;ch=prog[--p];}break;case'!':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){syn=22;token[m++]=ch;}else{syn=-1;p--;}break;case'+':syn=13;token[0]=ch;break;case'-':syn=14;token[0]=ch;break;case'*':syn=15;token[0]=ch;break;case'/':syn=16;token[0]=ch;break;case';':syn=26;token[0]=ch;break;case'(':syn=27;token[0]=ch;break;case')':syn=28;token[0]=ch;break; case'#':syn=0;token[0]=ch;break;default:syn=-1;}}七、测试用例:补充:功能扩展测试用例:八、程序输出结果:功能扩展测试用例输出结果用例一:用例二:用例三:普通功能测试用例显示结果九、实验心得通过编译原理实验一词法分析实验,使得自己对词法分析的流程有了更深刻的了解,虽然源代码并非由自己设计,但是在调试程序的过程中,尤其是进行测序功能扩展的过程中,想了很多种办法,终于找到了最合适的方法,而且还进行了代码的优化,这个过程虽然有时有些枯燥,但是更多时候是欣喜的,不仅复习了c语言的许多内容,并且有了更深的理解。

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

实用文档
实验一 词法分析程序设计与实现
一、 实验目的及内容
调试并完成一个词法分析程序,加深对词法分析原理的理解。
二、实验原理(状态转换图)
1、 C语言子集
(1) 关键字:
begin if then while do end
所有关键字都是小写。
(2) 运算符和界符:
:= + – * / < <= <> > >= = ; ( ) #
(3) 其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:
ID=letter(letter| digit)*
NUM=digit digit *
(4) 空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM,运算符、界
符和关键字,词法分析阶段通常被忽略。

2、 各种单词符号对应的种别码
单词符号 种别码 单词符号 种别码
begin 1 : 17
if 2 := 18
then 3 > 20
while 4 <> 21
do 5 <= 22
end 6 < 23
letter(letter| digit)* 10 >= 24

digit digit * 11 = 25
* 13 ; 26
/ 14 ( 27
+ 15 ) 28
实用文档
- 16 # 0

3、 词法分析程序的功能
输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;
token为存放的单词自身字符串;
sum为整型常数。

二、 软件平台及工具
PC机以及VISUAL C++6.0软件。
三、 实验方法、步骤(或:程序代码或操作过程)
(1)程序代码:
#include
#include
#include
char prog[80],token[8];
char ch;
int syn,p,m=0,n,row,sum=0;
char *rwtab[6]={"begin","if","then","while","do","end"};

void scaner()
{
for(n=0;n<8;n++) token[n]=NULL;
ch=prog[p++];
while(ch==' ')
{
ch=prog[p];
p++;
}
实用文档
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{
m=0;
while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{
token[m++]=ch;
ch=prog[p++];
}
token[m++]='\0';
p--;
syn=10;
for(n=0;n<6;n++)
if(strcmp(token,rwtab[n])==0)
{
syn=n+1;
break;
}
}
else if((ch>='0'&&ch<='9'))
{
{
sum=0;
while((ch>='0'&&ch<='9'))
{
sum=sum*10+ch-'0';
ch=prog[p++];
}
}
p--;
syn=11;
if(sum>32767)
syn=-1;
实用文档
}
else switch(ch)
{
case'<':m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='>')
{
syn=21;
token[m++]=ch;
}
else if(ch=='=')
{
syn=22;
token[m++]=ch;
}
else
{
syn=23;
p--;
}
break;
case'>':m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=24;
token[m++]=ch;
}
else
{
syn=20;
p--;
实用文档
}
break;
case':':m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=18;
token[m++]=ch;
}
else
{
syn=17;
p--;
}
break;
case'*':syn=13;token[0]=ch;break;
case'/':syn=14;token[0]=ch;break;
case'+':syn=15;token[0]=ch;break;
case'-':syn=16;token[0]=ch;break;
case'=':syn=25;token[0]=ch;break;
case';':syn=26;token[0]=ch;break;
case'(':syn=27;token[0]=ch;break;
case')':syn=28;token[0]=ch;break;
case'#':syn=0;token[0]=ch;break;
case'\n':syn=-2;break;
default: syn=-1;break;
}
}

void main()
{
p=0;
实用文档
row=1;
cout<<"Please input string:"<do
{
cin.get(ch);
prog[p++]=ch;
}
while(ch!='#');
p=0;
do
{
scaner();
switch(syn)
{
case 11: cout<<"("< case -1: cout<<"Error in row "<case -2: row=row++;break;
default: cout<<"("<}
}
while (syn!=0);
}
(2)创建编辑程序
实用文档
(3)连接、编译和调试程序

(4)运行程序
五、实验过程原始记录( 测试数据、图表、计算等)
实用文档
(1)给定源程序

begin x:=8; if x>0 then x:=2*x+1/5; end#
输出结果

(2)源程序(包括上式未有的while、do以及判断错误语句):
begin
x<=$;
while
a<0
do
b<>9-x;
end
#

相关文档
最新文档