编译原理实验:词法分析
- 格式:pdf
- 大小:240.17 KB
- 文档页数:7
编译原理中的词法分析与语法分析原理解析编译原理中的词法分析和语法分析是编译器中两个基本阶段的解析过程。
词法分析(Lexical Analysis)是将源代码按照语法规则拆解成一个个的词法单元(Token)的过程。
词法单元是代码中的最小语义单位,如标识符、关键字、运算符、常数等。
词法分析器会从源代码中读取字符流,将字符流转换为具有词法单元类型和属性值的Token序列输出。
词法分析过程中可能会遇到不合法的字符序列,此时会产生词法错误。
语法分析(Syntax Analysis)是对词法单元序列进行语法分析的过程。
语法分析器会根据语法规则,将词法单元序列转换为对应的抽象语法树(Abstract Syntax Tree,AST)。
语法规则用于描述代码的结构和组织方式,如变量声明、函数定义、控制流结构等。
语法分析的过程中,语法分析器会检查代码中的语法错误,例如语法不匹配、缺失分号等。
词法分析和语法分析是编译器的前端部分,也是编译器的基础。
词法分析和语法分析的正确性对于后续的优化和代码生成阶段至关重要。
拓展部分:除了词法分析和语法分析,编译原理中还有其他重要的解析过程,例如语义分析、语法制导翻译、中间代码生成等。
语义分析(Semantic Analysis)是对代码进行语义检查的过程。
语义分析器会根据语言的语义规则检查代码中的语义错误,例如类型不匹配、变量声明未使用等。
语义分析还会进行符号表的构建,维护变量和函数的属性信息。
语法制导翻译(Syntax-Directed Translation)是在语法分析的过程中进行语义处理的一种技术。
通过在语法规则中嵌入语义动作(Semantic Action),语法制导翻译可在语法分析的同时进行语义处理,例如求解表达式的值、生成目标代码等。
中间代码生成(Intermediate Code Generation)是将高级语言源代码转换为中间表示形式的过程。
中间代码是一种抽象的表示形式,可以是三地址码、四元式等形式。
编译原理实验⼀词法分析实验⼀词法分析【实验⽬的】 (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。
编译原理实验报告班级姓名:学号:自我评定:实验一词法分析程序实现一、实验目的与要求通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。
二、实验内容根据教学要求并结合学生自己的兴趣和具体情况,从具有代表性的高级程序设计语言的各类典型单词中,选取一个适当大小的子集。
例如,可以完成无符号常数这一类典型单词的识别后,再完成一个尽可能兼顾到各种常数、关键字、标识符和各种运算符的扫描器的设计和实现。
输入:由符合或不符合所规定的单词类别结构的各类单词组成的源程序。
输出:把单词的字符形式的表示翻译成编译器的内部表示,即确定单词串的输出形式。
例如,所输出的每一单词均按形如(CLASS,VALUE)的二元式编码。
对于变量和常数,CLASS字段为相应的类别码;VALUE字段则是该标识符、常数的具体值或在其符号表中登记项的序号(要求在变量名表登记项中存放该标识符的字符串;常数表登记项中则存放该常数的二进制形式)。
对于关键字和运算符,采用一词一类的编码形式;由于采用一词一类的编码方式,所以仅需在二元式的CLASS字段上放置相应的单词的类别码,VALUE字段则为“空”。
另外,为便于查看由词法分析程序所输出的单词串,要求在CLASS字段上放置单词类别的助记符。
三、实现方法与环境词法分析是编译程序的第一个处理阶段,可以通过两种途径来构造词法分析程序。
其一是根据对语言中各类单词的某种描述或定义(如BNF),用手工的方式(例如可用C语言)构造词法分析程序。
一般地,可以根据文法或状态转换图构造相应的状态矩阵,该状态矩阵同控制程序便组成了编译器的词法分析程序;也可以根据文法或状态转换图直接编写词法分析程序。
构造词法分析程序的另外一种途径是所谓的词法分析程序的自动生成,即首先用正规式对语言中的各类单词符号进行词型描述,并分别指出在识别单词时,词法分析程序所应进行的语义处理工作,然后由一个所谓词法分析程序的构造程序对上述信息进行加工。
编译原理词法分析实验报告实验一词法分析一、实验目的通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
二、实验内容(1)功能描述:该程序是实现一个词法分析器,词法分析器的功能是输入源程序,输出单词符号。
词法分析器的单词符号常常表示成以下的二元式(单词种别码,单词符号的属性值)。
本实验中,采用的是将单词分为五种的方法。
识别关键字:main、if、int、for、while、do、return、break、continue;单词种别码为1。
标识符:单词种别码为2。
常数:为无符号整形数;单词种别码为3。
运算符:包括:+、-、*、/、=、>、<、>=、<=、!= ;单词种别码为4。
分隔符:包括:,、;、{、}、(、);单词种别码为5。
(2)程序结构描述:输入:从控制台输入一段源程序代码,对输入的代码进行词法分析,处理:分离出关键字、标识符、数值、运算符和界符。
输出:在词法分析结果表中输出每个单词所在行号、类型以及它所对应的编码。
其中,编码是自定义的,一种类型对应一个编码。
词法分析结果显示在控制台上。
(3)程序设计思路1、定义编码表,用ArrayList集合存放单词,如:关键字、运算符、分界符。
这三种单词是固定的,标示符和数字这两种单词不存放在集合中。
编码表是固定的,只需要初始化一次就够了,所以将集合定义为static类型,使其在类加载时,进行一次初始化。
2、static char allstr[] = new char[100000];该数组用于存储用户从控制台输入的所有字符。
3、//从键盘获取一个一个的字符public char Getchar() {try {ch = (char) System.in.read();} catch (Exception e) {e.printStackTrace();}return ch;}4、用while循环遍历allstr数组中存放的字符,判断分离出关键字、标示符、数字、运算符、标示符。
实验一词法分析器设计【实验目的】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)。
在进行词法分析过程中,我们需要定义各种词法规则,例如标识符的命名规则、关键字的集合、运算符的定义以及常量的表示方式等。
词法分析器通常使用有限自动机来实现。
有限自动机是一种能接受或拒绝某个输入序列的计算模型。
在词法分析器中,有限自动机可以方便地根据输入字符的不同状态进行相应的转移,直至得到一个完整的词法单元。
在编写词法分析器时,我们通常会先定义各个词法规则,然后将其转化为正则表达式或有限自动机的形式。
接下来,我们会根据这些规则生成一个词法分析器的状态转换图,并使用该图构建词法分析器的代码。
词法分析器的工作过程如下:输入源代码文本,逐个读取字符并根据当前状态进行状态转移。
如果当前字符能够完成一个词法单元的匹配,那么就将当前词法单元输出,并进入下一个状态。
如果当前字符不能完成一个词法单元的匹配,则继续读取下一个字符,直至完成一个词法单元的匹配或遇到非法字符。
通过词法分析器,我们可以将源代码文本转化为一系列的词法单元,例如关键字、标识符、运算符、常量等。
这些词法单元将作为编译器后续阶段的输入,用于进行语法分析和语义分析。
词法分析器是编译器的重要基础工具之一,它能够帮助我们更好地理解和处理源代码。
编译原理词法分析器编译原理是计算机科学中的重要领域,而词法分析器则是编译器的第一个阶段。
它的主要任务是将源代码转化为一个个词法单元,以便接下来的语法分析和语义分析等阶段进行处理。
在本文中,我们将深入探讨词法分析器的原理和实现。
一、什么是词法分析器词法分析器(Lexical Analyzer)是编译器中实现词法分析的部分。
它负责从源代码中提取出各个合法的词法单元,并进行分类和标记。
词法单元通常包括关键字、标识符、运算符、分隔符和常量等。
二、词法分析器的原理词法分析器的工作原理可以概括为以下几个步骤:1. 预处理:词法分析器首先会对源代码进行预处理,去除注释、替换宏定义等。
2. 分割:将预处理后的源代码分割成一个个字符。
3. 匹配:根据预定义的词法规则,将字符序列匹配到对应的词法单元上。
4. 标记:对每个词法单元都打上相应的标记,以便后续的语法分析。
三、词法分析器的实现1. 正则表达式:词法分析器通常使用正则表达式定义词法规则,用以匹配词法单元。
例如,使用正则表达式"\d+"可以匹配一个或多个数字。
2. 有限自动机:词法分析器可以通过构造有限自动机来进行词法分析。
有限自动机可以根据当前状态和输入字符进行状态转移,最终得到一个词法单元的序列。
3. 符号表:词法分析器使用符号表来存储已经识别出的标识符和关键字,并为每个标识符分配一个唯一的标识符号。
四、应用举例以C语言为例,假设我们要编写一个词法分析器来分析C源代码。
下面是一个简单的示例代码:```c#include <stdio.h>int main() {int a = 10;printf("Hello, World!\n");return 0;}```我们可以使用词法分析器将其分解为以下词法单元序列:1. 关键字:include、stdio、int、main、return2. 标识符:a3. 运算符:=4. 常量:105. 分隔符:()、{}6. 函数名:printf7. 字符串常量:"Hello, World!\n"通过词法分析器的处理,我们可以将源代码转化为一个个词法单元,为后续的语法分析提供准备。