词法分析程序设计与实现
北航编译原理课件 03.词法分析
3. 词法分析程序算法
北京航空航天大学计算机学院
17
1.单词及内部表示 单词及内部表示: 单词及内部表示
单词名称
BEGIN END FOR DO IF THEN ELSE 标识符 常数(整 常数 整) : + * , ( ) :=
保留字和分界符采用一符一类
记忆符
BEGINSY ENDSY FORSY DOSY IFSY THENSY ELSESY IDSY INTSY COLONSY PLUSSY STARSY COMSY LPARSY RPARSY ASSIGNSY
字母、数字
标识符 无符号整数
单字符分界符
S S S
字母
标 数字
非字母数字
出口
数字
数
非数字
出口
+ * , 单界 ( ) :
其他字符 非=
出口
双字符分界符
北京航空航天大学计算机学院
S
冒号
=
双界
其他字符
出口 15
查保留字表 读字符
字母、数字
S
字母
标 数字
非字母数字
标识符
非数字
数字
数
无符号整数 单字符分界符
如:b{ab} = {ba}b {a|b} = {{a} {b}} = (a*b*)*
北京航空航天大学计算机学院 23
例:设 ∑ = { a,b },下面是定义在∑上的正则表达式和正则集合 正则表达式 ba* a(a|b)* (a|b)*(aa|bb)(a|b)* 正则集合
北京航空航天大学计算机学院
北京航空航天大学计算机学院 20
‘*’ : ‘,’ : ‘(’ : ‘)’ : ‘:’ :
编译原理词法分析实验报告
编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的:1.熟悉编译原理中词法分析的基本概念和原理;2.掌握正则表达式的使用方法;3.实现一个简单的词法分析器。
二、实验内容:1.设计一个简单的编程语言,包含如下几种类型的词法单元:关键字、标识符、常量、运算符和界符。
2.使用正则表达式定义每种词法单元的模式。
3.设计一个词法分析器,将源代码中的每个词法单元识别出来并输出。
三、实验步骤:1. 确定编程语言的词法单元类型和正则表达式模式,定义相应的单词类型(如 TokenType)和模式(如 regex)。
2. 实现一个词法分析器的类 Lexer,包含以下方法:(1)一个构造方法,用于初始化词法分析器的输入源代码。
(2) 一个getNextToken方法,用于获取源代码中的下一个词法单元。
3. 在getNextToken方法中,使用正则表达式逐个识别源代码中的词法单元,并返回相应的Token对象。
4. 设计一个Token类,包含以下属性:词法单元类型、词法单元的值和位置信息等。
5.在主程序中使用词法分析器,将源代码中的每个词法单元识别出来并输出。
四、实验结果:1.设计一个简单的编程语言,包含如下词法单元类型(示例):(1) 关键字:if、else、while、for等;(2)标识符:变量名等;(3)常量:整数、浮点数、字符串等;(4)运算符:+、-、*、/、=等;(5)界符:(、)、{、}、;等。
2. 实现一个词法分析器,识别出源代码中的每个词法单元,并输出相应的Token对象。
五、实验总结:通过本次实验,我熟悉了编译原理中词法分析的基本概念和原理,并掌握了正则表达式的使用方法。
我成功完成了一个简单的词法分析器的设计与实现,实现了源代码中每个词法单元的识别与输出。
这次实验对我深化了对编译原理中词法分析的理解,并提高了我的编程能力。
词法分析程序实验报告
词法分析程序实验报告篇一:词法分析器_实验报告词法分析器实验报告实验目的:设计、编制、调试一个词法分析子程序-识别单词,加深对词法分析原理的理解。
实验要求:该程序要实现的是一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分界符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(一)实验内容(1)功能描述:对给定的程序通过词法分析器弄够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。
而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。
(2)程序结构描述:函数调用格式:参数含义:String string;存放读入的字符串 String str; 存放暂时读入的字符串 char ch; 存放读入的字符 int rs 判断读入的文件是否为空 char []data 存放文件中的数据 int m;通过switch用来判断字符类型,函数之间的调用关系图:函数功能:Judgement()判断输入的字符并输出单词符号,返回值为空; getChar() 读取文件的,返回值为空;isLetter(char c) 判断读入的字符是否为字母的,返回值为Boolean类型; switch (m) 判断跳转输出返回值为空;isOperator(char c)判断是否为运算符的,返回值为Boolean类型; isKey(String string)判断是否为关键字的,返回值为Boolean类型; isDigit(char c) 判断读入的字符是否为数字的,返回值为Boolean类型。
(二)实验过程记录:本次实验出错3次,第一次无法输出双运算符,于是采用双重if条件句进行判断,此方法失败,出现了重复输出,继续修改if语句,仍没有成功。
然后就采用了直接方法调用解决此问题。
对于变量的判断,开始忘了考虑字母和数字组成的变量,结果让字母和数字分家了,不过改变if语句的条件,解决了此问题。
中南大学编译原理实验报告
中南大学编译原理实验报告班级:计科1205姓名:***学号:**********实验一词法分析程序设计与实现一、实验目的加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。
二、实验内容自定义一种程序设计语言,或者选择已有的一种高级语言,编制它的词法分析程序。
词法分析程序的实现可以采用任何一种编程语言和编程工具。
从输入的源程序中,识别出各个具有独立意义的单词,即关键字、标识符、常数、运算符、界符。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)三、实验要求:1.对单词的构词规则有明确的定义;2.编写的分析程序能够正确识别源程序中的单词符号;3.识别出的单词以<种别码,值>的形式保存在符号表中,正确设计和维护符号表;4.对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成整个源程序的词法分析;四、实验步骤1.定义目标语言的可用符号表和构词规则;2.依次读入源程序符号,对源程序进行单词切分和识别,直到源程序结束;3.对正确的单词,按照它的种别以<种别码,值>的形式保存在符号表中;4.对不正确的单词,做出错误处理。
五、设计思路和实现过程本实验是词法分析器,我是用的是MFC实现的,我的设计思路就是按照书上提示的算法,先将几个词法分析器所需的基本函数用C++的形式实现,然后使用循环语句读入输入串的每一个字符,然后用if…else…语句实现,具体判断方式如下:1、如果读入的是字母,那么继续读入,知道读入的字符不是字母或者数字为止,对照标识符表,如果是标识符,则显示该串及对应标识符;如果不是,则显示该串和“$ID”;2、如果读入的是数字,则继续读入,知道不是数字为止,并显示该串和“$INT”;3、如果读入的是“=”,“+”,";",“(”,")","{","}",则分别输出该串和“$ASSIGN”,"$PLUS","$SEMICOLON","$LPAR","$RPAR","$LBRACE","$RBRACE";4、如果读入的是“*”,那么继续读入,如果下一个是“*”,则输出该串和"$POWER";否则输出该串和"$STAR",并将指针回退;5、如果独到输入串末尾,则退出。
词法分析程序设计与实现
实验一词法分析程序设计与实现一、实验目的及内容调试并完成一个词法分析程序,加深对词法分析原理的理解。
二、实验原理(状态转换图)1、C语言子集(1)关键字:begin if then while do end所有关键字都是小写。
(2)运算符和界符::= + –*/ 〈<= <> 〉>= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义: ID=letter(letter| digit)*NUM=digit digit *(4)空格由空白、制表符和换行符组成。
空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。
2、各种单词符号对应的种别码3、词法分析程序的功能输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数.二、软件平台及工具PC机以及VISUAL C++6.0软件。
三、实验方法、步骤(或:程序代码或操作过程) (1)程序代码:#include<stdio.h>#include〈string。
h>#include〈iostream.h〉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:”〈〈endl;do{cin.get(ch);prog[p++]=ch;while(ch!='#’);p=0;do{scaner();switch(syn){case 11: cout〈〈”("〈<syn〈〈”,"〈<sum〈<”)”<〈endl;break;case —1: cout〈<"Error in row ”〈〈row〈〈”!"<<endl;break;case -2: row=row++;break;default: cout〈<"("〈〈syn〈〈",”〈<token<〈”)”〈〈endl;break;}}while (syn!=0);}(2)创建编辑程序(3)连接、编译和调试程序(4)运行程序五、实验过程原始记录(测试数据、图表、计算等)(1)给定源程序begin x:=8;if x>0 then x:=2*x+1/5;end#输出结果(2)源程序(包括上式未有的while、do以及判断错误语句): beginx〈=$;whilea<0dob<>9—x;end#。
词法分析器的实现与设计
题目:词法分析器的设计与实现一、引言................................ 错误!未定义书签。
二、词法分析器的设计 (3)2.1词的内部定义 (3)2.2词法分析器的任务及功能 (3)32.2.2 功能: (4)2.3单词符号对应的种别码: (4)三、词法分析器的实现 (5)3.1主程序示意图: (5)3.2函数定义说明 (6)3.3程序设计实现及功能说明 (6)错误!未定义书签。
77四、词法分析程序的C语言源代码: (7)五、结果分析: (12)摘要:词法分析是中文信息处理中的一项基础性工作。
词法分析结果的好坏将直接影响中文信息处理上层应用的效果。
通过权威的评测和实际应用表明,IRLAS是一个高精度、高质量的、高可靠性的词法分析系统。
众所周知,切分歧义和未登录词识别是中文分词中的两大难点。
理解词法分析在编译程序中的作用,加深对有穷自动机模型的理解,掌握词法分析程序的实现方法和技术,用c语言对一个简单语言的子集编制一个一遍扫描的编译程序,以加深对编译原理的理解,掌握编译程序的实现方法和技术。
Abstract:lexical analysis is a basic task in Chinese information processing. The results of lexical analysis will directly affect the effectiveness of the application of Chinese information processing. The evaluation and practical application show that IRLAS is a high precision, high quality and high reliability lexical analysis system. It is well known that segmentation ambiguity and unknown word recognition are the two major difficulties in Chinese word segmentation. The understanding of lexical analyse the program at compile, deepen of finite automata model for understanding, master lexical analysis program implementation method and technology, using C language subset of a simple language compilation of a scanned again compiler, to deepen to compile the principle solution, master compiler implementation method and technology.关键词:词法分析器?扫描器?单词符号?预处理Keywords: lexical analyzer word symbol pretreatment scanner一、引言运用C语言设计词法分析器,由指定文件读入预分析的源程序,经过词法分析器的分析,将结果写入指定文件。
北邮-编译原理-词法分析
实验报告编译原理与技术ytinrete程序设计1题目:词法分析程序的设计与实现。
实验内容:设计并实现C语言的词法分析程序,要求如下。
(1)、可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。
(2)、可以识别并读取源程序中的注释。
(3)、可以统计源程序汇总的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果(4)、检查源程序中存在的错误,并可以报告错误所在的行列位置。
(5)、发现源程序中存在的错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。
|实验要求:方法1:采用C/C++作为实现语言,手工编写词法分析程序。
方法2:通过编写LEX源程序,利用LEX软件工具自动生成词法分析程序。
算法思路:首先通过遍历,统计行号和字符数,并记录所有的注释。
其次,再次读取,利用一个字符数组作为buffer保存一行的数据,在对其中的数据进行处理,完成之后再读下一行,跳过注释。
对于整行数据的处理,依靠空格将其分成单个单词再具体处理。
对于查错问题实在是一个难题,只能根据一些规则判定有错并记录。
&程序源代码:==*p || 'E'==*p || 'e'==*p)//小数和指数形式{(1,*p);p++;while(isdigit(*p)){(1,*p);p++;}}{sum_word++;(temp_word);cout<<endl<<"第"<<sum_word<<"个单词:"<<" 无符号数:" <<temp_word<<endl;}}elseif('#'==*p)//预处理文件特殊处理{while('\0'!=*p){(1,*p);》p++;}//p指向换行,完成直接退出(temp_word);}elseif('"'==*p)//字符串{();p++;while('"'!=*p)<{(1,*p);p++;}p++;sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 字符串:" <<temp_word<<endl;}elseif('+'==*p)//处理符号{。
北邮-编译原理-词法分析
实验报告编译原理与技术ytinrete程序设计1题目:词法分析程序的设计与实现。
实验内容:设计并实现C语言的词法分析程序,要求如下。
(1)、可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。
(2)、可以识别并读取源程序中的注释。
(3)、可以统计源程序汇总的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果(4)、检查源程序中存在的错误,并可以报告错误所在的行列位置。
((5)、发现源程序中存在的错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。
实验要求:方法1:采用C/C++作为实现语言,手工编写词法分析程序。
方法2:通过编写LEX源程序,利用LEX软件工具自动生成词法分析程序。
算法思路:首先通过遍历,统计行号和字符数,并记录所有的注释。
其次,再次读取,利用一个字符数组作为buffer保存一行的数据,在对其中的数据进行处理,完成之后再读下一行,跳过注释。
对于整行数据的处理,依靠空格将其分成单个单词再具体处理。
对于查错问题实在是一个难题,只能根据一些规则判定有错并记录。
-程序源代码:==*p || 'E'==*p || 'e'==*p)//小数和指数形式{(1,*p);p++;while(isdigit(*p)){(1,*p);—p++;}}sum_word++;(temp_word);cout<<endl<<"第"<<sum_word<<"个单词:"<<" 无符号数:" <<temp_word<<endl;}}elseif('#'==*p)//预处理文件特殊处理&while('\0'!=*p){(1,*p);p++;}//p指向换行,完成直接退出(temp_word);}else-if('"'==*p)//字符串{();p++;while('"'!=*p){(1,*p);p++;}p++;:sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 字符串:" <<temp_word<<endl;elseif('+'==*p)//处理符号{();if('='==*(p+1))//自加{temp_word = "+=";¥(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自加号:" <<temp_word<<endl;p+=2;//推进}elseif('+'==*(p+1))//自加1{temp_word = "++";(temp_word);—sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自加1号:" <<temp_word<<endl;p+=2;//推进}elseif(isdigit(*(p+1)))//有符号数{temp_word="+";for(int j=1; isdigit(*(p+j));j++)(1,*(p+j));,(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 有符号数:" <<temp_word<<endl;p+=2;//推进}else{temp_word = "+";(temp_word);sum_word++;,cout<<endl<<"第"<<sum_word<<"个单词:"<<" 加号:" <<temp_word<<endl;p+=2;//推进}}elseif('-'==*p)//处理符号{();if('='==*(p+1))//自减{—temp_word = "-=";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自减号:" <<temp_word<<endl;p+=2;//推进}elseif('-'==*(p+1))//自减1{temp_word = "--";、(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自减1号:" <<temp_word<<endl;p+=2;//推进}elseif(isdigit(*(p+1)))//有符号数{temp_word="-";for(int j=1; isdigit(*(p+j));j++)~(1,*(p+j));(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 有符号数:" <<temp_word<<endl;p+=2;//推进}else{temp_word = "-";(temp_word);:sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 减号:" <<temp_word<<endl;p+=2;//推进}}elseif('*'==*p)//处理符号{();if('='==*(p+1))//自乘!{temp_word = "*=";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自乘号:" <<temp_word<<endl;p+=2;//推进}else{temp_word = "*";[(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 乘号:" <<temp_word<<endl;p+=2;//推进}}elseif('/'==*p)//处理符号{'();if('='==*(p+1))//自除{temp_word = "*=";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自除号:" <<temp_word<<endl;p+=2;//推进}else|if('/'==*(p+1))//行注释return;// 直接跳出elseif('*'==*(p+1))//多行注释{in_comment=true;p+=2;while('\0'!=*p)//判断这行为止注释能不能结束{if(('*'==*p)&&('/')==*(p+1)),{in_comment = false;break;}p++;}}else{temp_word = "/";—(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 除号:" <<temp_word<<endl;p+=2;//推进}}elseif('='==*p)//处理等号{();¥if('='==*(p+1))//比较{temp_word = "==";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 比较号:"<<temp_word<<endl;p+=2;//推进}else{}temp_word = "=";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 赋值号:" <<temp_word<<endl;p+=2;//推进}}elseif('>'==*p)){();if('='==*(p+1)){temp_word = ">=";(temp_word);sum_word++;<<temp_word<<endl;p+=2;//推进}·else{temp_word = ">";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 大于号:" <<temp_word<<endl;p+=2;//推进}}《elseif('<'==*p){();if('='==*(p+1)){temp_word = "<=";(temp_word);sum_word++;<<temp_word<<endl;&p+=2;//推进}else{temp_word = "<";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 小于号:" <<temp_word<<endl;p+=2;//推进}[}elseif('!'==*p){();if('='==*(p+1)){temp_word = "!=";(temp_word);;sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 不等于号:" <<temp_word<<endl;p+=2;//推进}else{temp_word = "!";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 取反号:" <<temp_word<<endl;'p+=2;//推进}}elseif(':'==*p || '('==*p || ')'==*p || ';'==*p || '{' ==*p|| '}'==*p || ','==*p||'['==*p||']'==*p||'\0'==*p||'\n'==*p)//标点不算单词{if('('==*p)small_bracket++;//查错`if(')'==*p)small_bracket--;//查错if('{'==*p)big_bracket++;//查错if('}'==*p)big_bracket--;//查错p++;//推进}else//非法字符{`cout<<endl<<"error: 在第"<<current_line<<"行,出现非法字符:"<<*p<<endl;p++;}}}void analyse(void)//循环填充buffer并进行词法分析{char *p=buffer;(0);//文件指针回到头]while(!()){(*p);if('\n'==*p)//充满一句{*(p+1)='\0';*(p+2)='\0';current_line++;word_analyse();if(0!=small_bracket),{cout<<endl<<"error: 在第"<<current_line<<"行,小括号不匹配!"<<endl;small_bracket=0;}p=buffer;//重新填充}elsep++;{}if(0!=big_bracket)cout<<endl<<"error: 大括号不匹配!"<<endl;}void show_result(void)//显示统计结果{cout<<endl<<"the number of words is:"<<sum_word<<endl;cout<<endl<<"the number of char is:"<<sum_char<<endl;cout<<endl<<"the number of line is:"<<sum_line<<endl;¥cout<<"the followings are header:"<<endl;for(int i=0; i<(); i++){cout<<(i);}cout<<"the followings are comment:"<<endl;for(int i=0; i<(); i++){cout<<(i);}$}int main(void){("");if(NULL==file)》cout<<endl<<"找不到文件!"<<endl;else{//开始处理init();//初始化关键字analyse();();sum();//统计行数字节数注释show_result();//显示统计结果}int test;cin>>test;return 0;}实验结果测试:正常文件运行结果:有问题文件:运行结果:。
词法分析程序的设计(共15张PPT)
➢方法二:每个基本字一个编码;所有标识符 方法一:按单词的5大种类每种一个码,例如标识符为l,常数为2,基本字为3,运算符为4,界符为5。
GetChar();
分别判别ch字符是否为字为母或一数字 个编码;常数按类型分类,每类一个编 码;每个运算符一个编码;每个界符一个编 码。
(1,指向x的符号表入口)
(3,‘then’) 方法一:按单词的5大种类每种一个码,例如标识符为l,常数为2,基本字为3,运算符为4,界符为5。
(1,指向y的符号表入口)
(1,指向y的符号表入口)
(1,指向x的符号表入口 else If(ch=‘/’) {状态 l 的对应程序段;}
)
(4,‘:=’)
二元式(单词种别,单词自身的值) 对常数,基本字,运算符,界符就是他们本身的值
3. 换行符不能删,对于错误处理起作用。 (1,指向i的符号表入口)
每当遇到左括号,则计数器加1
❖ 复合型特殊符,如“:=”的处理
读到“:”时不能判断是否为冒号,必须读下一字符。
第9页,共15页。
❖ 括号类配对: “‘”和“’”、左注释符和右注释符的配对。也 可以把begin …end ,if …then,[ ],{ },( )等语 法配对在词法分析中进行处理 处理方法:
第5页,共15页。
单词的机内表示
二元式(单词种别,单词自身的值) 种别是语法分析需要的信息 二元式(单词种别,单词自自身身的值)值是编译其他阶段需要的信息 种别编码(常用整数编码) 常数按类型分类,每类一个编码;
二元式(单词种别,单词自身的值) GetChar();
➢ 方法一:按单词的5大种类每种一个码,例 常数按类型分类,每类一个编码;
编译原理实验报告
《编译原理》实验报告软件131 陈万全132852一、需求分析通过对一个常用高级程序设计语言的简单语言子集编译系统中词法分析、语法分析、语义处理模块的设计、开发,掌握实际编译系统的核心结构、工作流程及其实现技术,获得分析、设计、实现编译程序等方面的实际操作能力,增强设计、编写和调试程序的能力。
通过开源编译器分析、编译过程可视化等扩展实验,促进学生增强复杂系统分析、设计和实现能力,鼓励学生创新意识和能力。
1、词法分析程序设计与实现假定一种高级程序设计语言中的单词主要包括五个关键字begin、end、if、then、else;标识符;无符号常数;六种关系运算符;一个赋值符和四个算术运算符,试构造能识别这些单词的词法分析程序。
输入:由符合和不符合所规定的单词类别结构的各类单词组成的源程序文件。
输出:把所识别出的每一单词均按形如(CLASS,VALUE)的二元式形式输出,并将结果放到某个文件中。
对于标识符和无符号常数,CLASS字段为相应的类别码的助记符;VALUE字段则是该标识符、常数的具体值;对于关键字和运算符,采用一词一类的编码形式,仅需在二元式的CLASS字段上放置相应单词的类别码的助记符,VALUE字段则为“空”。
2、语法分析程序设计与实现选择对各种常见高级程序设计语言都较为通用的语法结构——算术表达式的一个简化子集——作为分析对象,根据如下描述其语法结构的BNF定义G2[<算术表达式>],任选一种学过的语法分析方法,针对运算对象为无符号常数和变量的四则运算,设计并实现一个语法分析程序。
G2[<算术表达式>]:<算术表达式> → <项> | <算术表达式>+<项> | <算术表达式>-<项><项> → <因式> | <项>*<因式> | <项>/<因式><因式> → <运算对象> | (<算术表达式>)若将语法范畴<算术表达式>、<项>、<因式>和<运算对象>分别用E、T、F和i 代表,则G2可写成:G2[E]:E → T | E+T | E-T T → F | T*F | T/F F → i | (E)输入:由实验一输出的单词串,例如:UCON,PL,UCON,MU,ID ······输出:若输入源程序中的符号串是给定文法的句子,则输出“RIGHT”,并且给出每一步分析过程;若不是句子,即输入串有错误,则输出“ERROR”,并且显示分析至此所得的中间结果,如分析栈、符号栈中的信息等,以及必要的出错说明信息。
词法分析器实验报告
词法分析器实验报告词法分析器实验报告一、引言词法分析器是编译器中的重要组成部分,它负责将源代码分解成一个个的词法单元,为之后的语法分析提供基础。
本实验旨在设计和实现一个简单的词法分析器,以深入理解其工作原理和实现过程。
二、实验目标本实验的目标是设计和实现一个能够对C语言代码进行词法分析的程序。
该程序能够将源代码分解成关键字、标识符、常量、运算符等各种词法单元,并输出其对应的词法类别。
三、实验方法1. 设计词法规则:根据C语言的词法规则,设计相应的正则表达式来描述各种词法单元的模式。
2. 实现词法分析器:利用编程语言(如Python)实现词法分析器,将源代码作为输入,根据词法规则将其分解成各种词法单元,并输出其类别。
3. 测试和调试:编写测试用例,对词法分析器进行测试和调试,确保其能够正确地识别和输出各种词法单元。
四、实验过程1. 设计词法规则:根据C语言的词法规则,我们需要设计正则表达式来描述各种词法单元的模式。
例如,关键字可以使用'|'操作符将所有关键字列举出来,标识符可以使用[a-zA-Z_][a-zA-Z0-9_]*的模式来匹配,常量可以使用[0-9]+的模式来匹配等等。
2. 实现词法分析器:我们选择使用Python来实现词法分析器。
首先,我们需要读取源代码文件,并将其按行分解。
然后,针对每一行的代码,我们使用正则表达式进行匹配,以识别各种词法单元。
最后,我们将识别出的词法单元输出到一个结果文件中。
3. 测试和调试:我们编写了一系列的测试用例,包括各种不同的C语言代码片段,以测试词法分析器的正确性和鲁棒性。
通过逐个测试用例的运行结果,我们可以发现和解决词法分析器中的问题,并进行相应的调试。
五、实验结果经过多次测试和调试,我们的词法分析器能够正确地将C语言代码分解成各种词法单元,并输出其对应的类别。
例如,对于输入的代码片段:```cint main() {int a = 10;printf("Hello, world!\n");return 0;}```我们的词法分析器将输出以下结果:```关键字:int标识符:main运算符:(运算符:)运算符:{关键字:int标识符:a运算符:=常量:10运算符:;标识符:printf运算符:(常量:"Hello, world!\n"运算符:)运算符:;关键字:return常量:0运算符:;```可以看到,词法分析器能够正确地将代码分解成各种词法单元,并输出其对应的类别。
词法分析程序的设计与实现
词法分析程序的设计与实现方法1:采用C作为实现语言,手工编制一.文法及状态转换图1.语言说明:C语言有以下记号及单词:(1)标识符:以字母开头的、后跟字母或数字组成的符号串。
(2)关键字:标识符集合的子集,该语言定义的关键字有32个,即auto,break,case,char,const,continue,default,do,double,else,enum, extern,float,for,goto,if,int,long,register,return,short,signed,static, sizeof,struct,switch,typedef ,union,unsigned ,void, volatile和while。
(3)无符号数:即常数。
(4)关系运算符:<,<=,==,>,>=,!=。
(5)逻辑运算符:&&、||、!。
(6)赋值号:=。
(7)标点符号:+、++、-、--、*、:、;、(、)、?、/、%、#、&、|、“”、,、.、{}、[]、_、^等(8)注释标记:以“/*”开始,以“*/”结束。
(9)单词符号间的分隔符:空格。
2.记号的正规文法:仅给出各种单词符号的文法产生式(1)标识符的文法id->letter ridrid->ε|letter rid|digit rid(2)无符号整数的文法digits->digit remainderremainder->ε|digit remainder(3)无符号数的文法num->digit num1num1->digit num1|. num2|E num4|εnum2->digit num3num3->digit num3|E num4|εnum4->+digits|-digits|digit num5digits->digit num5num5->digit num5|ε(4)关系运算符的文法relop-> <|<=|==|>|>=|!=(5)赋值号的文法assign_op->=(6)标点符号的文法special_symbol->+|-|*|%|#|^|(|)|{|}|[|]|:|;|”|?|/|,|.& (7)逻辑运算符的文法logic->&&| || | !(8)注释头符号的文法note->/starstar->*3.状态转换图其中,状态0是初始状态,若此时读入的符号是字母,则转换到状态1,进入标识符识别过程;如果读入的是数字,则转换到状态2,进入无符号数识别过程;……;若读入的符号是/,转换到状态11,再读入下一个符号,如果读入的符号是*,则转换到状态12,进入注释处理状态;如果在状态0读入的符号不是语言所定义的单词符号的开始字符,则转换到状态13,进入错误处理状态。
(完整word版)编译原理词法分析程序实现实验报告
(完整word版)编译原理词法分析程序实现实验报告实验一词法分析程序实现一、实验内容选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。
输入:由无符号数和+,-,*,/, ( , ) 构成的算术表达式,如1.5E+2-100。
输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。
二、设计部分因为需要选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来,而其中的关键则为无符号数的识别,它不仅包括了一般情况下的整数和小数,还有以E为底数的指数运算,其中关于词法分析的无符号数的识别过程流程图如下:GOTO 1:(完整word版)编译原理词法分析程序实现实验报告GOTO 2:三、源程序代码部分#include <stdio.h>#include<stdlib.h>#include <math.h>#define MAX 100#define UNSIGNEDNUMBER 1#define PLUS 2#define SUBTRACT 3#define MULTIPLY 4#define DIVIDE 5#define LEFTBRACKET 6#define RIGHTBRACKET 7#define INEFFICACIOUSLABEL 8#define FINISH 111int count=0;int Class;void StoreType();int Type[100];char Store[20]={'\0'};void ShowStrFile();//已经将要识别的字符串存在文件a中void Output(int a,char *p1,char *p2);//字符的输出过程int Sign(char *p);//'+''-''*''/'整体识别过程int UnsignedNum(char *p);//是否适合合法的正整数0~9int LegalCharacter(char *p);//是否是合法的字符:Sign(p)||UnsignedNum(p)||'E'||'.' void DistinguishSign(char *p);//'+''-''*''/'具体识别过程void TypyDistinguish();//字符的识别过程void ShowType();//将类别码存储在Type[100]中,为语法分析做准备void ShowStrFile()//已经将要识别的字符串存在文件a中{FILE *fp_s;char ch;if((fp_s=fopen("a.txt","r"))==NULL){printf("The FILE cannot open!");exit(0);}elsech=fgetc(fp_s);while(ch!=EOF){putchar(ch);ch=fgetc(fp_s);}printf("\n");}void StoreStr()//将文件中的字符串存储到数组Store[i] {FILE *fp=fopen("a.txt","r");char str;int i=0;while(!feof(fp)){fscanf(fp,"%c",&str);if(str=='?'){Store[i]='\0';break;}Store[i]=str;i++;}Store[i]='\0';}void ShowStore(){int i;for (i=0;Store[i]!='\0';i++)printf("%c",Store[i]);printf("\n");}void Output(int a,char *p1,char *p2){printf("%3s\t%d\t%s\t","CLASS",a,"VALUE");while(p1<=p2){printf("%c",*p1);p1++;}printf("\n");}int Sign(char *p){char ch=*p;if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')') return 1;elsereturn 0;}int UnsignedNum(char *p){char ch=*p;if('0'<=ch&&ch<='9')return 1;elsereturn 0;}int LegalCharacter(char *p){char ch=*p;if(Sign(p)||UnsignedNum(p)||ch=='E'||ch=='.')。
北邮编译原理-词法分析文档和程序
实验报告班级:2011211314姓名: oneseven学号:一.题目:词法分析程序设计与实现二.实验内容:设计并实现 C 语言的词法分析程序,要求如下。
(1) 可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。
(2) 可以识别并读取源程序中的注释。
(3) 可以统计源程序中的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果。
(4) 检查源程序中存在的非法字符错误,并可以报告错误所在的行列位置。
三.实现要求:采用C/C++作为实现语言,手工编写词法分析程序。
四.实现功能:基本完成了实验内容中要求的所有功能。
(1)识别出源程序中的每个单词符号,并以记号的形式输出每个单词符号(2)识别并读取源程序中的注释(3) 统计源程序中的语句行数、单词个数和字符个数(4) 检查源程序中存在的非法字符错误,并可以报告错误所在的行列位置。
注:本程序未把注释中的单词符号,“”中的单词符号统计在单词个数中。
单词个数只包括了标示符,关键字,无符号数。
五.实验原理:1.词法分析程序的功能:输入源程序,输出单词符号的记号形式,如图所示:源程序单词符号的记号形式2.处理过程:每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词,直至整个源程序全部扫描完毕,并形成相应的单词串形式的源程序。
六.代码#include<iostream>#include<fstream>#include<string>#include <iomanip>using namespace std;string keyword[32]={"auto","break","case","char","const", //关键字"continue","default","do","double","else","extern","enum","float","for","goto","if","int","long","return","register","static","short","signed","unsigned","struct","switch","sizeof","typedef","union","volatile","void","while"};int column=0,row=1,character=0,word=0;ifstream inf("test.txt",ios::in);char c;int find_key(string word) //匹配关键字{for(int i=0;i<32;i++)if(keyword[i].compare(word)==0)return 1;return 0;}void choice(){while(c=='\n'||c==' '||c=='\t') //不计空白符{if (c=='\n'){row++;column=0; //row清零,重新计数另一行}c=inf.get();column++;}return;}void get() //读取字符{character++;c=inf.get();column++;return;}int process(){string str="";if(inf.fail())cout<<"请创建test.txt并输入程序"<<endl;else{ofstream outf("out.txt");outf<<setw(10)<<"正规表达式"<<setw(30)<<"记号"<<setw(30)<<"属性"<<endl;c=inf.get();column++;while(c!=EOF){switch(c){ //匹配字符对应记号case 'a'...'z':case 'A'...'Z':case '_':word++;while(isalpha(c)||isdigit(c)||c=='_'){str+=c;get();}if(c=='@'||c=='?'||c=='$'||c=='#'){int tag=column;while(isalpha(c)||isdigit(c)||c=='_'||c=='@'||c=='?'||c=='$'||c=='#'){str+=c;get();}outf<<setw(10)<<str<<setw(30)<<"ERROR"<<setw(30)<<"错误在第"<<row<<"行第"<<tag<<"列"<<endl;str="";break;}if(find_key(str)){outf<<setw(10)<<str<<setw(30)<<str<<setw(30)<<"关键字"<<endl;str="";}else{outf<<setw(10)<<str<<setw(30)<<"id"<<setw(30)<<"标示符"<<endl;str="";}break;case '0'...'9':word++;while(isdigit(c)||c=='.'||c=='e'||c=='E'){str+=c;if(c=='e'||c=='E'){get();str+=c;}get();}if(isalpha(c)){int tag=column;while(isalpha(c)||c=='_'||isdigit(c)||c=='@'||c=='?'||c=='$'||c=='#'){str+=c;get();}outf<<setw(10)<<str<<setw(30)<<"ERROR"<<setw(30)<<"错误在第"<<row<<"行第"<<tag<<"列"<<endl;str="";break;}outf<<setw(10)<<str<<setw(30)<<"num"<<setw(30)<<"无符号数"<<endl;str="";break;case'>':get();if(c=='=')outf<<setw(10)<<">="<<setw(30)<<"relop"<<setw(30)<<"关系运算符"<<endl;else if(c=='>')outf<<setw(10)<<">>"<<setw(30)<<"bit_op"<<setw(30)<<"位运算符"<<endl;else{outf<<setw(10)<<">"<<setw(30)<<"relop"<<setw(30)<<"关系运算符"<<endl;break;}get();break;case'<':get();if(c=='=')outf<<setw(10)<<"<="<<setw(30)<<"relop"<<setw(30)<<"关系运算符"<<endl;else if(c=='<')outf<<setw(10)<<"<<"<<setw(30)<<"bit_op"<<setw(30)<<"位运算符"<<endl;else{outf<<setw(10)<<"<"<<setw(30)<<"relop"<<setw(30)<<"关系运算符"<<endl;break;}get();break;case'=':get();if(c=='=')outf<<setw(10)<<"=="<<setw(30)<<"relop"<<setw(30)<<"关系运算符"<<endl;else{outf<<setw(10)<<"="<<setw(30)<<"assign_op"<<setw(30)<<"赋值符"<<endl;break;}get();break;case'!':get();if(c=='=')outf<<setw(10)<<"!="<<setw(30)<<"relop"<<setw(30)<<"关系运算符"<<endl;else{outf<<setw(10)<<"!"<<setw(30)<<"logic_op"<<setw(30)<<"逻辑运算符"<<endl;break;}get();break;case'|':get();if(c=='|')outf<<setw(10)<<"||"<<setw(30)<<"relop"<<setw(30)<<"逻辑运算符"<<endl;else{outf<<setw(10)<<"|"<<setw(30)<<"logic_op"<<setw(30)<<"位运算符"<<endl;break;}get();break;case'&':get();if(c=='&')outf<<setw(10)<<"&&"<<setw(30)<<"relop"<<setw(30)<<"逻辑运算符"<<endl;else{outf<<setw(10)<<"&"<<setw(30)<<"logic_op"<<setw(30)<<"位运算符"<<endl;break;get();break;case'+':get();if(c=='+')outf<<setw(10)<<"++"<<setw(30)<<"alg_op"<<setw(30)<<"运算符"<<endl;else if(c=='=')outf<<setw(10)<<"+="<<setw(30)<<"alg_op"<<setw(30)<<"运算符"<<endl;else{outf<<setw(10)<<"+"<<setw(30)<<"alg_op"<<setw(30)<<"运算符"<<endl;break;}get();break;case'-':get();if(c=='-')outf<<setw(10)<<"--"<<setw(30)<<"alg_op"<<setw(30)<<"运算符"<<endl;else if(c=='=')outf<<setw(10)<<"-="<<setw(30)<<"alg_op"<<setw(30)<<"运算符"<<endl;else{outf<<setw(10)<<"-"<<setw(30)<<"alg_op"<<setw(30)<<"运算符"<<endl;break;}get();break;case'*':get();if(c=='=')outf<<setw(10)<<"*="<<setw(30)<<"alg_op"<<setw(30)<<"运算符"<<endl;else{outf<<setw(10)<<"*"<<setw(30)<<"alg_op"<<setw(30)<<"运算符"<<endl;break;}break;case '\"':str+=c;get();while(c!='\"'){str+=c;get();if(c==' '||c=='\t')character--;}str+='\"';outf<<setw(10)<<str<<setw(30)<<"literal"<<setw(30)<<"字符串"<<endl;str="";get();break;case'/':str+=c;get();if(c=='=')outf<<setw(10)<<"/="<<setw(30)<<"alg_op"<<setw(30)<<"运算符"<<endl;else if(c=='/'){str+=c;get();while(c!='\n'&&c!=EOF){str+=c;get();}character--;outf<<setw(10)<<str<<setw(30)<<"annotation"<<setw(30)<<"注释"<<endl;}else if(c=='*'){str+=c;get();char tag=c;while(tag!='*'&&c!='/'&&c!=EOF){str+=c;tag=c;choice();get();}str+=c;outf<<setw(10)<<str<<setw(30)<<"annotation"<<setw(30)<<"注释"<<endl;}else{outf<<setw(10)<<"/"<<setw(30)<<"alg_op"<<setw(30)<<"运算符"<<endl;str="";break;}str="";get();break;case ' ':case '\n':case EOF:break;default:outf<<setw(10)<<c<<setw(30)<<c<<setw(30)<<"符号"<<endl;get();break;}choice();}outf<<"语句行数:"<<row<<endl;outf<<"单词个数:"<<word<<endl;outf<<"字符个数:"<<character<<endl;inf.close();outf.close();return 1;}inf.close();return 0;}int main(){int flag;flag=process();if(flag==1){cout<<"词法分析源程序详见test.txt"<<endl;cout<<"词法分析结果及错误分析详见out.txt"<<endl; //输出结果cout<<"语句行数:"<<row<<endl;cout<<"单词个数:"<<word<<endl;cout<<"字符个数:"<<character<<endl;}system("pause");return 0;}七.测试数据:(1)运行程序(2)测试代码test.txt(3)输出结果out.txt。
实验一 词法分析程序的设计与实现(C语言)
实验一 词法分析程序的设计与实现(C 语言)一、实验目的通过C 语言词法分析程序的实现理解编译程序过程中对单词的分析过程。
二、实验重难点DFA 自动机的数据结构表示,程序流程图,词法分析程序实现三、实验内容与要求实验内容:1. 设计存储DFA 自动机的数据结构2.绘制程序流程图3. 词法分析程序设计四、实验学时2课时五、实验设备与环境C 语言编译环境六、根据实验过程填写下列内容1.DFA 自动机的状态转换图和数据结构设计。
a /b2. 程序流程图(见附页)3. 代码#include<stdio.h>int f(int x,char e){ int df[4][2]={{2,3},{4,3},{2,4},{4,4}};U a a a S b Q bV bint i;if(e=='a')i=df[x][1];if(e=='b')i=df[x][2];return(i);}void main(){ int S=1,U=2,V=3,Q=4;int k=S;char c;printf("请输入字符,按#结束:\n");c=getchar();while(c!='#'){k=f(k,c);c=getchar();}if(k==Q) printf("你输入的字符串能被DFA所识别\n");else printf("你输入的字符串能被DFA所识别\n");}4.测试数据及结果分析(结果见附页)分析:从实验的结果可以看出上面程序代码基本上可以实现所给DFA的要求,但是有关实验的可读性和功能方面还有待进一步改进。
程序流程图教师评语:是否完成实验程序的预备设计? 是: 不是: 程序能否正常运行? 是: 不是: 有无测试数据及结果分析 是: 不是: 是否在本次规定时间完成所有项目? 是: 不是: 实验成绩等级: 教师签名:N0:时间:开始初始化输入句子判断是否退出标志判断是否被接受?接受不接受输出错误位置NY NY结束。
实验一词法分析
for (int i=0;i<50;i++)
{
cout<<a[i];
}
cout<<endl;
cout<<"------------字符串判断完毕------------"<<endl;
}
system("pause");
return 0;
}
Vc6.0新建空工程+源文件
{
b[k]=a[t+1]; //存放是标识符的字符
k++;
}
else if((a[t+1]>='0')&&(a[t+1]<='9')) //识别是非标识符的字符
{
c[m]=a[t+1]; //存放是单个数字的字符
m++;
}
else{
e[p]=a[t+1]; //存放是非标识符的字符
p++;
}
}
cout<<"--------------判断结果----------------"<<endl;
char a[50]={0}; //存放字符串
char b[50]={0}; //存放标志符
char d[50]={0}; //存放非标识符
cout<<"请输入字符串(以$结束):"<<endl;
for(int i=0;i<50;i++)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、实验目的及内容
调试并完成一个词法分析程序,加深对词法分析原理的理解。
二、实验原理(状态转换图)
1、C语言子集
(1)关键字:
beginif thenwhiledoend
所有关键字都是小写。
(2)运算符和界符:
:=+–*/<<=<>>>==;()#
(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:
charch;
int syn,p,m=0,n,row,sum=0;
char *rwtab[6]={"begin","if","then","while","do","end"};
voidscaner()
{
ﻩfor(n=0;n<8;n++) token[n]=NULL;
ﻩch=prog[p++];
ﻩwhile(ch==' ')
{
case11:cout<<"("<<syn<<","<<sum<<")"<<endl;break;
case-1: cout<<"Errorinrow"<<row<<"!"<<endl;break;
case -2: row=row++;break;
default: cout<<"("<<syn<<","<<token<<")"<<endl;break;
{
ﻩﻩ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;
default:syn=-1;break;
}
}
voidmain()
{
ﻩp=0;
ﻩrow=1;
cout<<"Pleaseinputstring:"<<endl;
do
{
ﻩcin.get(ch);
ﻩprog[p++]=ch;
ﻩ}
while(ch!='#');
ﻩp=0;
do
ﻩ{
ﻩscaner();
switch(syn)
ID=letter(letter| digit)*
NUM=digitdigit*
(4)空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。
2、各种单词符号对应的种别码
单词符号
种别码
单词符号
种别码
begin
1
:
17
if
2
:=
18
then
3
>
20
while
ﻩ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;
ﻩﻩ}
}
ﻩwhile(syn!=0);
}
(2)创建编辑程序
(3)连接、编译和调试程序
(4)运行程序
五、实验过程原始记录( 测试数据、图表、计算等)
(1)给定源ቤተ መጻሕፍቲ ባይዱ序
begin x:=8; ifx>0thenx:=2*x+1/5;end#
输出结果
(2)源程序(包括上式未有的while、do以及判断错误语句):
4
<>
21
do
5
<=
22
end
6
<
23
letter(letter|digit)*
10
>=
24
digitdigit *
11
=
25
*
13
;
26
/
14
(
27
+
15
)
28
-
16
#
0
3、词法分析程序的功能
输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;
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++];
token为存放的单词自身字符串;
sum为整型常数。
二、软件平台及工具
PC机以及VISUAL C++6.0软件。
三、实验方法、步骤(或:程序代码或操作过程)
(1)程序代码:
#include<stdio.h>
#include<string.h>
#include<iostream.h>
charprog[80],token[8];
begin
x<=$;
while
a<0
do
b<>9-x;
end
#
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;
ﻩﻩﻩ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;
ﻩﻩ}
}
ﻩelseif((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;
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;