词法分析程序构造原理与实现技术实验报告文档

合集下载

编译技术实验报告词法(3篇)

编译技术实验报告词法(3篇)

第1篇一、实验目的本次实验旨在通过实践加深对编译技术中词法分析阶段的理解,掌握词法分析的基本原理和方法,能够实现一个简单的词法分析器,并对源代码进行初步的符号化处理。

二、实验环境1. 操作系统:Windows 102. 编程语言:Java3. 开发工具:Eclipse IDE4. 实验素材:实验提供的C语言源代码三、实验原理词法分析是编译过程中的第一个阶段,其主要任务是将源代码中的字符序列转换成一系列的词法单元(Token)。

词法单元是构成源程序的基本单位,如标识符、关键字、运算符等。

词法分析的基本原理如下:1. 字符流:从源代码中逐个读取字符,形成字符流。

2. 状态转换:根据字符流中的字符,在有限状态自动机(FSM)中转换状态。

3. 词法单元生成:当状态转换完成后,生成对应的词法单元。

4. 错误处理:在分析过程中,如果遇到无法识别的字符或状态,进行错误处理。

四、实验步骤1. 设计词法分析器:根据C语言的语法规则,设计有限状态自动机,定义状态转换图。

2. 实现状态转换函数:根据状态转换图,实现状态转换函数,用于将字符流转换为词法单元。

3. 实现词法单元生成函数:根据状态转换结果,生成对应的词法单元。

4. 测试词法分析器:使用实验提供的C语言源代码,测试词法分析器的正确性。

五、实验结果与分析1. 词法分析器设计:根据C语言的语法规则,设计了一个包含26个状态的状态转换图。

状态转换图包括以下状态:- 初始状态:用于开始分析。

- 标识符状态:用于分析标识符。

- 关键字状态:用于分析关键字。

- 运算符状态:用于分析运算符。

- 数字状态:用于分析数字。

- 字符串状态:用于分析字符串。

- 错误状态:用于处理非法字符。

2. 状态转换函数实现:根据状态转换图,实现了状态转换函数。

该函数用于将字符流转换为词法单元。

3. 词法单元生成函数实现:根据状态转换结果,实现了词法单元生成函数。

该函数用于生成对应的词法单元。

词法分析程序实验报告

词法分析程序实验报告

词法分析程序实验报告篇一:词法分析器_实验报告词法分析器实验报告实验目的:设计、编制、调试一个词法分析子程序-识别单词,加深对词法分析原理的理解。

实验要求:该程序要实现的是一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分界符五大类。

并依次输出各个单词的内部编码及单词符号自身值。

(一)实验内容(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语句的条件,解决了此问题。

【实验报告】实验一-编写词法分析程序

【实验报告】实验一-编写词法分析程序

编译原理实验报告实验名称:编写词法分析程序_______实验类型:设计型实验指导教师:专业班级:姓名:学号:实验地点:实验成绩:日期:2017年4月15日实验一编写语法分析程序一、实验目的1)通过设计、调试词法分析程序,掌握词法分析程序的设计工具,即有穷自动机,进一步理解自动机理论;2)掌握正则文法和正则表达式转换成有穷自动机的方法及有穷自动机的实现方法;3)会确定词法分析程序的输出形式及标识符与关键字的区分方法;4)加深对课堂教学的理解,提高词法分析方法的实践能力,掌握使用实验环境的技能技巧以及程序的调试方法。

二、实验设计1、写出TEST语言每条词法规则对应的正则文法或者正则表达式1)标识符:字母打头,后接任意字母或数字。

正则表达式:( a|b|……|z|A|B……|Z )( 0|1|……|9| a|b|……|z|A|B……|Z )*2)保留字:标符的子集,包括:if, else, for, while, do, int, write, read。

正则表达式:if | else | for | while | do | int | write | read3)无符号整数:由数字组成,但最高位不能为0,允许一位的0。

正则表达式:( (1……|9 )( 0|1|……|9)* )|04)分界符:(、)、;、{、}正则表达式:( | ) | ; | { | }5)运算符:+、-、*、/、=、<、>、>=、<=、!=、==正则表达式:+ | - | * | / | = | < | > | >= | <= | != | ==6)注释符:/* */正则表达式:/*(没有连续的*/的任意字符串|ℇ)*/2、对每个文法或者正则表达式分别构造NFA1)标识符:( a|b|……|z|A|B……|Z )( 0|1|……|9| a|b|……|z|A|B……|Z )*2)无符号整数:( (1|2|……|9 )( 0|1|……|9)* )|03)分界符:( | ) | ; | { | }4)运算符:+ | - | * | / | = | < | > | >= | <= | != | ==5)注释符:/*(没有连续的*/的任意字符串|ℇ)*/非*非*|非/3、将NFA合并,确定化,化简得到最终的DFA。

词法分析实验报告

词法分析实验报告

词法分析实验报告一、实验目的和背景词法分析是编译原理中的重要部分之一,其主要作用是将源程序中的字符序列转化为有意义的单词序列,以便于后续的处理和分析。

为了更好地理解词法分析的实现原理以及掌握相关算法和工具,本次词法分析实验旨在通过手动编写正则表达式、确定有限自动机的状态转移函数和实现词法分析程序来实现词法分析。

二、实验内容在本次实验中,我们需要完成以下任务: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. 继续进行状态转移,直至读取完整个源程序。

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

(完整word版)编译原理词法分析程序实现实验报告

(完整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=='.')。

词法分析实验报告

词法分析实验报告

词法分析实验报告词法分析是编译原理中的一个重要概念,它是编译器中的第一个阶段,也是最基础的一个阶段。

词法分析器将输入的源代码转化为一系列的标记(Token),这些标记是语法分析器后续分析的基本单元。

在本次实验中,我们使用C语言编写了一个简单的词法分析器。

该词法分析器可以识别常见的C语言关键字(如if、while、for等)、运算符(如+、-、*、/等)、标识符、常量等,并将它们转化为相应的标记。

实验过程中,我们使用了C++编程语言来实现词法分析器。

在主函数中,我们首先读取输入的源代码文件,并将其逐个字符地进行扫描。

扫描过程中,我们利用一些常见的正则表达式来匹配每个标记,并将其转化为相应的Token。

在匹配完成后,我们将Token存储在一个Token序列中,以便后续的语法分析器使用。

实验过程中,我们遇到了一些困难。

一是字符匹配的问题,在处理运算符等特殊字符时,需要对转义字符进行特殊处理。

二是标识符的识别问题,我们需要判断一个字符是否属于标识符中的某一部分,而不能将其单独当作一个标记。

为了解决这个问题,我们采用了状态机的方法,维护一个标识符的状态,根据状态的变化来判断是否识别到了一个完整的标识符。

在实验结果中,我们成功地将源代码转化为了一系列的标记。

这些标记可以用于后序的语法分析和语义分析等过程中。

同时,我们也发现了一些问题,如在处理注释时可能会出现误判等。

针对这些问题,我们可以进一步改进词法分析器,提高其准确性和鲁棒性。

总的来说,通过本次实验,我们深入理解了词法分析的原理和过程,并成功地实现了一个简单的词法分析器。

通过这个实验,我们对编译原理有了更深入的了解,并提高了自己的编程能力。

C语言词法分析器构造实验报告

C语言词法分析器构造实验报告

编译原理C语言词法分析器构造学院:信工班级: 1 4 0学号: **********名:******师:**2014年 6 月12日一、实验题目:编译原理词法分析二、实验内容:2.1主程序设计考虑:主程序的说明部分为各种表格和变量安排空间(关键字和特殊符号表)。

id 和ci 数组分别存放标识符和常数;还有一些为造表填表设置的变量。

主程序的工作部分建议设计成便于调试的循环结构。

每个循环处理一个单词;调用词法分析过程;输出每个单词的内部码(种别编码,属性值)。

建议从文件中读取要分析的符号串。

2.2词法分析过程考虑该过程根据输入单词的第一个有效字符(有时还需读第二个字符),判断单词种别,产生种别编码。

对于标识符和常数,需分别与标识符表和常数表中已登记的元素相比较,如表中已有该元素,则记录其在表中的位置,如未出现过,将标识符按顺序填入数组id 中,将常数存入数组中ci 中,并记录其在表中的位置。

注:所有识别出的单词都用二元组表示。

第一个表示单词的种别编码。

例如:关键字的t=1;标识符的t=2;常数t=3;运算符t=4;界符t=5。

第二个为该单词在各自表中的指针或内部码值(常数表和标识符表是在编译过程中建立起来的。

其i 值是根据它们在源程序中出现的顺序确定的)。

将词法分析程序设计成独立一遍扫描源程序的结构。

其主流程图如下:图1 词法分析程序流程图三、程序源代码:#include "stdafx.h"#include<iostream>#include<string>#include<math.h>#include<fstream>using namespace std;//关键字结构体struct key{string key_word;int bm;string zjf;};//界符结构体struct JF{char jf_ch;int bm;string zjf; };//运算符结构体struct ysf{string ysf_w;int bm;string zjf;};//得到关键字字母表void fuc_K_table(key K_w[]){int i=0;ifstream infile("E:\\cffx\\key.txt",ios::in);if(!infile){cerr<<"open error!"<<endl;}for(i=0;i<12;i++){infile>>K_w[i].key_word ;infile>>K_w[i].bm ;infile>>K_w[i].zjf ; }infile.close ();}//得到界符字母表void fuc_JF_table(JF J_CHAR[]){int i=0;ifstream infile("E:\\cffx\\jf.txt",ios::in);if(!infile){cerr<<"open error!"<<endl; }for(i=0;i<9;i++){infile>>J_CHAR[i].jf_ch;infile>>J_CHAR[i].bm;infile>>J_CHAR[i].zjf; }infile.close ();}//得到运算符表void fuc_ysf_table(ysf YSF_W[]){int i=0;ifstream infile("E:\\cffx\\ysf.txt",ios::in);if(!infile){cerr<<"open error!"<<endl; }for(i=0;i<18;i++){infile>>YSF_W[i].ysf_w;infile>>YSF_W[i].bm; infile>>YSF_W[i].zjf; } infile.close ();}//查找是否为保留字int Reserve(string strToken,key K_w[]){int i=0;for(i=0;i<12;i++)if(strToken==K_w[i].key_word ) return K_w[i].bm;if(i>=12) return -1; }//查找是否为界符int Reservejf(char ch,JF J_CHAR[]){int i=0;for(i=0;i<9;i++)if(ch==J_CHAR[i].jf_ch ) return J_CHAR[i].bm;if(i>=9) return -1;}//查找是否为运算符int Reserveysf(string strToken,ysf YSF_W[]){int i=0;for(i=0;i<18;i++)if(strToken==YSF_W[i].ysf_w ) return YSF_W[i].bm;if(i>=18) return -1;}//将strToken中的常数插入常数表int InsertConst(string strToken,key K_w[]){int i=0,j=0,m=0;while(strToken[i]!='\0') i++;for(j=0;j<i;j++) m=10*m+((int)strToken[j]-48);return m;}//判断是否为字母bool IsLetter(char ch){if((ch>=97&&ch<=122)||( ch>=65&&ch<=90))return true; else return false;} //判断是否为数字bool IsDigit(char ch){if((ch>=48&&ch<=57))return true; else return false;}//判断是否为界符bool IsJF(char ch){switch(ch){case'{': case'}': case'[': case']':case'(': case')':case';': case',':case'"':return true;default:return false;}}//判断是否为运算符bool IsYSF(char ch){bool re=false;switch(ch){case'>': case'<': case'=': case'+': case'-': case'*':case'/': case'%': case'&': case'|': case'!':case'"':{re=true;break;} }return re; }//主函数int main(int argc, char* argv[]){key K_w[12]; JF J_CHAR[9];ysf YSF_W[18];fuc_K_table(K_w); fuc_JF_table(J_CHAR);fuc_ysf_table(YSF_W); int i=0;cout<<"关键字种别编码表:"<<endl;for(i=0;i<12;i++)cout<<K_w[i].key_word<<" "<<K_w[i].bm<<endl;cout<<"界符种别编码表:"<<endl;for(i=0;i<9;i++)cout<<J_CHAR[i].jf_ch<<" "<<J_CHAR[i].bm<<endl;cout<<"运算符种别编码表:"<<endl;for(i=0;i<18;i++)cout<<YSF_W[i].ysf_w<<" "<<YSF_W[i].bm<<endl;cout<<"常数的种别编码为:50"<<endl;cout<<"普通标识符的种别编码为:51"<<endl;FILE*fp;fp=fopen("E:\\cffx\\f1.txt","r");cout<<"词法分析器输出结果为:"<<endl;char ch; int digit=0;string strToken;if(fp==NULL){cout<<"error";exit(0);} else{while(ch!='#'){strToken="\0";ch=fgetc(fp);if(ch==' '||ch=='\t'||ch=='\n'){}elseif(IsLetter(ch)){while(IsLetter(ch)||IsDigit(ch)){strToken=strToken+ch;ch=fgetc(fp); }fseek(fp,-1L,SEEK_CUR);i=Reserve(strToken,K_w);if(i>-1)cout<<'('<<strToken<<','<<i<<')'<<endl;elsecout<<'('<<strToken<<",51)"<<endl; }elseif(IsDigit(ch)){while(IsDigit(ch)){strToken=strToken+ch;ch=fgetc(fp); }fseek(fp,-1L,SEEK_CUR);digit=InsertConst(strToken,K_w);cout<<'('<<digit<<",50"<<')'<<endl; }elseif(IsJF(ch)){int jfcount=Reservejf(ch,J_CHAR);cout<<'('<<ch<<','<<jfcount<<')'<<endl; }elseif(IsYSF(ch)){while(IsYSF(ch)){strToken=strToken+ch;ch=fgetc(fp); }fseek(fp,-1L,SEEK_CUR);i=Reserveysf(strToken,YSF_W);if(i>-1)cout<<'('<<strToken<<','<<i<<')'<<endl;elsecout<<"输入符号错误!"<<endl; }}fclose(fp);}return 0;}四、实验截图:F1中是数据为:实验结果为:五、实验总结:这个程序主要参考书上关于词法分析器的设计。

词法分析程序构造原理与实现技术实验报告文档

词法分析程序构造原理与实现技术实验报告文档

词法分析程序构造原理与实现技术实验报告变更说明、实验目的:本实验的目的在于在教师的引导下以问题回朔与思维启发的方式,使学生在不断的探究过程中掌握编译程序设计和构造的基本原理和实现技术,启迪学生的抽象思维、激发学生的学习兴趣、培养学生的探究精神和专业素养,从而提高学生发现问题、分析问题和解决问题的能力。

、实验内容:[实验项目]完成以下正则文法所描述的Pascal 语言子集单词符号的词法分析程序。

<标识符字母丨<标识符〉字母丨<标识符〉数字<无符号整数>—数字丨<无符号整数〉数字<单字符分界符>T + I- I * I; I ( I)<双字符分界符>f <大于>=I <小于>=I <小于>>I <冒号>=I <斜竖>* <小于>f <<等于>f = <大于>T><冒号>T: <斜竖>T/该语言的保留字:begin end if then else for do while and or not[设计说明](1)该语言大小写不敏感;(2)字母为a-z A-Z,数字为0-9 ; (3) 可以对上述文法进行扩充和改造;(4) ‘/*……*/ '为程序的注释部分。

[设计要求](1)给出各单词符号的类别编码;( 2)词法分析程序应能发现输入串中的错误;( 3)词法分析作为单独一遍编写,词法分析结果为二元式序列组成的中间文件;( 4)设计两个测试用例(尽可能完备),并给出测试结果。

三、实验环境:操作系统:Windows 7软件:VC++6.0四、程序功能描述:给出了各单词符号的类别编码;词法分析程序能够对给出的文件中的输入串做出正确的词法;词法分析程序能发现文件输入串中的错误;词法分析结果为二元式序列组成的中间文件;词法分析程序能兼容注释并能发现文件注释未关闭的错误五、数据结构设计:char T0KEH[20];FILF *fp_out=fopen("result-txf"w"); char ch;int i=0,c;int zhu5hi=0;ch^fgetcCFp);六、程序结构描述:设计方法:本程序采用从文件读取字符串,根据已有文法、词法的构成及规定对字符串进行词法分析,其种类主要包括保留字、标识符、无符号数字、字符等, 将分析的结果写入另一个文件。

完整版-编译实验报告词法分析

完整版-编译实验报告词法分析
}
label[i-1]=(char *)malloc(sizeof(searchchar));
strcpy(label[i-1],searchchar);
labelnum++;
return(i);
}
default:
return 0;
}
}/////////////////////////////////////////////////////////////////////////////////////////////////////
程序运行结果:
【调试情况】
程序中,用到了较多的数组和动态数组分配,和较多的循环判断,在动态内存分配时出现了较多的错误,而在关键字和单词的判定中,也出现了不可预知的错误和警告,通过设置断点和插入特殊变量标记法,发现问题并予以解决。
【设计技巧】
由于此实验是测试验证的实验,在生成此词法程序中,用到了较多的跳转语句,实现程序结构的跳转执行,并利用动态数组来存放一些变量
return(i+1);
}
return(0);
}
case 3:{
for (i=0;i<=3;i++)
{
if (strcmp(arithmetic[i],searchchar)==0){
return(i+1);
}
}
return(0);
}
case 4:{
for (i=0;i<=5;i++)
{
if(strcmp(relation[i],searchchar)==0)
int constnum=0,labelnum=0;/////////////////////////////////////////////////////////////////////////////////////////////////////

词法分析程序实验报告

词法分析程序实验报告

词法分析程序实验报告词法分析程序实验报告一、实验目的1. 理解词法分析器的基本功能2. 理解词法规则的描述方法3. 理解状态转换图及其实现4. 能够编写简单的词法分析器二、实验要求给出单词序列对应的状态识别。

单词符号State 对应的值单词符号State 对应的值function 1 = 18if 2 < 20else 3 <= 21for 4 != 22then 5 > 23while 6 >= 24do 7 == 25 endfunction 8 ; 26letter(letter|digit)* 10 ( 27digit digit* 11 ) 28+ 13 { 29- 14 } 30* 15 # 0/ 162、主程序流程图N程序开始初始化输入源程序调用scanner()函数,识别单词序列输出单词序列Y结束输入串结束?三、识别单词的状态转换图Scanner()函数流程图变量初始化忽略空格和换行num 读取常数state=11Token[]读入关键字、标识符关键字?判断关键字 statestate=10判断运算符和分界符 state 其余符号 state=-1 ReturnNY{)(;其他其他===其他!其他</* - + 非数字数字数字开始空格或换行字母0 1返回’10’或关键字234 返回’11’567 8返回’13’ 返回’14’ 返回’15’ 返回’16’ 910111213 14 1516171819 20 >=222425返回’20’返回’21’返回’-1’返回’22’ 返回’23’ 返回’24’返回’18’返回’25’ 返回’26’ 返回’27’ 返回’28’ 返回’29’} #2. 分析直接转向法和表驱动法的优缺点状态转换图的实现通常有两种方法:状态转换表和直接转向法(1) :状态转换表法又称数据中心,是把状态转换图看作一种数据结构,由控制程序控制字符在其上运行,从而完成词法分析。

实现词法分析实验报告

实现词法分析实验报告

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

编译原理词法分析实验报告一、实验内容二、实验目的三、实验预期四、程序规定五、实验原理六、测试用例七、输出结果八、实验心得一、实验内容:词法分析:1、识别简单语言的单词符号;2、识别关键字、标识符、数字、运算符等。

并扩展浮点识别功能。

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

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

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

输出:单词的二元组(syn,token/sum)程序流程图状态转换图六、程序代码: #include<stdio.h> #include<string.h> char prog[80],token[8]; char ch;int syn,p,m,n,sum;char * rwtab[6]={"function","if","then","while","do","endfunc"}; void scaner(); void 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("\nerror");break;default:printf("\n(%d,%s)",syn,token);}}while(syn!=0);}///// main 函数结束void scaner(){for(n=0;n<8;n++)token[n]=NULL;////清空 token数组ch=prog[++p];while(ch=='\n' || ch==' ')ch=prog[++p];if(ch>='a'&&ch<='z'){m=0;while(ch>='a'&&ch<='z'){token[m++]=ch;ch=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'){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=21;token[m+1]=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;}elsesyn=-1;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;}}七、测试用例:九、实验心得通过编译原理实验一词法分析实验,使得自己对词法分析的流程有了更深刻的了解,虽然问题多多,但是还是学到了不少东西。

词法分析器实验报告_5

词法分析器实验报告_5

一、实验目的1.1总体目的1.1.1 掌握词法分析的基本原理;1.1.2.理解词法分析在编译程序过程中的作用;1.1.3.熟悉关键字表等相关的数据结构与单词的分类方法.1.1.4.加深对编译原理的理解,掌握词法分析器的实现方法和技术,同时,将JA V A 的理论知识结合实际,锻炼编程技术,强调良好的程序设计风格。

1.2程序目的利用JAVA语言针对C语言编制一个一遍扫描的编译程序。

从文件中识别出各个单词, 识别出所取的单词的类型, 并且对代码中的词法错误进行提示。

二、实验内容根据编译原理中的词法分析原理, 利用Java语言针对C语言编写一个词法分析程序: 输入: 打开一个C语言程序的源代码文件, 将其读入程序输入框。

处理: 对输入框中的代码进行词法分析,分离出关键字、标识符、数值、运算符和界符。

输出:在词法分析结果表中输出每个单词所在行号、类型以及它所对应的编码。

其中, 编码是自定义的,一种类型对应一组编码。

词法分析结果显示在词法分析错误信息栏, 提示错误个数、错误所在行号, 并对某些词法错误原因进行说明。

三、实验需求针对C语言程序代码进行词法分析器, 从指定文件中读入预分析的源程序, 从左至右扫描源程序的字符串, 按照词法规则(正则文法规则)识别出一个个正确的单词, 并转换成该单词相应的二元式(种别码、属性值)以便之后进行语法分析使用。

同时, 按照给定的规则, 识别出单词符号作为输出, 发现其中的语法错误, 不同类别的字符通过相应的函数模块来分析识别, 使程序能够正确识别文法所规定的任何组织形式的字符组合, 将所有的分析状态显示在词法分析器中。

最后在错误分析栏中显示该文件中C语言代码的词法错误个数、错误所在行, 并对错误原因进行说明。

四、主要数据结构介绍4.1关键字编码4.2标识符统一编码1004.3数值统一编码2004.4界符编码4.5运算符编码4.6全局变量含义int row: 语法错误出现的所在列数int line: 语法错误出现的所在行数int err: 语法错误的个数int begin: 当前程序扫描在字符串中的开始位置int end: 当前程序扫描在字符串中的结束位置4.7局部变量定义int i: 选择第i 个字符进行检测 int state: 单词类型判断标志 int N: 文件长度char c: 当前遍历的字符 string str: 输入字符串 int flag: 退出标志五、主要模块算法介绍5.1总体流程介绍说明: state 为输入字符状态标志, 根据输入字符不同类型选择不同处理。

词法分析设计实验报告(附代码)

词法分析设计实验报告(附代码)

实验一词法分析设计实验学时:4实验类型:综合实验要求:必修一、实验目的通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。

二、实验内容用VC++/VB/JAVA语言实现对C语言子集的源程序进行词法分析。

通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示;同时进行标识符登记符号表的管理。

以下是实现词法分析设计的主要工作:(1)从源程序文件中读入字符。

(2)统计行数和列数用于错误单词的定位。

(3)删除空格类字符,包括回车、制表符空格。

(4)按拼写单词,并用(内码,属性)二元式表示。

(属性值——token的机内表示)(5)如果发现错误则报告出错(6)根据需要是否填写标识符表供以后各阶段使用。

单词的基本分类:◆关键字:由程序语言定义的具有固定意义的标识符。

也称为保留字例如if、 for、while、printf ;单词种别码为1。

◆标识符:用以表示各种名字,如变量名、数组名、函数名;◆常数:任何数值常数。

如 125, 1,0.5,3.1416;◆运算符:+、-、*、/;◆关系运算符: <、<=、= 、>、>=、<>;◆分界符:;、,、(、)、[、];三、实验要求1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。

2、将标识符填写的相应符号表须提供给编译程序的以后各阶段使用。

3、根据测试数据进行测试。

测试实例应包括以下三个部分:◆全部合法的输入。

◆各种组合的非法输入。

◆由记号组成的句子。

4、词法分析程序设计要求输出形式:例:输入VC++语言的实例程序:If i=0 then n++;a﹤= 3b %);输出形式为:单词二元序列类型位置(行,列)(单词种别,单词属性)for (1,for ) 关键字(1,1)i ( 6,i ) 标识符(1,2)= ( 4,= ) 关系运算符(1,3)0 ( 5,0 ) 常数(1,4)then ( 1,then) 关键字(1,5)n (6,n ) 标识符(1,6)++ Error Error (1,7); ( 2, ; ) 分界符(1,8)a (6,a ) 标识符(2,1)﹤= (4,<= ) 关系运算符(2,2)3b Error Error (2,4)% Error Error (2,4)) ( 2, ) ) 分界符(2,5); ( 2, ; ) 分界符(2,6)实验报告正文:◆功能描述:该程序具有词法分析功能,即面对一段程序源代码,通过该程序,能检查出源代码是否由词法错误。

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

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

编译原理实验词法分析实验报告一、实验目的词法分析是编译过程中的第一个阶段,其主要任务是从输入的源程序中识别出具有独立意义的单词符号,并将其转换为内部编码形式。

本次实验的目的是通过设计和实现一个简单的词法分析程序,深入理解词法分析的基本原理和方法,提高对编程语言语法结构的认识和编程能力。

二、实验原理词法分析的基本原理是根据编程语言的词法规则,使用有限自动机或正则表达式等技术来识别单词符号。

在本次实验中,我们采用了状态转换图的方法来设计词法分析器。

状态转换图是一种用于描述有限自动机的图形表示方法,它由状态节点和有向边组成。

每个状态节点表示自动机的一个状态,有向边表示状态之间的转换条件。

当输入字符与当前状态的转换条件匹配时,自动机将从当前状态转换到下一个状态。

当到达一个终态时,表示识别出了一个单词符号。

三、实验环境本次实验使用了 Python 编程语言,并在 PyCharm 集成开发环境中进行开发和调试。

四、实验内容1、定义单词符号的种类和编码关键字:如`if`、`else`、`while` 等标识符:由字母、数字和下划线组成,且以字母或下划线开头常数:包括整数和浮点数运算符:如`+`、``、``、`/`等分隔符:如`(){},;`等2、设计状态转换图根据单词符号的定义,设计了相应的状态转换图,用于识别不同类型的单词符号。

例如,对于标识符的识别,从起始状态开始,当输入字符为字母或下划线时,进入标识符状态,继续输入字母、数字或下划线,直到遇到非标识符字符为止,此时到达终态,识别出一个标识符。

3、实现词法分析程序使用 Python 语言实现了基于状态转换图的词法分析程序。

程序首先读取输入的源程序文本,然后逐个字符进行处理,根据当前状态和输入字符进行状态转换,当到达终态时,输出识别出的单词符号及其编码。

4、进行测试编写了一些测试用例,包括包含各种单词符号的源程序代码。

运行词法分析程序对测试用例进行分析,检查输出结果是否正确。

词法分析程序实验报告

词法分析程序实验报告
state=2; pos--; } } if(state!=2) ch=strline[++pos]; } return true; }
2) 字符常数或字符串常数的识别状态转换图及算法实现
算法实现: 字符串识别
int recog_string(int &pos) {
char ch = strline[pos]; //ch 应该为 ' if(ch != '\"') return -1; int state = 0; while(state != 2) {
C 语言部分单词的种别码
关键字
1
auto
2
double
3
int
4
struct
5
break
6
else
7
long
8
switch
9
case
10
enum
11
register
12
typedef
13
char
14
extern
15
return
16
union
17
const
18
float
19
short
20
unsigned
case 4: if(ch == '+' || ch == '-') state = 5; else state = 6; break;
case 5: if(isdigit(ch)) state = 6; else { result = -1; state = 7; } break;
case 6: if(isdigit(ch)) state = 6; else { pos--; state = 7; result = 2; //返回一个带有 e 或 E 的实

词法分析程序构造原理与实现技术 编译原理实验报告

词法分析程序构造原理与实现技术  编译原理实验报告

编译原理实验词法分析程序构造原理与实现技术目录引言 (3)一、实验目的 (3)二、实验环境 (3)三、实验内容 (3)四、实验要求 (4)五、程序功能描述 (4)5.1 输入输出 (4)5.2大小写不敏感 (5)5.3识别大多数常用程序字符 (5)5.4注释的处理 (5)5.5 错误检查和处理 (5)六、主要数据结构 (6)七、程序结构描述 (6)7.1各单词符号的类别编码 (6)7.2程序总体以及局部执行图 (6)7.3设计方法 (8)7.4函数定义及函数之间的调用关系 (8)八、程序测试 (8)代码附录 (12)引言本课程开展研究性教学的目的是,在教师的引导下以问题回朔与思维启发的方式,使学生在不断的探究过程中掌握编译程序设计和构造的基本原理和实现技术,启迪学生的抽象思维、激发学生的学习兴趣、培养学生的探究精神和专业素养,从而提高学生发现问题、分析问题和解决问题的能力。

一、实验目的1.解决正则文法到状态转换图的转化问题2.掌握正则文法及其状态转换图的基本概念,正则表达式及有限自动机的基本概念3.深入理解理论对实践的指导作用:基本原理、实现技术和方法的正确运用4.掌握正规文法构造相应的状态转换图的基本方法和正则表达式构造有限自动机的基本方法及不确定有限自动机确定化的基本方法5.完成词法分析程序的设计与编写二、实验环境软件:操作系统:WINDOWS 8应用软件:VC6.0三、实验内容1、教学安排内容:完成以下正则文法所描述的Pascal 语言子集单词符号的词法分析程序。

<标识符>→字母︱<标识符>字母︱<标识符>数字<无符号整数>→数字︱<无符号整数>数字<单字符分界符> →+ ︱-︱* ︱; ︱(︱)<双字符分界符>→<大于>=︱<小于>=︱<小于>>︱<冒号>=︱<斜竖>*<小于>→< <等于>→= <大于>→> <冒号> →: <斜竖> →/该语言的保留字:begin end if then else for do while and or not2、在此基础上,我自己新完善了一下词法分析处理:1)新增保留字:return break main2)扩充可识别的标识符文法:<标识符>→<标识符><下划线>字母︱<标识符><下划线>数字3)新增可识别的经常使用的符号:如' ︱" ︱== ︱!= ︱\n(\t)(\r) ︱%s(%d)(%f) 等,以及数组(形如a[] )还有程序经常出现的{},<> 等四、实验要求1.给出各单词符号的类别编码;2.词法分析程序应能发现输入串中的错误;3.词法分析作为单独一遍编写,词法分析结果为二元式序列组成的中间文件;4.设计两个测试用例(尽可能完备),并给出测试结果。

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

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

词法分析实验报告(鲍小伟20032320)一.实验目的:通过设计、编程、调试出一个具体词法分析程序,加深对词法分析原理的理解,掌握其设计方法。

二.实验内容:用C/C++实现对PASCAL的子集程序设计语言的词法识别程序。

三.实验要求与原理:(1)实验要求:将该语言的源程序,即相应字符流转换成内部表示,并对标识符填写相应的符号表供编译程序以后各阶段使用,输出的单词符号格式为二元组(单词种别,单词在标识符表中的地址),标识符表格式有“序号”和“标识符本身的值”两项。

写出设计报告,内容为:状态转换图、单词符号及内部表示、符号表、出错处理、编程方法等。

(2)实验原理:状态转换图:空白8923单词符号及内部表示:标志符表和常数表:void getchar();//将下一输入字符读到ch中,指针后移一字符位置void getbc();//保证ch是一个非空白字符void concat();//将ch连接到字符串stroken的末尾void retract();//置ch为空白字符,指针前移一字符位置int isdigit();//判断是否整数int isletter();//首字母的判断int reserve();//对stroken进行关键字表的查找,返回其编码值int insertid();//将stroken中的标识符插入符号表,返回在符号表中的位置int insertconst();//将stroken中的常数插入常数表,返回在常数表中的位置四.主要源代码:Scanner::Scanner(char str[], int n) //构造函数{strcpy(buffer, str);length = n;i = j = 0;}int Scanner::isdigit()//判断是否整数{if(ch>='0' && ch<='9')return 1;elsereturn 0;}int Scanner::isletter()//首字母的判断{if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z'))return 1;elsereturn 0;}void Scanner::getchar() //将下一输入字符读到ch中,指针后移一字符位置{ch = buffer[i];i++;}void Scanner::getbc() //保证ch是一个非空白字符{while(ch == ' ')getchar();}void Scanner::concat() //将ch连接到字符串stroken的末尾{strtoken[j] = ch;j++;}void Scanner::retract() //置ch为空白字符,指针前移一字符位置{ch = ' ';i--;}int Scanner::reserve() //对stroken进行关键字表的查找,返回其编码值{int i, flag = 0;for(i=0; i<15; i++){if( strncmp(reservechar[i],strupr(strtoken), j) == 0 ){flag = 1;break;}}if(flag == 1) return i+1;else return 0;}int Scanner::insertid() //将stroken中的标识符插入符号表,返回在符号表中的位置{for(int a = 0; a < m; a++)for(int b = 0; b < x[a]; b++)if( strncmp(&id[a][0], strtoken, j) == 0 ){return m+1;break;}for(a = 0; a < j; a++)id[m][a] = strtoken[a];x[m] = j;m++;return m;}int Scanner::insertconst() //将stroken中的常数插入常数表,返回在常数表中的位置{for(int i = 0; i < j; i++)cst[n][i] = strtoken[i];y[n] = j;n++;return n;}void Scanner::scan(){while(i < length){j = 0;int code, value;strcpy(strtoken, " "); //置strtoken为空串getchar();getbc();if(isletter()) //如果打头的是字母{while(isletter() || isdigit()){concat();getchar();}retract();code = reserve();if(code == 0) //如果扫描到的是标识符{value = insertid();cout<<"<34,"<<value<<">"<<'\n';}else cout<<"<"<<code<<",*>"<<'\n'; //如果扫描到的是关键字}else if(isdigit()) //如果打头的是数字{while(isdigit()){concat();getchar();}retract();value = insertconst();cout<<"<33,"<<value<<">"<<'\n';}else if(ch == '+')cout<<"<16,*>"<<'\n';else if(ch == '-')cout<<"<17,*>"<<'\n';else if(ch == '*')cout<<"<18,*>"<<'\n';else if(ch == '/')cout<<"<19,*>"<<'\n';else if(ch == '=')cout<<"<20,*>"<<'\n';else if(ch == '<'){getchar();if(ch == '>')cout<<"<21,*>"<<'\n';else if(ch == '=')cout<<"<23,*>"<<'\n';else{retract();cout<<"<22,*>"<<'\n';}}else if(ch == '>'){getchar();if(ch == '=')cout<<"<25,*>"<<'\n';else{retract();cout<<"<24,*>"<<'\n';}}else if(ch == '.')cout<<"<26,*>"<<'\n';else if(ch == ',')cout<<"<27,*>"<<'\n';else if(ch == ';')cout<<"<28,*>"<<'\n';else if(ch == ':'){getchar();if(ch == '=')cout<<"<30,*>"<<'\n';else{retract();cout<<"<29,*>"<<'\n';}}else if(ch == '(')cout<<"<31,*>"<<'\n';else if(ch == ')')cout<<"<32,*>"<<'\n';else if(ch == '{'){while(ch != '}')getchar();}else cout<<"出错!"<<'\n';}}void main(void){fstream file;file.open("F:/20032320/20032320.txt", ios::in||ios::nocreate); //以只读方式打开file.unsetf(ios::skipws); //不跳过文本中的空格char buffer[100]; //缓冲区定义cout<<"扫描结果如下所示"<<'\n';while(file.getline(buffer, 100)){Scanner SS(buffer, strlen(buffer));SS.scan();}cout<<"标识符表如下:\n"<<"编号\t"<<"值\n";for(int i=0; i<m; i++){cout<<i+1<<'\t';for(int j=0; j<x[i]; j++)cout<<id[i][j];cout<<'\n';}cout<<"常数表如下:\n"<<"编号\t"<<"值\n";for(i=0; i<n; i++){cout<<i+1<<'\t';for(int j=0; j<y[i]; j++)cout<<cst[i][j];cout<<'\n';}}五.运行结果:程序的运行结果如下图所示:。

词法分析~实验报告

词法分析~实验报告

词法分析~实验报告实验⼀、词法分析实验专业商业软件3班姓名陈笑璞学号 201506110218⼀、实验⽬的(1)编制⼀个词法分析程序(2)词法分析是编译的第⼀个阶段,主要任务是从左⾄右逐个字符地对源程序进⾏扫描,产⽣⼀个个单词序列,⽤于语法分析。

(3)通过词法分析的练习,能够进⼀步了解编译原理。

(4)通过了解词法分析程序的设计原则、单词的描述技术、识别机制及词法分析程序的⾃动构造原理。

⼆、实验内容和要求(1)输⼊:源程序字符串(2)输出:⼆元组(种别,单词符号本⾝)。

三、实验⽅法、步骤及结果测试实验⽅法、步骤:(1)对字符串表⽰的源程序(2)从左到右进⾏扫描和分解(3)根据词法规则(4)识别出⼀个⼀个具有独⽴意义的单词符号(5)以供语法分析之⽤(6)发现词法错误,则返回出错信息2、原理分析: 我的设计思路是利⽤链队列(好处:先进先出且不浪费存储空间)进⾏存储⽤户输⼊字符串,以回车键结束(其中必须以⾮数字结尾,否则程序出错)(这是我在后来的编程⾥遇到的问题,我知道问题出在哪⾥,但我现在还解决不了,因为我是通过申请⼦针域来存储,所以我是利⽤p->next来作为判断结束条件,如果以数字结束,那p->next指向未知领域,程序出错,同时这也是很危险的),然后我是利⽤出队列来判断,如果是字母存进数组⾥,直到下⼀个字符不是字母,调⽤函数判断数组的字符串,利⽤strcmp来判断,输出数组,再清空数组;void Print(char str[])//调⽤函数来判断关键字与标识符并输出{int i=0;if(strcmp(str,"begin")==0)printf("(1,'%s')\n",str);else if(strcmp(str,"if")==0)printf("(2,'%s')\n",str);else if(strcmp(str,"then")==0)printf("(3,'%s')\n",str);else if(strcmp(str,"while")==0)printf("(4,'%s')\n",str);else if(strcmp(str,"do")==0)printf("(5,'%s')\n",str);else if(strcmp(str,"end")==0)printf("(6,'%s')\n",str);else{if(str[0]=='\0')return;printf("(10,'%s')\n",str);}memset(str,0,N);//清空数组str⾥的所有元素}结果测试:四、实验总结说实话,通过这次的编译原理词法分析的实验,我遇到了不少问题,也学到了不少的东西,因为这次实验我是想⽤我⾃⼰的想法来编写程序,我是⽤链队列来存储字符串的,也许⽤数组来存储字符串会简单点,但我不想,我还是想利⽤链队列来存储字符串,这样可以节约存储空间,还可以利⽤队列先进先出的特点,不好就是利⽤队列不够灵活,每次都要出栈判断、存储,释放p的⼦针域;虽然在编写过程中,遇到不少问题,遇到⼀个,就想办法解决⼀个,通过问朋友⽼师等,也通过发朋友圈问,还通过发博客来问⼤神们,这种途径是最有效的,也是最好的;所以每次就差⼀点就做好了,⼜会遇到⼀个新的问题,就要想办法去解决它,如今除了字符串是以数字结尾会出现问题外(暂时没找到好的⽅法),其他问题已解决。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
程序的自我评价:
此程序实现了要求中的所有功能,并增加了对注释的一些操作,但因编程能力的欠缺,其中有的地方不免有些繁杂,还有一些潜藏的问题,需要进一步测试来时程序变得更加具有健壮性。
九、
/****************************************************
课题名称:词法分析程序构造原理与实现技术
}
break;
case':':
if(!feof(fp))
ch=fgetc(fp);
if(ch=='=')
{
fprintf(fp_out,"(%d,%s)",26,":=");
printf("(%d,%s)\n",26,":=");
}
else
{
if(ch!=EOF)
fseek(fp,-1,1);
}
break;
printf("(%d,%c)\n",14,'+');
}
break;
case'-':
{
fprintf(fp_out,"(%d,%c)",15,'-');
printf("(%d,%c)\n",15,'-');
}
break;
case'*':
{
fprintf(fp_out,"(%d,%c)",16,'*');
if(c==0)
{
fprintf(fp_out,"(%d,%s)",12,TOKEN);//标识符
printf("(%d,%s)\n",15,TOKEN);//标识符
}
else
{
fprintf(fp_out,"(%d,%s)",c,TOKEN);//保留字
printf("(%d,%s)\n",c,TOKEN);//保留字
[设计要求](1)给出各单词符号的类别编码;(2)词法分析程序应能发现输入串中的错误;(3)词法分析作为单独一遍编写,词法分析结果为二元式序列组成的中间文件;(4)设计两个测试用例(尽可能完备),并给出测试结果。
3、
操作系统:Windows 7
软件:VC++6.0
4、
给出了各单词符号的类别编码;
词法分析程序能够对给出的文件中的输入串做出正确的词法;
<等于>→= <大于>→> <冒号>→: <斜竖>→/
该语言的保留字:begin end if then else for do while and or not
[设计说明](1)该语言大小写不敏感;(2)字母为a-z A-Z,数字为0-9;(3)可以对上述文法进行扩充和改造;(4)‘/*……*/’为程序的注释部分。
printf("(%d,%c)\n",16,'*');
}
break;
case';':
{
fprintf(fp_out,"(%d,%c)",17,';');
printf("(%d,%c)\n",17,';');
}
break;
case'(':
{
fprintf(fp_out,"(%d,%c)",18,'(');
default:
fprintf(fp_out,"(%s,%c)","非法字符",ch);
printf("(%s,%c)\n","非法字符",ch);
break;
}
}
ch=fgetc(fp);
if(zhushi==1)//该部分为检查注释是否结束,若结束,则令shuzhi=0;
if(ch=='*')
{
printf("(%d,%s)\n",22,">=");
}
else
{
if(ch!=EOF)
fseekБайду номын сангаасfp,-1,1);
fprintf(fp_out,"(%d,%c)",21,'>');
printf("(%d,%c)\n",21,'>');
}
break;
case'+':
{
fprintf(fp_out,"(%d,%c)",14,'+');
int scanner(FILE *fp)
{
char TOKEN[20];
FILE *fp_out=fopen("result.txt","w");
char ch;
int i=0,c;
int zhushi=0;//zhushi等于0表示当前不是注释,zhushi=1表示当前及以后的都是注释
ch=fgetc(fp);
2、
[实验项目]完成以下正则文法所描述的Pascal语言子集单词符号的词法分析程序。
<标识符>→字母︱<标识符>字母︱<标识符>数字
<无符号整数>→数字︱<无符号整数>数字
<单字符分界符>→+︱-︱*︱;︱(︱)
<双字符分界符>→<大于>=︱<小于>=︱<小于>>︱<冒号>=︱<斜竖>* <小于>→<
printf("(%d,%s)\n",16,TOKEN);//无符号整数
}
else
switch(ch)
{
case'<':
if(!feof(fp))
ch=fgetc(fp);
if(ch=='=')
{
fprintf(fp_out,"(%d,%s)",24,"<=");
printf("(%d,%s)\n",24,"<=");
if(!feof(fp))
ch=fgetc(fp);
if(ch=='/')
{
fprintf(fp_out,"(%s,%s)","注释结束","*/");
}
break;
case'=':
{
fprintf(fp_out,"(%d,%c)",20,'=');
printf("(%d,%c)\n",20,'=');
}
break;
case'>':
if(!feof(fp))
ch=fgetc(fp);
if(ch=='=')
{
fprintf(fp_out,"(%d,%s)",22,">=");
{
zhushi=1;//zhushi=1;
fprintf(fp_out,"(%d,%s)",28,"/*");
printf("(%d,%s)\n",28,"/*");
}
else
{
if(ch!=EOF)
fseek(fp,-1,1);
fprintf(fp_out,"(%d,%c)",27,'/');
printf("(%d,%c)\n",27,'/');
}
}
else
if(isdigit(ch))//是否为数字
{
TOKEN[0]=ch;
ch=fgetc(fp);
i++;
while(isdigit(ch))
{
TOKEN[i]=ch;
i++;
ch=fgetc(fp);
}
TOKEN[i]='\0';
if(ch!=EOF)
fseek(fp,-1L,1);
fprintf(fp_out,"(%d,%s)",13,TOKEN);//无符号整数
{
if(isalpha(ch))
ch=tolower(ch);
TOKEN[i]=ch;
i++;
ch=fgetc(fp);
}
TOKEN[i]='\0';
if(ch!=EOF)//经验证,若没有此判断,遇到文件结尾仍返回的话,则
fseek(fp,-1L,1);//ch的值永远为文件最后一个字符
c=lookup(TOKEN);//查找保留字
#include<iostream>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////////
相关文档
最新文档