实验1-3 《编译原理》词法分析程序设计方案讲课教案

合集下载

编译原理词法分析课程设计

编译原理词法分析课程设计

DONGFANG COLLEGE,FUJIAN AGRICULTURE AND FORESTRY UNIVERSITY课程名称:编译原理词法分析系别:计算机科学系年级专业: 2013级计算机科学与技术学号: 1350303059姓名:张清鉴任课教师:朱均燕成绩:2015 年12 月31 日目录前言 (1)一、课程设计的目的 (1)二、课程设计的要求 (1)1.待分析的简单语言的词法 (1)2.各种单词符号对应的种别码 (2)3. 此法分析程序功能 (3)三、课程设计报告内容 (3)3.1课程设计的环境 (3)3.2系统技术分析: (3)3.3 系统流程图及各模块 (4)3.4源程序代码清单 (4)3.5程序调试情况 (9)四、总结 (10)参考文献 (11)前言词法分析(英语:lexical analysis)是计算机科学中将字符序列转换为单词(Token)序列的过程。

进行词法分析的程序或者函数叫作词法分析器(Lexical analyzer,简称Lexer),也叫扫描器(Scanner)。

词法分析器一般以函数的形式存在,供语法分析器调用。

词法分析阶段是编译过程的第一个阶段,是编译的基础。

这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。

词法分析程序实现这个任务。

词法分析程序可以使用Lex等工具自动生成。

词法分析是编译程序的第一个阶段且是必要阶段;词法分析的核心任务是扫描、识别单词且对识别出的单词给出定性、定长的处理;实现词法分析程序的常用途径:自动生成,手工生成.词法分析一、课程设计的目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

二、课程设计的要求1.待分析的简单语言的词法(1)关键字:begin if then while do end所有的关键字都是小写。

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

实验1-3-《编译原理》词法分析程序设计方案

实验1-3-《编译原理》词法分析程序设计方案

实验1-3 《编译原理》S语言词法分析程序设计方案一、实验目的了解词法分析程序的两种设计方法之一:根据状态转换图直接编程的方式;二、实验内容1.根据状态转换图直接编程编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。

在此,词法分析程序作为单独的一遍,如下图所示。

具体任务有:(1)组织源程序的输入(2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件(3)删除注释、空格和无用符号(4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。

将错误信息输出到屏幕上。

(5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。

标识符表结构:变量名,类型(整型、实型、字符型),分配的数据区地址注:词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。

常量表结构:常量名,常量值三、实验要求1.能对任何S语言源程序进行分析在运行词法分析程序时,应该用问答形式输入要被分析的S源语言程序的文件名,然后对该程序完成词法分析任务。

2.能检查并处理某些词法分析错误词法分析程序能给出的错误信息包括:总的出错个数,每个错误所在的行号,错误的编号及错误信息。

本实验要求处理以下两种错误(编号分别为1,2):1:非法字符:单词表中不存在的字符处理为非法字符,处理方式是删除该字符,给出错误信息,“某某字符非法”。

2:源程序文件结束而注释未结束。

注释格式为:/* …… */四、保留字和特殊符号表括整数和实数)单词助记符while switch break begin end id num内码值- - - - - 在符号表中的位置在常数表中的位置单词代码19 20 21 22 23 24 25 26 27 单词+ - * / % ( ) [ ] 单词助记符+ - * / % ( ) [ ] 内码值- - - - - - - - -单词代码28 28 29 30 单词!= < > <= >= == ;{ } 单词助记符rlop ;{ } 内码值!= < > <= >= == - -单词代码37 38 39 40 41 42 43 44 45 单词/= += -= *= %= || && ! = 单词助记符/= += -= *= %= or and not = 内码值- - - - - - - - - 单词的构词规则:字母=[A-Za-z]数字=[0-9]标识符=(字母|_)(字母|数字)*数字=数字(数字)*(.数字+|)四、S语言表达式和语句说明1.算术表达式:+、-、*、/、%2.关系运算符:>、>=、<、<=、==、!=3.赋值运算符:=,+=、-=、*=、/=、%=4.变量说明:类型标识符变量名表;5.类型标识符:int char float6.If语句:if 表达式then 语句[else 语句]7.For语句:for(表达式1;表达式2;表达式3)语句8.While语句:while 表达式do 语句9.S语言程序:由函数构成,函数不能嵌套定义。

编译原理实验一词法分析

编译原理实验一词法分析

编译原理实验⼀词法分析实验⼀词法分析【实验⽬的】 (1)熟悉词法分析器的基本功能和设计⽅法; (2)掌握状态转换图及其实现; (3)掌握编写简单的词法分析器⽅法。

【实验内容】 对⼀个简单语⾔的⼦集编制⼀个⼀遍扫描的词法分析程序。

【实验要求】 (1)待分析的简单语⾔的词法 1) 关键字 begin if then while do end 2) 运算符和界符 := + - * / < <= <> > >= = ; ( ) # 3) 其他单词是标识符(ID)和整形常数(NUM),通过以下正规式定义: ID=letter(letter|digit)* NUM=digitdigit* 4) 空格由空⽩、制表符和换⾏符组成。

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

(2)各种单词符号对应的种别编码 (3)词法分析程序的功能 输⼊:所给⽂法的源程序字符串 输出:⼆元组(syn,token 或 sum)构成的序列。

syn 为单词种别码; token 为存放的单词⾃⾝字符串; sum 为整形常数。

【实验代码】1 #include<iostream>2 #include<string.h>3 #include<conio.h>4 #include<ctype.h>5using namespace std;6int sum,syn,p,m,n;7char ch,chs[8],s[100];8char *tab[6]={"begin","if","then","while","do","end"};910int scanner(){11for(n=0;n<8;n++) chs[n]='\0';12 m=0;13 n=0;14 ch=s[p++];15while(ch=='') ch=s[p++];16if(isalpha(ch)){17while(isalpha(ch)||isdigit(ch)){18//isalpha(ch)函数:判断字符ch是否为英⽂字母,⼩写字母为2,⼤写字母为1,若不是字母019//isdigit(ch)函数:判断字符ch是否为数字,是返回1,不是返回020 chs[m++]=ch;21 ch=s[p++];22 }23 syn=10;24for(n=0;n<6;n++)25if(strcmp(chs,tab[n])==0) syn=n+1;26 p--;27 }else if(isdigit(ch)){28 sum=0;29while(isdigit(ch)){30 sum=sum*10+(ch-'0');31 ch=s[p++];32 }33 syn=11;34 p--;35 }else if(ch==':'){36 syn=17;37 chs[m++]=ch;38 ch=s[p++];39if(ch=='='){ syn=18;chs[m]=ch;p++;}40 p--;41 }else if(ch=='<'){42 syn=20;43 chs[m++]=ch;44 ch=s[p++];45if(ch=='>') { syn=21;chs[m]=ch;p++;}46if(ch=='=') { syn=22;chs[m]=ch;p++;}47 p--;48 }else if(ch=='>'){49 syn=23;50 chs[m++]=ch;51 ch=s[p++];52if(ch=='=') { syn=24;chs[m]=ch;p++;}53 p--;54 }else switch(ch){55case'+':syn=13;chs[m]=ch;break;56case'-':syn=14;chs[m]=ch;break;57case'*':syn=15;chs[m]=ch;break;58case'/':syn=16;chs[m]=ch;break;59case'=':syn=25;chs[m]=ch;break;60case';':syn=26;chs[m]=ch;break;61case'(':syn=27;chs[m]=ch;break;62case')':syn=28;chs[m]=ch;break;63case'#':syn=0;chs[m]=ch;break;64default:syn=-1;65 }66return0;67 }68int main(){69 p=0;70 cout<<"Please input code and end with character '#':"<<endl;71do{72//cin>>ch;不识别空格73 ch=getchar();74 s[p++]=ch;75 }while(ch!='#');76 p=0;77do{78 scanner();79switch(syn){80case11:cout<<'('<<syn<<','<<sum<<')'<<endl;break;81case -1:cout<<'('<<syn<<','<<"error"<<')'<<endl;break;82default:cout<<'('<<syn<<','<<chs<<')'<<endl;83 }84 }while(syn!=0);85//getch():是⼀个不回显函数,当⽤户按下某个字符时,函数⾃动读取,⽆需按回车,所在头⽂件是conio.h。

编译原理综合性实验:词法分析的设计

编译原理综合性实验:词法分析的设计
编译过程中编译程序需要不断汇集和反复查证出现在源程序中各种名字的属性和特征 等有关信息。这些信息通常记录在符号表中。符号表中的每一项一般包含两部分:名字,与 此名字有关的信息,如类型,种属,值等。符号表主要在词法或语法分析阶段生成,可能用 于语义检查、产生中间代码以及最终生成目标代码等不同阶段。
对数字常数的处理如下:先查符号表 VAL 栏,若发现相同的常数则直接输出其二元式。 若表内无相同的常数,则将数字常数填入符号表内,在 TYPE 栏内填入整型或实型,然后输 出其二元式。二元式中包含该常数在符号表中的入口。
1.3 词法分析程序的详细设计
图 1-3 的数据流图属于输入-变换-输出形式的变换型数据流图,但加工 1.3—1.9 构成了典型的事务处理型数据流图。根据数据流图,可以得到词法分析 程序的总体框架,如图 1-4。
图 1-3 词法分析程序的详细数据流图 在上面的数据流图中,各个加工处理完成的功能如下: 加工 1.1(读一行并打印):收到读下一行命令后,从源程序读入一行,装入缓冲区,行计 数,并打印。在这里需要注意的是,回车换行在源程序(文本文件)中用两个字符 0D0AH 来表示,而用高级语言(C 语言)读入内存后,就用一个字符 0AH 来表示,这是在用高级
查找函数可以使用顺序查找,也可以使用折半查找。 例如:使用顺序查找方法查找给定单词 key 是否是关键字的函数原型和算法描述如下:
int iskeyword (char * str)/*设 keyword 为所有关键字列表*/ /*该函数返回 0 表示 str 不是关键字,不为 0 表示 str 是关键字*/
词不能跨行书写; (4) 关键字都是保留字。
1.2 词法分析程序的总体设计
图 1-2 词法分析程序的顶层数据流图 图 1-2 是词法分析程序的顶层数据流图,即是词法分析程序的输入输出界面图,由此可 以看出词法分析程序的功能就是从源程序中读入一个个字符,依据一定的构词规则,识别出 各类有用的单词。其中源程序清单和错误信息从屏幕、打印机或文件输出,其余文件均以顺 序文件的形式输出到外存储器上,以供下一阶段使用。由此可以得到更详细的数据流图,如 图 1-3。

编译原理 词法分析程序设计

编译原理 词法分析程序设计

实验1 词法分析程序设计【实验目的】(1)理解词法分析在编译程序中的作用(2)加深对有穷自动机模型的理解(3)掌握词法分析程序的实现方法和技术【实验内容】对一个简单语言的子集编制一个一遍扫描的词法分析程序。

【设计思路】图1.1 词法分析主程序示意图2、源程序代码(1)scan.h //头文件-----扫描程序#include<stdio.h>#include<string.h>#define CLEAR memset(token,'\0',sizeof(token))//清空数组tokenchar prog[80],token[8];char ch;int syn,p,m,n,sum; //p是缓冲区prog的指针,m是token的指针char *rwtab[6]={"begin","if","then","while","do","end"};void scanner() //词法扫描程序{CLEAR;m=0;while(ch==' '){++p;ch=prog[p]; //读下一个字符;}if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){m=0;while((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9')){token[m++]=ch;++p;ch=prog[p];//读下一个字符;}token[m++]='\0';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转换为数字++p;ch=prog[p];}syn=11;}elseswitch(ch)//其他字符情况{case'<':m=0;token[m++]=ch;++p;ch=prog[p];if(ch=='>'){syn=21;++m;token[m]=ch;}else if(ch=='='){syn=22;++m;token[m]=ch;}{syn=20;}break;case'>':token[0]=ch;++p;ch=prog[p];if(ch=='='){syn=24;token[0]=ch;}else{syn=23;}break;case':':token[0]=ch;++p;ch=prog[p];if(ch=='='){syn=18;++m;token[m]=ch;++p;ch=prog[p];}else{syn=17;}break;case'+':syn=13;token[0]=ch;ch=prog[++p];break;case'-':syn=14;token[0]=ch;ch=prog[++p];break;case'*':syn=15;token[0]=ch;ch=prog[++p];case'/':syn=16;token[0]=ch;ch=prog[++p];break;case'=':syn=25;token[0]=ch;ch=prog[++p];break;case';':syn=26;token[0]=ch;ch=prog[++p];break;case'(':syn=27;token[0]=ch;ch=prog[++p];break;case')':syn=28;token[0]=ch;ch=prog[++p];break;case'#':syn=0; token[0]=ch;ch=prog[++p];break;default:syn=-1;}}(2)word.cpp // 词法分析主程序#include"scan.h"void main(void){p=0;printf("\n please input string:\n");do{ch=getchar();prog[p++]=ch;}while(ch!='#');p=0;ch=prog[0];if(ch>='0'&&ch<='9')printf("error!\n");else{do{scanner();//调用扫描子程序switch(syn){case 11:printf("(%d,%d)\n",11,sum);break;case -1:printf("error!\n");break;default:printf("(%d,'%s')\n",syn,token);}} while(syn!=0);}}【思考题】在编程过程中遇到了哪些问题,你是如何解决的。

编译原理课程设计教案

编译原理课程设计教案

编译原理课程设计教案第一章:编译原理概述1.1 编译器的作用与重要性解释编译器将高级语言程序转换为机器语言程序的过程强调编译器在软件开发中的关键角色1.2 编译原理的基本概念介绍编译程序的基本组成部分,如词法分析器、语法分析器、语义分析器、中间代码器、目标代码器和代码优化器等解释源程序、目标程序和中间代码的概念1.3 编译过程的阶段详细介绍编译过程的各个阶段,包括词法分析、语法分析、语义分析、中间代码、代码优化和目标代码强调每个阶段的目标和重要性第二章:词法分析2.1 词法分析的基本概念解释词法分析器的任务和作用介绍词法单位的概念,如标识符、关键字、常量和符号等2.2 词法分析的技术和方法介绍词法分析常用的技术和方法,如有限自动机、正则表达式和词法规则等解释词法分析过程中的扫描线和词法单元的产生过程2.3 词法分析器的实现介绍如何实现一个简单的词法分析器,包括词法规则的定义和词法分析器的构造提供相关的编程练习,让学生通过编写代码实现基本的词法分析功能第三章:语法分析3.1 语法分析的基本概念解释语法分析器的任务和作用介绍语法规则和语法树的概念3.2 语法分析的技术和方法介绍语法分析常用的技术和方法,如递归下降分析法、LL分析法、LR分析法等解释语法分析过程中的分析表和状态机的概念3.3 语法分析器的实现介绍如何实现一个简单的语法分析器,包括语法规则的定义和语法分析器的构造提供相关的编程练习,让学生通过编写代码实现基本的语法分析功能第四章:语义分析4.1 语义分析的基本概念解释语义分析器的任务和作用介绍语义规则和语义错误的概念4.2 语义分析的技术和方法介绍语义分析常用的技术和方法,如类型检查、上下文无关文法分析、语义规则等解释语义分析过程中的语义规则和语义冲突的解决方法4.3 语义分析器的实现介绍如何实现一个简单的语义分析器,包括语义规则的定义和语义分析器的构造提供相关的编程练习,让学生通过编写代码实现基本的语义分析功能第五章:中间代码5.1 中间代码的基本概念解释中间代码器的任务和作用介绍中间代码的概念和中间代码的原则5.2 中间代码的技术和方法介绍中间代码的常用技术和方法,如三地址代码、静态单赋值代码等解释中间代码过程中的基本规则和操作符的转换5.3 中间代码器的实现介绍如何实现一个简单的中间代码器,包括中间代码的定义和中间代码器的构造提供相关的编程练习,让学生通过编写代码实现基本的中间代码功能第六章:代码优化6.1 代码优化的基本概念解释代码优化器的任务和作用介绍代码优化的目标和常见的优化技术6.2 常见代码优化技术详细介绍各种代码优化技术,如常量折叠、死代码消除、循环优化、表达式简化等强调优化技术对提高程序性能的重要性6.3 代码优化器的实现介绍如何实现一个简单的代码优化器,包括优化规则的定义和代码优化器的构造提供相关的编程练习,让学生通过编写代码实现基本的代码优化功能第七章:目标代码7.1 目标代码的基本概念解释目标代码器的任务和作用介绍目标代码的概念和目标代码的原则7.2 目标代码的技术和方法介绍目标代码的常用技术和方法,如寄存器分配、指令调度等解释目标代码过程中的基本规则和操作符的转换7.3 目标代码器的实现介绍如何实现一个简单的目标代码器,包括目标代码的定义和目标代码器的构造提供相关的编程练习,让学生通过编写代码实现基本的目标代码功能第八章:调试技术8.1 调试技术的基本概念解释调试器的作用和重要性介绍调试过程中的常见问题和调试技术8.2 调试器的结构和原理详细介绍调试器的结构和原理,如断点、单步执行、查看变量等功能强调调试技术对发现和修复程序错误的重要性8.3 调试器的实现介绍如何实现一个简单的调试器,包括断点的设置、单步执行、变量查看等功能提供相关的编程练习,让学生通过编写代码实现基本的调试功能第九章:编译器性能评价9.1 编译器性能评价的基本概念解释编译器性能评价的目的和方法介绍编译器性能评价的指标和评价方法9.2 编译器性能评价的指标和评价方法详细介绍编译器性能评价的指标,如执行速度、内存占用、编译时间等介绍常用的编译器性能评价方法和工具9.3 编译器性能评价的实践介绍如何进行编译器性能评价的实践,包括评价指标的选取和评价方法的实施提供相关的实践练习,让学生通过实际操作评价编译器的性能第十章:编译原理应用与发展趋势10.1 编译原理在软件开发中的应用介绍编译原理在软件开发中的应用领域,如解释器设计、即时编译、程序分析等强调编译原理在提高程序性能和开发效率方面的重要性10.2 编译原理的研究现状与未来发展介绍编译原理研究领域的前沿技术和最新研究成果探讨编译原理未来的发展趋势和挑战10.3 编译原理在实践中的应用案例分析分析编译原理在实际项目中的应用案例,如开源编译器项目、商业编译器产品等引导学生思考如何将编译原理应用于实际工程实践中的问题重点和难点解析重点环节一:编译器的作用与重要性编译器作为程序设计语言和计算机硬件之间的桥梁,其作用不可忽视。

编译原理实习设计——词法分析程序

编译原理实习设计——词法分析程序

图三:实数的识别
} 27 { * 26 * 25 ] * 24 [ * 23 ( * 22 ) * 21 ; *
20 , * * | 19 18 非| 17 | * * 16 & 15 非& 14 & * = 13 * 12 非= 11 = * 10 # * 9 = * 8 非= 7 %
* 6 ^ * 5 = * 4 非= 3 ! * 2
if(c=='>' || c=='"') { Output("$ID", string); for(int p=0; p<k; p++) { string[p]=NULL; } break; } else if( c=='.' || IsLetter(c) IsDigit(c) ) { string[k++]=c; } } break; } j++; } c=Get_ch(++j); } if(IsLetter(c) || c=='_') { k=0; string[k++]=c; j++; while(1) { c=Get_ch(j); if(IsLetter(c) || c=='_' || IsDigit(c)) { string[k++]=c; } else { if(IsKeyword(string) ) { Output("$keyword", string); }
!= ^ % %= = == && & | || , ; ( ) [ ] { } + ++ += - ―― -= * *= / /=

编译原理实验教程课程设计

编译原理实验教程课程设计

编译原理实验教程课程设计背景编译原理是计算机科学专业的一门重要课程,它研究如何将高级语言翻译成低级语言,以便计算机执行。

编译器是实现这一过程的关键工具。

然而,对于很多学生来说,编译原理的理论知识学习起来比较抽象,难以掌握。

因此,本文旨在为编译原理的学习提供一些实验教程的设计思路。

实验一:词法分析器词法分析器是编译器的第一个模块,它的作用是将输入的字符流转化为一个个单词符号。

本实验的目的是设计并实现一个简单的词法分析器,实现以下功能:1.识别输入的程序中所包含的各个单词符号。

2.输出所有单词符号及其对应的单词类型。

3.当遇到不合法单词符号时,给出相应的错误提示。

具体实现可以采用有限自动机的思想,使用正则表达式或者手写代码,实现对于不同的单词类型的识别,并对于不合法单词进行识别和报错处理。

实验二:语法分析器语法分析器是编译器的第二个模块,它的作用是将词法分析器输出的单词序列转换成语法树或者语法分析表,以便后续进行语义分析和目标代码生成。

本实验的目的是设计并实现一个简单的语法分析器,实现以下功能:1.识别输入的程序是否符合所设计的文法规则。

2.输出语法树或语法分析表。

具体实现可以采用自上而下的递归下降分析法或自下而上的移进-规约分析法,实现对于不同的句型的识别,并生成语法树或语法分析表。

实验三:语义分析器语义分析器是编译器的第三个模块,它的作用是对语法分析器输出的语法树或语法分析表进行语义分析,并生成中间代码。

本实验的目的是设计并实现一个简单的语义分析器,实现以下功能:1.对语法树或语法分析表进行遍历,识别语法错误和语义错误,给出相应的错误提示。

2.生成中间代码。

具体实现可以采用语义规则和符号表的检查方式,识别语法错误和语义错误,并在生成中间代码时,根据中间代码语言的规则进行实现。

实验四:目标代码生成器目标代码生成器是编译器的第四个模块,它的作用是将中间代码转换成机器语言,以便计算机执行。

本实验的目的是设计并实现一个简单的目标代码生成器,实现以下功能:1.将中间代码转换成机器语言。

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

实验1-3《编译原理》词法分析程序设计方案实验1-3 《编译原理》S语言词法分析程序设计方案一、实验目的了解词法分析程序的两种设计方法之一:根据状态转换图直接编程的方式;二、实验内容1.根据状态转换图直接编程编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。

在此,词法分析程序作为单独的一遍,如下图所示。

具体任务有:(1)组织源程序的输入(2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件(3)删除注释、空格和无用符号(4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。

将错误信息输出到屏幕上。

(5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。

标识符表结构:变量名,类型(整型、实型、字符型),分配的数据区地址注:词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。

常量表结构:常量名,常量值三、实验要求1.能对任何S语言源程序进行分析在运行词法分析程序时,应该用问答形式输入要被分析的S源语言程序的文件名,然后对该程序完成词法分析任务。

2.能检查并处理某些词法分析错误词法分析程序能给出的错误信息包括:总的出错个数,每个错误所在的行号,错误的编号及错误信息。

本实验要求处理以下两种错误(编号分别为1,2):1:非法字符:单词表中不存在的字符处理为非法字符,处理方式是删除该字符,给出错误信息,“某某字符非法”。

2:源程序文件结束而注释未结束。

注释格式为:/* …… */四、保留字和特殊符号表单词的构词规则:字母=[A-Za-z]数字=[0-9]标识符=(字母|_)(字母|数字)*数字=数字(数字)*(.数字+| )四、S语言表达式和语句说明1.算术表达式:+、-、*、/、%2.关系运算符:>、>=、<、<=、==、!=3.赋值运算符:=,+=、-=、*=、/=、%=4.变量说明:类型标识符变量名表;5.类型标识符:int char float6.If语句:if 表达式then 语句 [else 语句]7.For语句:for(表达式1;表达式2;表达式3)语句8.While语句:while 表达式 do 语句9.S语言程序:由函数构成,函数不能嵌套定义。

函数格式为:返回值函数名(参数){数据说明语句}五、程序参考结构说明1.Initscanner函数:程序初始化:输入并打开源程序文件和目标程序文件,初始化保留字表2.Scanner函数:若文件未结束,反复调用lexscan函数识别单词。

3.Lexscan函数:根据读入的单词的第一个字符确定调用不同的单词识别函数4.Isalpha函数:识别保留字和标识符5.Isnumber函数:识别整数,如有精力,可加入识别实数部分工功能6.Isanotation函数:处理除号/和注释7.Isother函数识别其他特殊字符8.Output函数:输出单词的二元式到目标文件,输出格式(单词助记符,单词内码值),如(int,-)(rlop,>)……9.Error函数:输出错误信息到屏幕10.除此之外,还可以设置查符号表,填写符号表等函数,学生可自行设计。

实验中,可以将某些类型的单词识别过程利用DFA算法实现,DFA算法参考如下:DFA(S=S0,MOVE[][],F[],ALPHABET[],ALLS[])/*S为状态,初值为DFA的初态,MOVE[][]为状态转换矩阵,F[] 为终态集,ALPHABET[] 为字母表,其中的字母顺序与MOVE[][] 中列标题的字母顺序一致。

ALLS[]为状态集*/{Char Wordbuffer[10]=“”//单词缓冲区置空Nextchar=getchar();//读字符i=0;while(nextchar!=NULL)//NULL代表此类单词{ if (nextcha r!∈ALPHABET[]) {ERROR(“非法字符”),return(“非法字符”);}S=MOVE[S][nextchar] //下一状态if(S=NULL)return(“不接受”);//下一状态为空,不能识别,单词错误 wordbuffer[i]=nextchar ; //保存单词符号i++;nextchar=getchar();}Wordbuffer[i]=‘\0’;If(S∈F)return(wordbuffer); //接受Else return(“不接受”);}六、实验过程说明1.每人单独完成。

2.完成后,由老师验收,并给出成绩。

3.实验完成后,写出实验报告(要求交打印稿)。

报告内容要求如下:七、测试源程序示例://aa.c void aa( ) {float rate,circle; rate=3;circle=3.14*rate*rate; } 输出结果:(1)输出结果文件:(void,-)(id, 0) ((,-) (),-) ({,- ) ( float,-) (id,1)……(2)标识符的符号表:0 1 2 3 4 5 (3)常数表:0 1 2 3 实验地点:教10五楼计算机学院软一机房实验时间:第4周周二3单元、周四1单元、第五周周二3单元 八、实验代码#include<stdio.h>#include<stdlib.h>#include<ctype.h>#include<string.h>#define MAX 10//保留字符号长度#define MAXSIZE 45//保留字和特殊符号表长度#define NUM 30//标识符和常数的个数FILE *in,*out;// 指向文件的指针char infile[MAX];//文件名字char token[MAX];char Word[NUM][MAX];//标识符char consts[NUM][MAX];//常数char lownum[NUM][MAX]={"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19""20","21","22","23","24","25","26","27","28","29"}; //自定义表int n=1;//行号int num=0; //错误统计数typedef struct Key_word//保留字和特殊符号表结构{//int keyNum;char keyWord[MAX];char keySign[MAX];char keyValue[MAX];}Key_word;//初始化保留字表Key_word Key[MAXSIZE]={{"int","int","-"},{"char","char","-"},{"float","float","-"},{"void","void","-"},{"const","const","-"},{"for","for","-"},{"if","if","-"},{"else","else","-"},{"then","then","-"},{"while","while","-"},{"switch","switch","-"},{"break","break","-"},{"begin","begin","-"},{"end","end","-"},{"","",""},{"","",""},{"","id",""},{"","num",""},{"+","+","-"},{"-","-","-"},{"*","*","-"},{"/","/","-"},{"%","%","-"},{"(","(","-"},{")",")","-"},{"[","[","-"},{"]","]","-"},{"","",""},{"<","rlop","<"},{">","rlop",">"}, {"<=","rlop","<="},{">=","rlop",">="},{"=","rlop","="},{"!=","rlop","!="},{";",";","-"},{"","",""},{"/=","/=","-"},{"+=","+=","-"},{"-=","-=","-"},{"*=","*=","-"},{"%=","%=","-"},{"||","or","-"},{"&&","and","-"},{"!","not","-"},{"=","=","-"}}; //打开关闭文件int Initscanner(){printf("请输入要输入的文件:\n");scanf("%s",infile);if((in=fopen(infile,"r"))==NULL){printf("cannot open infile!\n");return 0;}if((out=fopen("word.txt","a+"))==NULL){printf("cannot open outfile!\n");return 0;}return 0;}//写入文件void Output(int n,int m){fputs("(",out);fputs(Key[n].keySign,out);fputs(",",out);if(m==-1)fputs(Key[n].keyValue,out);elsefputs(lownum[m],out);//下标fputs(")",out);}//Isalpha函数:识别保留字和标识符int Isalpha(){int i;for(i=0;i<16;i++)//关键字{if(strcmp(token,Key[i].keyWord)==0){Output(i,-1);return 0;}}//标识符Word[NUM][MAX]for(i=0;i<NUM;i++){if((Word[i][0]!=NULL)&&strcmp(token,Word[i])==0){Output(16,i);return 0;}if(Word[i][0]==NULL){strcpy(Word[i],token);Output(16,i);return 0;}}return 0;}int Isnumber()//Isnumber函数:consts[NUM][MAX]{int i;for(i=0;i<NUM;i++){if((consts[i][0]!=NULL)&&strcmp(token,consts[i])==0){Output(17,i);return 0;}if(consts[i][0]==NULL){strcpy(consts[i],token);Output(17,i);return 0;}}return 0;}void remove() //扫描指针回退一个字符{fseek(in,-1,SEEK_CUR);}//Isanotation函数:处理除号/和注释void Isanotation() //提示第一个字符已经存为/了{char ch,pre;ch=getc(in);if(ch=='=')// "/="Output(36,-1);else if(ch=='*')// "/*"{ch=getc(in);do{if(feof(in)){num++;printf("\n第(%d)行 : 注释错误: /*后面的字符全部当做注释,缺少结束注释*/\n",n);break;}pre=ch;ch=getc(in);}while(pre!='*'||ch!='/');}else// "/"{remove(); //指针回退一个字符Output(21,-1);}}//Isother函数识别其他特殊字符void Isother(){ int i=1;int j=0;char ch;if(token[0]=='<'||token[0]=='>'||token[0]=='!'||token[0]=='%') {ch=getc(in);if(ch=='=')token[i++]=ch;elseremove();}else if(token[0]=='|'){ch=getc(in);if(ch=='|')token[i++]=ch;elseremove();}else if(token[0]=='&'){ch=getc(in);if(ch=='&')token[i++]=ch;elseremove();}token[i]='\0';for(i=18;i<45;i++){if(strcmp(token,Key[i].keyWord)==0){Output(i,-1);break;}}if(i==45){num++;printf("\n第(%d)行 : 字符错误 : %s字符非法\n",n,token);}}void Scanner(){char ch;int i;ch=getc(in);while(!feof(in)){while(ch==' '||ch=='\t'||ch=='\n') //先统计行数{if(ch=='\n')++n;ch=getc(in);}if(((ch>='a')&&(ch<='z'))||(ch=='_'))//标识符 isalpha(ch)单词{i=1;token[0]=ch;ch=getc(in);while(((ch>='a')&&(ch<='z'))||((ch>='0')&&(ch<='9')))//word number{token[i++]=ch;ch=getc(in);}token[i]='\0';Isalpha();}else if((ch>='0')&&(ch<='9'))//整数{i=1;token[0]=ch;ch=getc(in);while(isdigit(ch)){token[i++]=ch;ch=getc(in);}token[i]='\0';Isnumber();}else if(ch=='/')//区分 "/" , "/=" , "/*"{token[0]=ch;Isanotation();ch=getc(in);}else //特殊字符{token[0]=ch;Isother();ch=getc(in);}}}void show(){int i;char ch;printf("\n二元式:\n");rewind(out);while(!feof(out)){printf("%c",getc(out));}printf("\n标志符表\n");for(i=0;i<NUM;i++){if(Word[i][0]!=NULL)printf("%d,%s\n",i,Word[i]);}printf("\n常数表\n");for(i=0;i<NUM;i++){if(consts[i][0]!=NULL)printf("%d,%s\n",i,consts[i]);}}void main(){Initscanner();Scanner();printf("\n共有%d个错误\n",num);show();fclose(in);fclose(out);}九、实验结果输入文件void aa( ) beginfloat rate,circle; rate=3;circle=3.14*rate;/******/ end输出文件(void,-) (id,0) ((,-) (),-) (begin,-) (float,-) (id,1) (id,2) (;,-) (id,1) (rlop,=) (num,0) (;,-) (id,2) (rlop,=) (num,0) (num,1) (*,-) (id,1) (;,-) (end,-)十、实验总结经过此次实验,了解了程序的词法构词规则和词法分析过程。

相关文档
最新文档