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

编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的: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)掌握状态转换图及其实现; (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。
编译原理-词法分析

词法分析是编译原理中的重要阶段,负责将源代码分解为词法单元,为后续 的语法分析准备输入。
词法分析的定义和作用
词法分析是编译器的第一阶段,其主要目的是将源代码转换为有意义的词法 单元,如标识符、关键字、操作符等,以便后续的语法分析和语义分析使用。
词法分析的流程
1
扫描
将源代码分割为符号序列。
2
识别
将符号序列映射到相应的词法单元。
归类
将词法单元分为不同的类别,如标识符、关键字、操作符等。
常见的词法分析技术
正则表达式
用于描述词法单元的模式。
有限自动机
用于识别符号序列并生成词法 单元。
词法分析器生成器
自动生成词法分析器的工具。
词法分析的应用场景
词法分析广泛应用于编译器、解释器和语言处理工具等领域,确保源代码的正确解析和语义分析。
词法分析的挑战和解决方案
错误处理
如何处理错误输入和不合法的词法 单元。
性能优化
如何提高词法分析的速度和效率。
跨平台兼容
如何处理不同编程语言和操作系统 的词法规则。
结论和总结
词法分析是编译原理中不可或缺的一部分,对于编译器的正确性和性能有着 重要影响。了解词法分析的流程和技术,可帮助开发者构建更高效的编译器 和语言处理工具。
编译原理报告—词法分析器

词法分析器的作用词法分析是编译的第一阶段。
词法分析器的主要任务是读入源程序的输入字符,将它们组成词素,生成并输出一个词法单元序列,这个词法单元序列被输出到语法分析器进行语法分析。
另外,由于词法分析器在编译器中负责读取源程序,因此除了识别词素之外,它还会完成一些其他任务,比如过滤掉源程序中的注释和空白,将编译器生成的错误消息与源程序的位置关联起来等。
总而言之,词法分析器的作用如下:1.读入源程序的输入字符,将它们组成词素,生成并输出一个词法单元序列;2.过滤掉源程序中的注释和空白;3.将编译器生成的错误消息与源程序的位置关联起来;4.其它。
词法分析过程首先,对某个正则语言L,构造能够描述其的正则表达式r;然后,需要将r 转换成一个有穷自动机。
这里有三种方法,一是直接转换成NFA,而是直接转换成DFA,三是先转换成NFA,再把NFA 转换成DFA;最后,如果将r 转换成了一个DFA,需要将此DFA 的状态数最小化。
正则表达式正则表达式可以用来描述词素的模式,一个正则表达式可以由较小的正则表达式递归的构建。
对于符号集合∑={a,b},有:-正则表达式a 表示语言{a};-正则表达式a|b 表示语言{a,b};-正则表达式(a|b)(a|b)表示语言{aa,ab,ba,bb};-正则表达式a*表示语言{ε,a,aa,aaa,…};-正则表达式(a|b)*表示语言{ε,a,b,aa,ab,ba,bb,aaa,…};-正则表达式a|a*b 表示语言{a,b,ab,aab,aaab,…}。
上面通过基本的并、连接和闭包运算递归定义了正则表达式有穷自动机一个有穷自动机可以把一个描述词素的模式变成一个词法分析器,从本质上来讲,有穷自动机是与状态转换图相类似的图,它有以下特点:有穷自动机是一个识别器,它只能对每个输入符号串简单的输出“yes”或“no”,表示是否能够识别此符号串;有穷自动机和状态转换图类似,它具有有限个数的结点,每个结点表示一个状态,并且这些状态中有一个初始状态和若干个终止状态。
编译原理实验报告——词法分析器(内含源代码)

编译原理实验(一)——词法分析器一.实验描述运行环境:vc++2008对某特定语言A ,构造其词法规则。
该语言的单词符号包括:12状态转换图3程序流程:词法分析作成一个子程序,由另一个主程序调用,每次调用返回一个单词对应的二元组,输出标识符表、常数表由主程序来完成。
二.实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。
同时增强编写和调试程序的能力。
三.实验任务编制程序实现要求的功能,并能完成对测试样例程序的分析。
四.实验原理char set[1000],str[500],strtaken[20];//set[]存储代码,strtaken[]存储当前字符char sign[50][10],constant[50][10];//存储标识符和常量定义了一个Analyzer类class Analyzer{public:Analyzer(); //构造函数 ~Analyzer(); //析构函数int IsLetter(char ch); //判断是否是字母,是则返回 1,否则返回 0。
int IsDigit(char ch); //判断是否为数字,是则返回 1,否则返回 0。
void GetChar(char *ch); //将下一个输入字符读到ch中。
void GetBC(char *ch); //检查ch中的字符是否为空白,若是,则调用GetChar直至ch进入一个非空白字符。
void Concat(char *strTaken, char *ch); //将ch中的字符连接到strToken之后。
int Reserve(char *strTaken); //对strTaken中的字符串查找保留字表,若是一个保留字返回它的数码,否则返回0。
void Retract(char *ch) ; //将搜索指针器回调一个字符位置,将ch置为空白字符。
编译原理词法分析实验

编译原理词法分析实验一、实验目的本实验旨在通过编写一个简单的词法分析器,了解编译原理中词法分析的基本原理和实现方法。
二、实验材料1. 计算机编程环境2. 编程语言三、实验步骤1. 了解词法分析的概念和作用。
词法分析是编译器中的第一个阶段,它的主要任务是将源代码中的字符序列转化为有意义的标识符,如关键字、操作符、常量和标识符等。
2. 设计词法分析器的流程和算法。
词法分析器的主要原理是通过有限状态自动机来识别和提取标识符。
在设计过程中,需考虑各种可能出现的字符序列,并定义相应的状态转移规则。
3. 根据设计的流程和算法,使用编程语言编写词法分析器的代码。
4. 编译并运行词法分析器程序,输入待分析的源代码文件,观察程序的输出结果。
5. 分析输出结果,检查程序是否正确地提取了源代码中的标识符。
四、实验结果经过词法分析器的处理,源代码将被成功地转化为有意义的标识符。
结果可以通过以下几个方面来验证:1. 关键字和操作符是否被正确识别和提取。
2. 常量和标识符是否被正确识别和提取。
3. 检查程序的错误处理能力,如能否发现非法字符或非法标识符。
4. 输出结果是否符合预期,可与自己编写的语法规则进行对比。
5. 对于特殊情况,如转义字符等是否正确处理。
五、实验总结通过本次实验,我深入了解了编译原理中词法分析的重要性和基本原理。
编写词法分析器的过程中,我学会了使用有限状态自动机来识别和提取标识符,并通过实践巩固了相关知识。
此外,我还对源代码的结构有了更深入的了解,并且掌握了如何运用编程语言来实现词法分析器。
通过本次实验,我不仅提升了自己的编程技术,也对编译原理有了更深入的认识和理解。
六、实验心得通过实验,我深刻体会到了词法分析在编译过程中的重要性。
合理设计和实现词法分析器,可以大大提高编译器的效率和准确性。
同时,通过编写词法分析器的代码,我不仅锻炼了自己的编程能力,还提升了对编译原理的理解和掌握。
这次实验让我更加深入地了解了编译原理中的词法分析,也为我今后在编程领域的发展打下了坚实的基础。
编译原理实验--词法分析器

实验一词法分析器设计【实验目的】1.熟悉词法分析的基本原理,词法分析的过程以及词法分析中要注意的问题。
2.复习高级语言,进一步加强用高级语言来解决实际问题的能力。
3.通过完成词法分析程序,了解词法分析的过程。
【实验内容】用C语言编写一个PL/0词法分析器,为语法语义分析提供单词,使之能把输入的字符串形式的源程序分割成一个个单词符号传递给语法语义分析,并把分析结果(基本字,运算符,标识符,常数以及界符)输出。
【实验流程图】【实验步骤】1.提取pl/0文件中基本字的源代码while((ch=fgetc(stream))!='.'){int k=-1;char a[SIZE];int s=0;while(ch>='a' && ch<='z'||ch>='A' && ch<='Z'){if(ch>='A' && ch<='Z') ch+=32;a[++k]=(char)ch;ch=fgetc(stream);}for(int m=0;m<=12&&k!=-1;m++)for(int n=0;n<=k;n++){if(a[n]==wsym[m][n]) ++s;else s=0;if(s==(strlen(wsym[m]))) {printf("%s\t",wsym[m]);m=14;n=k+1;} }2.提取pl/0文件中标识符的源代码while((ch=fgetc(stream))!='.'){int k=-1;char a[SIZE]=" ";int s=0;while(ch>='a' && ch<='z'||ch>='A' && ch<='Z'){if(ch>='A' && ch<='Z') ch+=32;a[++k]=(char)ch;ch=fgetc(stream);}for(int m=0;m<=12&&k!=-1;m++)for(int n=0;n<=k;n++){if(a[n]==wsym[m][n]) ++s;else s=0;if(s==(strlen(wsym[m]))) {m=14;n=k+1;}}if(m==13) for(m=0;a[m]!=NULL;m++) printf("%c ",a[m]);3.提取pl/0文件中常数的源代码while((ch=fgetc(stream))!='.'){while(ch>='0' && ch<='9'){num=10*num+ch-'0';ch=fgetc(stream);}if(num!=0) printf("%d ",num);num=0;}4.提取pl/0文件中运算符的源代码int ch=fgetc(stream);while(ch!='.'){switch(ch){case'+': printf("+ ");break;case'-': printf("- ");break;case'*': printf("* ");break;case'/': printf("/ ");break;case'>': if(fgetc(stream)=='=')printf(">= "); else printf("> ");break;case'<': if(fgetc(stream)=='=')printf("<= "); else printf("< ");break;case':': printf(":= ");break;case'#': printf("# ");break;case'=': printf("= ");break;default: break;}ch=fgetc(stream);5.提取pl/0文件中界符的源代码int ch=fgetc(stream);while(ch!='.'){switch(ch){case',': printf(", ");break;case';': printf("; ");break;case'(': printf("( ");break;case')': printf(") ");break;default: break;}ch=fgetc(stream);}【实验结果】1.pl/0文件(222.txt)内容const a=10;var b,c;procedure p;beginc:=b+a;end;beginread(b);while b#0 dobegincall p;write(2*c);read(b)endend .2.实验运行结果【实验小结】1.了解程序在运行过程中对词法分析,识别一个个字符并组合成相应的单词,是机器能过明白程序,定义各种关键字,界符。
编译原理词法分析器

编译原理词法分析器
编译原理词法分析器是编译器中的一个重要组成部分。
它负责将源代码分解成一个个词素(token)。
在进行词法分析过程中,我们需要定义各种词法规则,例如标识符的命名规则、关键字的集合、运算符的定义以及常量的表示方式等。
词法分析器通常使用有限自动机来实现。
有限自动机是一种能接受或拒绝某个输入序列的计算模型。
在词法分析器中,有限自动机可以方便地根据输入字符的不同状态进行相应的转移,直至得到一个完整的词法单元。
在编写词法分析器时,我们通常会先定义各个词法规则,然后将其转化为正则表达式或有限自动机的形式。
接下来,我们会根据这些规则生成一个词法分析器的状态转换图,并使用该图构建词法分析器的代码。
词法分析器的工作过程如下:输入源代码文本,逐个读取字符并根据当前状态进行状态转移。
如果当前字符能够完成一个词法单元的匹配,那么就将当前词法单元输出,并进入下一个状态。
如果当前字符不能完成一个词法单元的匹配,则继续读取下一个字符,直至完成一个词法单元的匹配或遇到非法字符。
通过词法分析器,我们可以将源代码文本转化为一系列的词法单元,例如关键字、标识符、运算符、常量等。
这些词法单元将作为编译器后续阶段的输入,用于进行语法分析和语义分析。
词法分析器是编译器的重要基础工具之一,它能够帮助我们更好地理解和处理源代码。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
院部
计算机系
班级
B150402
学号
姓名
课程名称
编译原理
实验日期
2018.6.4
实验名称
词法分析器
成绩
实验目的:
加深对词法分析过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析;能够使自己编写的程序对简单的程序片段进行词法分析。
实验条件:
装有Windows操作系统,Microsoft Visual C++ 6.0。
return 3;
}
else if (a[i] == '>')
{
fprintf(fout,"<>\t(18)\n");
return 3;
}
else
{
i--;
fprintf(fout,"<\t(19)\n");
return 3;
}
case '>':
i++;
if (a[i] == '=')
{
fprintf(fout,">=\t(20)\n");
return(1);
}
if(fout==NULL){
printf("打开词法分析输出文件有错\n");
return(2);//返回错误代码2
}
printf("\n--------开始进行词法分析--------\n");
while (!feof(fin))
{
a[l++] = fgetc(fin);
}
}
int main()
{
printf("************C语言实现编译原理词法分析器************\n\n");
printf("\n");
int l = 0;
int m;
i = 0;
char input[100],output[100];//输入文件和输出文件的路径和文件名
printf("请输入词法分析输入的文件名(包括路径):");
4.对不正确的单词,做出错误处理。
实验容:
1.编程思路:
1.1、实现预处理功能
源程序中可能包含有对程序执行无意义的符号,要求将其剔除。
首先编制一个源程序的输入过程,从键盘、文件或文本框输入若干行语句,依次存入输入缓冲区(字符型数据);然后编制一个预处理子程序,去掉输入串中的回车符、换行符和跳格符等编辑性文字;把多个空白符合并为一个;去掉注释。
case ';': fprintf(fout,";\t(27)\n"); return 3;
case '(': fprintf(fout,"(\t(28)\n"); return 3;
case ')': fprintf(fout,")\t(29)\n"); return 3;
case '{': fprintf(fout,"{\t(30)\n"); return 3;
if (row != 0)
{
int y;
for (y = 0; y < 1000; y++)
{
int w = number[y][0];
sum = 0;
int d;
for (d = 1; d <= number[y][0]; d++)
{
w = w - 1;
sum = sum + number[y][d] * pow(2, w);
i--;
//判断该标识符是否为关键字
for (n = 0; n < 100; n++)
{
if (strcmp(word, keyWord[n]) == 0)
{
fprintf(fout,"%s\t(%d)\t关键字\n", keyWord[n], n + 1);
return 3;
}
}
//判断该标识符是否存在标识符表中
6. 实验报告包括以下容
(1)编程思路、流程图、源代码
(2)上机调试时发现的问题,以及解决的过程
(3)所使用的测试数据及结果
(4)心得体会
实验步骤
1.给出目标语言的所有单词符号及种别编码、单词符号的状态转换图。
2.依次读入源程序,对源程序进行单词切分和识别,直到源程序结束。
3.对正确的单词,按照它的种别以<种别码,值>的形式保存在符号表中。
{
number[row][n] = c % 2;
c = c / 2;
}
number[row][0] = m;
int line = row;
fprintf(fout,"%d\t(15,%d)\n", num, line + 1);
row++;
return 3;
}
else //分析符号
switch (a[i])
strcpy(mark[line], word);
fprintf(fout,"%s\t(14, %d)\t标识符\n", word, line + 1);
line++;
return 3;
}
else if (a[i] >= '0' && a[i] <= '9') //分析常数
{
char x[100];
2.流程图:
2.1主程序流程图
主函数流程图
2.2分析函数流程图
分析函数流程图
3.源代码:
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
int i, row = 0, line = 0;
scanf("%s",input);
printf("请输入词法分析输出的文件名(包括路径):");
scanf("%s",output);
fin=fopen(input,"r");
fout=fopen(output,"w");
if(fin==NULL){
printf("打开词法分析输入文件有错\n");
return 3;
}
else
{
i--;
fprintf(fout,">\t(21)\n");
return 3;
}
case '+': fprintf(fout,"+\t(22)\n"); return 3;
case '-': fprintf(fout,"-\t(23)\n"); return 3;
case '*': fprintf(fout,"*\t(24)\n"); return 3;
{
char word[10];
char keyWord[100][100] = { "char","int","if","else","var" ,"return","break","do","while","for","double","float","short"}; //关键字表
int n = 0;
2)运算符和界符
+ - * /<<><=>>==;()[ ] \ | & { } \\ #
3)空格由空白、制表符和换行符组成
空格一般用来分隔ID、NUM、专用符号和关键字,词法分析阶段通常被忽略。
1.4、各种单词符号对应的种别码
表1各种单词符号的种别码
单词符号
种别码
char
1
int
2
if
3
else
4
i++;
if(a[i]!='&'){
i--;
fprintf(fout,"&\t(38)\n"); return 3;
}
else{
fprintf(fout,"&&\t(39)\n");return 3;
}
case '\\': fprintf(fout,"\\\t(40)\n"); return 3;
}
int m = 0;
if (line != 0)
{
int q = 0;
while (q<line)
{
if (strcmp(word, mark[q++]) == 0)
{
fprintf(fout,"%s\t(14,%d)\t标识符\n", word, q);
return 3;
}
}
}
//将该标识符保存到标识符表中