编译原理实验_词法分析器的设计与实现
编译原理实验一词法分析
编译原理实验⼀词法分析实验⼀词法分析【实验⽬的】 (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。
编译原理实验报告
编译原理实验报告一、实验目的本次编译原理实验的主要目的是通过实践加深对编译原理中词法分析、语法分析、语义分析和代码生成等关键环节的理解,并提高实际动手能力和问题解决能力。
二、实验环境本次实验使用的编程语言为 C/C++,开发工具为 Visual Studio 2019,操作系统为 Windows 10。
三、实验内容(一)词法分析器的设计与实现词法分析是编译过程的第一个阶段,其任务是从输入的源程序中识别出一个个具有独立意义的单词符号。
在本次实验中,我们使用有限自动机的理论来设计词法分析器。
首先,我们定义了单词的种类,包括关键字、标识符、常量、运算符和分隔符等。
然后,根据这些定义,构建了相应的状态转换图,并将其转换为程序代码。
在实现过程中,我们使用了字符扫描和状态转移的方法,逐步读取输入的字符,判断其所属的单词类型,并将其输出。
(二)语法分析器的设计与实现语法分析是编译过程的核心环节之一,其任务是在词法分析的基础上,根据给定的语法规则,判断输入的单词序列是否构成一个合法的句子。
在本次实验中,我们采用了自顶向下的递归下降分析法来实现语法分析器。
首先,我们根据给定的语法规则,编写了相应的递归函数。
每个函数对应一种语法结构,通过对输入单词的判断和递归调用,来确定语法的正确性。
在实现过程中,我们遇到了一些语法歧义的问题,通过仔细分析语法规则和调整函数的实现逻辑,最终解决了这些问题。
(三)语义分析与中间代码生成语义分析的任务是对语法分析所产生的语法树进行语义检查,并生成中间代码。
在本次实验中,我们使用了四元式作为中间代码的表示形式。
在语义分析过程中,我们检查了变量的定义和使用是否合法,类型是否匹配等问题。
同时,根据语法树的结构,生成相应的四元式中间代码。
(四)代码优化代码优化的目的是提高生成代码的质量和效率。
在本次实验中,我们实现了一些基本的代码优化算法,如常量折叠、公共子表达式消除等。
通过对中间代码进行分析和转换,减少了代码的冗余和计算量,提高了代码的执行效率。
电子科大-编译原理实验报告(得分80分)
电子科技大学实验报告学生姓名:爸爸学号:2222222222222 指导教师:陈昆实验地点:科研楼A-506 实验时间:2017-04-28一、实验项目名称:词法分析器的设计与实现二、实验学时:4学时三、实验原理1.编译程序要求对高级语言编写的源程序进行分析和合成,生成目标程序。
词法分析是对源程序进行的首次分析,实现词法分析的程序为词法分析程序或词法分析器,也称扫描器。
2.词法分析的功能是:从左到右逐个地扫描源程序字符串,按照词法规则,识别出单词符号作为输出,对识别过程中发现的词法错误,输出相关的错误信息。
3.识别出来的单词会采用某种中间表现形式,通常一个单词用一个二元式来表示:(单词类别,单词的属性)。
4.状态转换图简称转化图,是有限有向图,是设计词法分析器的有效工具。
四、实验目的通过该实验,让同学们自己独立自主的设计词法分析器,使得同学们可以更好的掌握词法分析程序设计的原理及相应的程序设计方法,对编译这门课程也可以有更加深刻理解,同时还可以锻炼编程能力。
五、实验内容实现求n!的极小语言的词法分析程序,返回二元式作为输出。
六、实验器材(设备、元器件)1.操作系统:Windows XP2.开发工具:VS2013七、实验步骤(1)在VS2013中创建工程;(2)编写输入输出,初始化,错误处理等函数;(3)建立相应的单词符号与种别对照表,根据状态转换图编写相应的处理函数;(4)运行代码进行调试;(5)编写测试需要的输入文件:.pas文件;(6)生成.dyd文件。
八、实验数据及结果分析编码完成后将测试程序放入debug文件夹中,测试程序如下图:代码运行成功后在debug文件夹中会产生对应的exe,在cmd中运行后,会在debug文件夹中生成后缀为dyd和err的文件,打开dyd如下图所示:因为没有错误,所以对应的test1.err的文件为空可以对源程序进行词法分析,如果有错给出出错信息和所在行数,如果无错则生成二元式文件。
编译原理实验报告
编译原理实验报告班级姓名:学号:自我评定:实验一词法分析程序实现一、实验目的与要求通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。
二、实验内容根据教学要求并结合学生自己的兴趣和具体情况,从具有代表性的高级程序设计语言的各类典型单词中,选取一个适当大小的子集。
例如,可以完成无符号常数这一类典型单词的识别后,再完成一个尽可能兼顾到各种常数、关键字、标识符和各种运算符的扫描器的设计和实现。
输入:由符合或不符合所规定的单词类别结构的各类单词组成的源程序。
输出:把单词的字符形式的表示翻译成编译器的内部表示,即确定单词串的输出形式。
例如,所输出的每一单词均按形如(CLASS,VALUE)的二元式编码。
对于变量和常数,CLASS字段为相应的类别码;VALUE字段则是该标识符、常数的具体值或在其符号表中登记项的序号(要求在变量名表登记项中存放该标识符的字符串;常数表登记项中则存放该常数的二进制形式)。
对于关键字和运算符,采用一词一类的编码形式;由于采用一词一类的编码方式,所以仅需在二元式的CLASS字段上放置相应的单词的类别码,VALUE字段则为“空”。
另外,为便于查看由词法分析程序所输出的单词串,要求在CLASS字段上放置单词类别的助记符。
三、实现方法与环境词法分析是编译程序的第一个处理阶段,可以通过两种途径来构造词法分析程序。
其一是根据对语言中各类单词的某种描述或定义(如BNF),用手工的方式(例如可用C语言)构造词法分析程序。
一般地,可以根据文法或状态转换图构造相应的状态矩阵,该状态矩阵同控制程序便组成了编译器的词法分析程序;也可以根据文法或状态转换图直接编写词法分析程序。
构造词法分析程序的另外一种途径是所谓的词法分析程序的自动生成,即首先用正规式对语言中的各类单词符号进行词型描述,并分别指出在识别单词时,词法分析程序所应进行的语义处理工作,然后由一个所谓词法分析程序的构造程序对上述信息进行加工。
编译原理课程设计C编译器词法分析与语法分析的实现
编译原理课程设计报告课落款称: C-编译器词法分析与语法分析的实现提交文档学生姓名:黄臻旸提交文档学生学号: 1043041227 同组成员名单:无指导教师姓名:金军指导教师评阅成绩:指导教师评阅意见:..提交报告时刻:2021年 6 月 5 日编译原理课程设计报告 (1)一、课程设计目标 (3)二、分析与设计 (3)2.一、说明所用的方式: (3)2.二、系统总图: (3)2.2.一、scanner部份: (3)2.2.二、parse部份: (5)2.2.3、代码设计说明 (7)3、程序代码实现 (10)3.一、获取输入部份(在main.c中): (10)3.二、词法分析部份(在scan.c中): (10)3.3、语法分析部份(在parse.c中): (15)3.4、输出与结点的成立(在util.c中) (29)3.五、TokenType、treeNode与结点类型的声明(在globals.h中) (35)4、测试结果 (36)五、总结 (40)5.一、收成 (43)5.二、不足 (43)一、课程设计目标本次实验,本C- 编译器要紧设计而且实现了C- 编译器的词法分析功能与语法分析功能。
二、分析与设计2.一、说明所用的方式:各部份的实现方式(scanner:手工实现、Lex;parser:递归下降、LL(1)、LR(0)、SLR(1)、2.二、系统总图:2.2.一、scanner部份:2.2.1.一、实验原理:扫描程序的任务是从源代码中读取字符并形成由编译器的以后部份(一般是分析程序)处置的逻辑单元。
由扫描程序生成的逻辑单元称作记号(token),将字符组合成记号与在一个英语句子中将字母将字母组成单词并确信单次的含义很相像。
在此程序中,我将记号分成了以下类型:typedef enum {ENDFILE,ERROR,IF,ELSE,INT,RETURN,VOID,WHILE,ID,NUM,ASSIGN,PLUS,MINUS,TIMES,OVER,L T,LET,BT,BET,EQ,NEQ,// = + - * / < <= > >= == !=LPAREN_1,RP AREN_1,SEMI,COM,LPAREN_2,RP AREN_2,LPAREN_3,RP AREN_3,LIN,RIN// { } ; , [ ] ( ) /*} TokenType;其中,关键字有:else、if、int、return、void、while;专用符号有:+、-、*、/、<、<=、>、>=、==、~=、=、;、,、(、)、[、]、{、}、/*、*/其他标记是ID、NUM,通过以下正那么表达式概念:ID = letter letter*NUM = digit digit*letter = a|..|z|A|..|Zdigit = 0|..|9小写大写字母是有区别的。
编译原理 实验一 词法分析
《编译系统设计实践》实验项目一:词法分析指导老师:陈晖组长:许堃组员:一、实验目的词法分析的目的是将输入的源程序进行划分,给出基本符号(token)的序列,并掠过注解和空格等分隔符号。
基本符号是与输入的语言定义的词法所规定的终结符。
二、实验内容本实验要求学生编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续进行)三、程序设计与实现程序功能描述:程序从文本读入一段程序代码,对每一个字符进行分析,识别出各个具有独立意义的单词,并依次输出各个单词的内部编码及单词符号自身值。
过程描述:过程描述:先从文本中读入字符,定义两个指针begin和forward,begin指向每一个词素的首个字符,forward一直向前扫描,直到发现某个单词被匹配为止,一旦确定了下一个单词,forward指针将指向该词素结尾的字符,确定词素后,根据内部编号输出其编号和自身值。
数据结构:数组程序流程图:正则表达式:标识符 id->letter_(letter_|digit)*无符号数 number->digit optitionalfraction optionalexponent 空白符 ws->(blank|tab|newline)+ 关系运算符 relop-> <|>|<=|>=|=|<> 运算符 operator->+|-|*|/DFA 图:=|<>|<|>|<=|>=|+|-|*|/ a —z A--Z0--9;| ( | ) | ,| [ | ] | .开始(每个词素首个字符)符号转化 符号转化符号转化符号转化关键字?标识符?结束startdelim22other24 23*19 12141316151817 startotherdigit. digit E+ | -digitdigit digitdigit Edigit *startletter9other 11 10letter/dig*start<other= 67 8return(relop, LE) 54>= 123other>=* * return(relop, NE)return(relop, LT)return(relop, EQ)return(relop, GE)return(relop, GT)10四、程序测试第一组测试:输入:输出:第二组测试:输入:输出:第三组测试:输入:输出:五、小组成员分工与实验小结由于有一段时间没有编程序,而且实验本身也有些难度,所以在实验初期遇到了很大阻碍,不知道该从何下手。
编译原理的实验报告
一、实验目的1. 理解编译原理的基本概念和原理。
2. 掌握编译器的各个阶段及其实现方法。
3. 能够运用编译原理的知识解决实际问题。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 20194. 实验内容:词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成三、实验内容1. 词法分析(1)实验目的:实现一个简单的词法分析器,将源代码中的字符序列转换为词法符号序列。
(2)实验步骤:1)定义词法符号类型,包括标识符、关键字、运算符、常量等。
2)设计词法分析器算法,对源代码进行遍历,将字符序列转换为词法符号序列。
3)实现词法分析器程序,输出词法符号序列。
(3)实验结果:输入源代码:int a = 10;输出词法符号序列:{<int, int>, <a, a>, <=, =>, <10, 10>, <;, ;>}2. 语法分析(1)实验目的:实现一个简单的语法分析器,将词法符号序列转换为抽象语法树(AST)。
(2)实验步骤:1)定义语法规则,包括产生式、非终结符、终结符等。
2)设计语法分析算法,根据语法规则对词法符号序列进行解析,生成AST。
3)实现语法分析器程序,输出AST。
(3)实验结果:输入词法符号序列:{<int, int>, <a, a>, <=, =>, <10, 10>, <;, ;>}输出AST:```AST:- ExpressionStatement- Expression- BinaryExpression- Identifier: a- Operator: =- Constant: 10```3. 语义分析(1)实验目的:实现语义分析器,对AST进行语义检查,确保程序的正确性。
(2)实验步骤:1)定义语义规则,包括类型检查、作用域检查等。
编译原理词法分析器实验报告
一、实验目的设计一个简单的词法分析器,从而进一步加深对词法分析器工作原理的明白得。
二、实验要求一、该个词法分析器要求至少能够识别以下几类单词:(1)关键字:else if int return void while共6个,所有的关键字都是保留字,而且必需是小写;(2)标识符:识别与C语言词法规定相一致的标识符,通过以下正那么表达式概念:ID = letter (letter | digit)*;(3)常数:NUM = digit digit*(.digit digit* |ε)(e(+ | - |ε) digit digit* |ε),letter = a|..|z|A|..|Z|,digit = 0|..|9,包括整数,如123等;小数,如123.45等;科学计数法表示的常数,如1.23e3,2.3e-9等;(4)专用符号:+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */;二、分析器的输入为由上述几类单词组成的程序,输出为该段程序的机内表示形式,即关键字、运算符、界限符变成其对应的机内符,常数利用二进制形式,标识符利用相应的标识符表指针表示。
3、词法分析器应当能够指出源程序中的词法错误,如不可识别的符号、错误的词法等。
三、实验环境实验环境为win7系统、vs2005。
四、实验内容1、词法分析程序的功能:输入:所给文法的源程序字符串。
输出:二元组(syn,token)或(sum或fsum,对应二进制)组成的序列。
其中:syn为单词类别码;token为寄存的单词自身字符串;sum为整型常数;fsum为浮点型常数。
二、各类单词符号类别码如下表:五、要紧函数说明一、程序全局变量char inputstr[300],token[8];//别离寄存程序段、组成单词符号的字符串char ch;//输入字符int syn;//单词字符的类别码int p;//缓冲区inputstr的指针int sum;//整型常量float fsum;//浮点型常量char *rwtab[6]={"else","if","int","return","void","while"};//关键字数组二、语法分析函数void scaner()该函数完成所有的语法分析,关于输入的程序片段,第一去掉空格和换行,然后逐字符分析,找出各个单词(存入token[8]),判别它们的类型(确信syn 值,若是是整数那么是sum值,若是是浮点数那么是fsum)。
电子科大-编译原理实验报告(得分70分)
______________________________________________________________________________________________________________精品资料计算机专业类课程实验报告课程名称:编译原理学 院:计算机科学与工程学院 专 业:计算机科学与技术专业 学生姓名:郫县库里 学 号:2014666666666 指导教师:日 期: 2017年 5月 14日电子科技大学实验报告实验一一、实验名称:词法分析器的设计与实现二、实验学时:4三、实验内容和目的:(一)实验内容:1.源语言:求n!的极小语言2.输入输出:源程序*.pas文件作为输入,经过自己编程实现的词法分析器进行处理,生成二元式,保存到*.dyd文件中,如下图所示。
(二)实验目的:通过设计词法分析器的实验,使同学们了解和掌握词法分析程序设计的原理及相应的程序设计方法,同时提高编程能力。
四、实验原理:(一)结合“数据结构”进行分析:1.二元式文件*.dyd(1)二元式形式:______________________________________________________________________________________________________________分析:由输出二元式形式可知,使用printf输出可以很方便达到要求:(2)每行后加一分析:对输入文件中的换行符“\n”,要采取相应的策略:(3)文件结尾加分析:对于文件末尾的“EOF”,要采取相应的策略:2.错误信息文件:*.err(1)错误信息格式分析:设置出错处理的函数,并且需要记录错误行号、错误性质:(2)注意:进入每一阶段, 首先打开.err, 如果无错误, 则.err为空。
(二)词法分析的实现方法——利用状态转换精品资料分析:根据状态转化图,编写读到不同的内容时的状态转化函数,是设计词法分析器的核心。
编译原理实验报告词法分析器语法分析器
头验一一、实验名称:词法分析器的设计二、实验目的:1词法分析器能够识别简单语言的单词符号2 ,识别出并输出简单语言的基本字•标示符.无符号整数•运算符.和界符三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
2、程序流程图(1)主程序验报告(2)扫描子程序3、各种单词符号对应的种别码单词符号种别码助记符内码值while 1 while -if 2 if -else 3 else -switch 4 switch -case 5 case -标识符6 id id在符号表中的位置常数7 num num在常数表中的位置+ 8 + -- 9 - -* 10 * -<= 11 relop LE< 11 relop LT== 11 relop EQ= 12 = -J 13J-五、实验内容:1、实验分析编写程序时,先定义几个全局变量a[] 、token[] (均为字符串数组),c,s( char 型),i,j,k (int型),a[]用来存放输入的字符串,token[] 另一个则用来帮助识别单词符号,s 用来表示正在分析的字符。
字符串输入之后,逐个分析输入字符,判断其是否‘#',若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c) 、int letter(char c) 判断其是数字,字符还是算术符, 分别为用以判断数字或字符的情况,算术符的判断可以在switch 语句中进行,还要通过函数int lookup(char token[]) 来判断标识符和保留字。
2 实验词法分析器源程序:#include <stdio.h> #include <math.h> #include <string.h> int i,j,k;char c,s,a[20],token[20]={'0'};int letter(char s){if((s>=97)&&(s<=122)) return(1);else return(0);}int digit(char s){if((s>=48)&&(s<=57)) return(1);else return(0);void get(){s=a[i];i=i+1;}void retract(){i=i-1;}int lookup(char token[20]){ if(strcmp(token,"while")==0) return(1);else if(strcmp(token,"if")==0) return(2);else if(strcmp(token,"else")==0) return(3);else if(strcmp(token,"switch")==0) return(4);else if(strcmp(token,"case")==0) return(5);else return(0);}void main(){printf("please input string :\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!='#');i=1;j=0;get();while(s!='#'){ memset(token,0,20); switch(s){case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'g':case 'h':case 'i':case 'j':case 'k':case 'l':case 'm':case 'n':case 'o':case 'p': case 'q': case 'r':case 's':case 't':case 'u':case 'v':case 'w':case 'x':case 'y':case 'z':while(letter(s)||digit(s)) {token[j]=s;j=j+1;get();}retract();k=lookup(token); if(k==0)printf("(%d,%s)",6,token); else printf("(%d,-)",k); break; case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':while(digit(s)){token[j]=s;j=j+1;get();}retract();printf("%d,%s",7,token); break;case '+':printf("('+',NULL)");break;case '-':printf("('-',null)");break;case '*':printf("('*',null)");break;case '<':get();if(s=='=') printf("(relop,LE)");else{retract();printf("(relop,LT)");}break;case '=':get();if(s=='=')printf("(relop,EQ)");else{retract();printf("('=',null)");}break;case ';':printf("(;,null)");break;case ' ':break; default:printf("!\n");}j=0;get();六:实验结果:实验二一、实验名称:语法分析器的设计二、实验目的:用C语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术。
编译原理词法分析与语法分析的基本原理与实现
编译原理词法分析与语法分析的基本原理与实现编译原理是计算机科学的核心课程之一,它研究如何将高级语言编写的程序转换为计算机可以执行的机器码。
而词法分析和语法分析则是编译原理中的两个重要组成部分,它们负责将源代码分解为更加抽象和易于处理的单元,以供后续的语义分析和代码生成阶段使用。
一、词法分析的基本原理与实现词法分析是编译器的第一道工序,它负责将源代码按照词素的单位进行分解,生成一个个词法单元(Token)。
词法单元是计算机程序中最小的、有着确定含义的语法单元,例如关键字、标识符、常数、运算符等。
词法分析器根据编程语言的词法规则,通过有限自动机(DFA)来实现对源代码的扫描和分析。
词法分析的基本原理可以概括为以下几个步骤:1. 正则表达式定义词法规则:不同的编程语言有着不同的词法规则,可以通过正则表达式的方式来定义关键字、标识符、运算符等的模式。
2. 构建有限自动机(DFA):根据正则表达式的定义,可以通过状态转换图的方式来构造一个有限自动机。
这个自动机可以根据输入的字符逐步进行状态转换,最终确定每个输入字符的类型。
3. 扫描源代码:将源代码作为输入输入到DFA中,逐个字符进行扫描,并根据状态转换图确定每个词法单元的类型。
4. 生成词法单元(Token):根据扫描的结果,生成对应的词法单元,包括单词的类型和对应的值。
实现词法分析的方式有很多种,常用的方法包括手动写正则表达式和有限自动机,以及使用词法分析生成器(Lexical Analyzer Generator)等现成工具。
二、语法分析的基本原理与实现语法分析是编译器的第二道工序,它负责根据词法分析的结果,构建抽象语法树(Abstract Syntax Tree,AST)。
抽象语法树是用来描述源代码语法结构的一个抽象数据结构,它将源代码转换为一棵以表达式和语句为节点的树。
语法分析的基本原理可以概括为以下几个步骤:1. 文法定义:编程语言的语法结构可以通过上下文无关文法(Context-Free Grammar,CFG)来定义,即通过产生式对非终结符进行扩展。
编译原理词法分析器实验报告
编译原理词法分析器实验报告1. 引言编译原理是计算机科学中的重要概念,它涉及将高级语言程序转换为计算机可执行的低级指令。
词法分析是编译过程中的第一个阶段,它负责将源代码分解为词法单元,为后续的语法分析做准备。
本实验旨在设计和实现一个基本的词法分析器,以了解词法分析的原理和实际应用。
2. 实验目标本实验的主要目标是实现一个基本的词法分析器,能够识别并提取源代码中的各种词法单元。
具体而言,我们将设计一个针对某种编程语言的词法分析器,能够识别关键字、标识符、算术运算符、括号、常量等。
3. 实验环境为了完成本实验,我们需要使用以下工具和环境:•一种编程语言,例如Python、Java或C++•一个文本编辑器,例如Visual Studio Code或Sublime Text•一个命令行终端4. 实验步骤4.1 定义词法规则首先,我们需要定义词法分析器的词法规则。
这些规则描述了编程语言中各种词法单元的模式。
例如,关键字可以被定义为由特定字符组成的字符串,标识符可以被定义为以字母开头并由字母和数字组成的字符串。
4.2 实现词法分析器接下来,我们将根据定义的词法规则,使用编程语言实现一个词法分析器。
在实现过程中,我们可以使用正则表达式来匹配和提取各种词法单元。
4.3 编写测试用例完成词法分析器的实现后,我们需要编写一些测试用例来验证其正确性。
测试用例应该包含各种可能的输入情况,以确保词法分析器能够正确地识别和提取词法单元。
4.4 运行测试用例最后,我们将使用编写的测试用例来运行词法分析器,并检查输出是否符合预期。
如果测试通过,说明词法分析器能够正常工作;否则,我们需要检查代码并进行调试。
5. 实验结果经过实验,我们成功地设计并实现了一个基本的词法分析器。
该词法分析器能够按照预定义的词法规则,正确地识别和提取源代码中的各种词法单元。
在运行测试用例时,词法分析器能够产生符合预期的输出,表明其具有良好的准确性和可靠性。
编译原理实验-词法分析器
编译原理实验-词法分析器⼀、实验⽬的设计、编制、调试⼀个词法分析程序,对单词进⾏识别和编码,加深对词法分析原理的理解。
⼆、实验内容1.选定语⾔,编辑任意的源程序保存在⽂件中;2.对⽂件中的代码预处理,删除制表符、回车符、换⾏符、注释、多余的空格并将预处理后的代码保存在⽂件中;3.扫描处理后的源程序,分离各个单词符号,显⽰分离的单词类型。
三、实验思路对于实验内容1,选择编写c语⾔的源程序存放在code.txt中,设计⼀个c语⾔的词法分析器,主要包含三部分,⼀部分是预处理函数,第⼆部分是扫描判断单词类型的函数,第三部分是主函数,调⽤其它函数;对于实验内容2,主要实现在预处理函数processor()中,使⽤⽂档操作函数打开源程序⽂件(code.txt),去除两种类型(“//”,“/*…*/”)的注释、多余的空格合并为⼀个、换⾏符、回车符等,然后将处理后的保存在另⼀个新的⽂件(afterdel.txt)中,最后关闭⽂档。
对于实验内容3,打开处理后的⽂件,然后调⽤扫描函数,从⽂件⾥读取⼀个单词调⽤判断单词类型的函数与之前建⽴的符号表进⾏对⽐判断,最后格式化输出。
四、编码设计代码参考了两篇博主的,做了部分改动,添加了预处理函数等1 #include<iostream>2 #include<fstream>3 #include<cstdio>4 #include<cstring>5 #include<string>6 #include<cstdlib>78using namespace std;910int aa;// fseek的时候⽤来接着的11string word="";12string reserved_word[20];//保留13char buffer;//每次读进来的⼀个字符14int num=0;//每个单词中当前字符的位置15int line=1; //⾏数16int row=1; //列数,就是每⾏的第⼏个17bool flag; //⽂件是否结束了18int flag2;//单词的类型192021//预处理函数22int processor(){//预处理函数23 FILE *p;24int falg = 0,len,i=0,j=0;25char str[1000],str1[1000],c;26if((p=fopen("code.txt","rt"))==NULL){27 printf("⽆法打开要编译的源程序");28return0;29 }30else{31//fgets(str,1000,p);32while((c=getc(p))!=EOF){33 str[i++] = c;34 }35 fclose(p);36 str[i] = '\0';37for(i=0;i<strlen(str);i++){38if(str[i]=='/'&&str[i+1]=='/'){39while(str[i++]!='\n'){}40 }//单⾏注释41else if(str[i]=='/'&&str[i+1]=='*'){42while(!(str[i]=='*'&&str[i+1]=='/')){i++;}43 i+=2;44 }//多⾏注释45else if(str[i]==''&&str[i+1]==''){46while(str[i]==''){i++;}47 i--;48if(str1[j-1]!='')49 str1[j++]='';50 }//多个空格,去除空格51else if(str[i]=='\n') {52if(str1[j-1]!='')53 str1[j++]='';54 }//换⾏处理,55else if(str[i]==9){56while(str[i]==9){57 i++;58 }59if(str1[j-1]!='')60 str1[j++]='';61 i--;62 }//tab键处理63else str1[j++] = str[i];//其他字符处理64 }65 str1[j] = '\0';66if((p = fopen("afterdel.txt","w"))==NULL){ 67 printf("can not find it!");68return0;69 }70else{71if(fputs(str1,p)!=0){72 printf("预处理失败!");73 }74else printf("预处理成功!");75 }76 fclose(p);77 }78return0;79 }8081//设置保留字82void set_reserve()83 {84 reserved_word[1]="return";85 reserved_word[2]="def";86 reserved_word[3]="if";87 reserved_word[4]="else";88 reserved_word[5]="while";89 reserved_word[6]="return";90 reserved_word[7]="char";91 reserved_word[8]="for";92 reserved_word[9]="and";93 reserved_word[10]="or";94 reserved_word[11]="int";95 reserved_word[12]="bool";96 }9798//看这个字是不是字母99bool judge_word(char x)100 {101if(x>='a' && x<='z' || x>='A' && x<='Z' ){ 102return true;103 }104else return false;105 }106107//看这个字是不是数字108bool judge_number(char x)109 {110if(x>='0' && x<='9'){111return true;112 }113else return false;114 }115116//看这个字符是不是界符117bool judge_jiefu(char x)118 {119if(x=='('||x==')'||x==','||x==';'||x=='{'||x=='}'){ 120return true;121 }122else return false;123 }124125126//加减乘127bool judge_yunsuanfu1(char x)128 {129if(x=='+'||x=='-'||x=='*')130 {131return true;132 }133else return false;134 }135136//等于赋值,⼤于⼩于⼤于等于,⼩于等于,⼤于⼩于137bool judge_yunsuannfu2(char x)138 {139if(x=='='|| x=='>'||x=='<'||x=='&'||x=='||'){140return true;141 }142else return false;143 }144145146//这个最⼤的函数的总体作⽤是从⽂件⾥读⼀个单词147int scan(FILE *fp)148 {149 buffer=fgetc(fp);//读取⼀个字符150if(feof(fp)){//检测结束符151 flag=0;return0;152 }153else if(buffer=='')154 {155 row++;156return0;157 }158else if(buffer=='\n')159 {160 row=1;161return0;162 }163//如果是字母开头或'_' 看关键字还是普通单词164else if(judge_word(buffer) || buffer=='_')165 {166 word+=buffer;167 row++;168while((buffer=fgetc(fp)) && (judge_word(buffer) || judge_number(buffer) || buffer=='_'))169 {170 word+=buffer;171 row++;172 }173if(feof(fp)){174 flag=0;175return1;176 }177for(int i=1;i<=12;i++){178if(word==reserved_word[i]){179 aa=fseek(fp,-1,SEEK_CUR);//如果执⾏成功,stream将指向以fromwhere为基准,偏移offset(指针偏移量)个字节的位置,函数返回0。
《编译原理》科学实验指导说明书
《编译原理》实验指导书实验一词法分析器的设计一、实验目的和要求加深对状态转换图的实现及词法分析器的理解。
熟悉词法分析器的主要算法及实现过程。
要求学生掌握词法分析器的设计过程,并实现词法分析。
二、实验基本内容给出一个简单语言的词法规则,画出状态转换图,并依据状态转换图编制出词法分析程序,能从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单Error”,然后跳过错误部分继续显示)词法规则如下:三、实验时间:上机三次。
第一次按照自己的思路设计一个程序。
第二、三次在理论课学习后修改程序,使得程序结构更加合理。
四、实验过程和指导:(一)准备:1.阅读课本有关章节(c/c++,数据结构),花一周时间明确语言的语法,写出基本算法以及采用的数据结构和要测试的程序例。
2.初步编制好程序。
3.准备好多组测试数据。
(二)上课上机:将源代码拷贝到机上调试,发现错误,再修改完善。
(三)程序要求:程序输入/输出示例:输入如下一段:main(){/*一个简单的c++程序*/int a,b; //定义变量a = 10;b = a + 20;}要求输出如右图。
要求:(1) 剔除注解符(2) 常数为无符号整数(可增加实型数,字符型数等)(四)练习该实验的目的和思路:程序开始变得复杂起来,可能是大家以前编过的程序中最复杂的,但相对于以后的程序来说还是简单的。
因此要认真把握这个过渡期的练习。
程序规模大概为200行及以上。
通过练习,掌握对字符进行灵活处理的方法。
(五)为了能设计好程序,注意以下事情:1.模块设计:将程序分成合理的多个模块(函数/类),每个模块(类)做具体的同一事情。
2.写出(画出)设计方案:模块关系简图、流程图、全局变量、函数接口等。
3.编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。
4.程序设计语言不限,建议使用面向对象技术及可视化编程语言,如C++,VC,JA V A,VJ++等。
编译原理_实验一_词法分析
实习一词法分析一、实验目的:根据活动状态转换图,设计并实现一个具体的C语言的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编写一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)。
二、实验过程1.活动状态转化图2.设计思路本C语言词法分析器使用JAVA语言编写。
(1)C语言词法分析●关键字将C语言32关键字"auto", "double", "int", "struct", "break","else","long", "switch", "case", "enum", "register", "typedef","char", " extern", "return", "union", "const", "float", "short"," unsigned", "continue", "for", "signed", "void","default", "goto","sizeof", "volatile", "do", "if", "while", "static"存储在keyword[]字符串数组中;●专用符号= + -* / <=>>= == != ;:, { } [ ] ( )将读入的字符与ASCLL表进行比较判断;对于像“==”,“<=”等字符进行超前搜索;●空格和空白、制表符和换行符。
计算机编译原理---词法分析器实验报告
编译原理实验报告书词法分析器目录1、摘要: (2)2、实验目的: (2)3、任务概述 (3)4、实验依据的原理 (3)5、程序设计思想 (5)6、实验结果分析 (7)7、总结 (9)1、摘要:本实验用C/C++高级语言编写词法分析程序,通过课堂上对词法分析器相关的背景知识的足够了解,清晰词法分析的过程,在脑海中形成词法分析的一般方案,根据方案一步步所要实现的目的,形成对词法分析器程序的模块划分和整体规划,最终实现一个词法分析器。
具体要求能够通过扫描源程序分析出单词符号,将相应字符流转换成内码。
2、实验目的:通过设计、调试词法分析程序,实现从源程序中分出各种单词的方法;熟悉词法分析程序所用的工具自动机,进一步理解自动机理论。
掌握文法转换成自动机的技术及有穷自动机实现的方法。
确定词法分析器的输出形式及标识符与关键字的区分方法。
加深对课堂教学的理解;提高词法分析方法的时间能力。
通过本实验,掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法以及掌握词法分析的实现方法,并可以成功的上机调试编出词法分析程序。
3、任务概述用C/C++实现对Pascal的子集程序设计语言的词法识别程序。
词法分析程序的主要工作为:(1)从源程序文件中读入字符。
(2)统计行数和列数用于错误单词的定位。
(3)删除空格类字符,包括回车、制表符空格。
(4)按拼写单词,并用(内码,属性)二元式表示。
(5)根据需要是否填写标识符表供以后各阶段使用。
4、实验依据的原理(1)词法分析器工作流程图图1 词法分析器工作流程图实现流程:从左至右逐个字符地对源程序进行扫描,产生一个个的单词符号,把作为字符串的源程序改造成为单词符号串的中间程序。
词法分析的功能是输入源程序,输出单词符号。
所依据的理论基础有有限自动机、正规式、正规文法。
(2)词法分析器的功能是输入源程序,输出单词符号,单词符号是一个程序语言的基本语法符号,一般分为五种:关键字、标识符、常数、运算符、界符五大类。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
41
-
16
数字
42
-=
17
标识符
43
--
18
,
44
&
19
//
45
&&
20
/**/
46
#
21
*
22
*=
23
/
24
/=
25
3.状态转换图
4.算法分析
①词法分析器工作的第一步是输入源程序文本。为了更好地对单词符号识别,把输入串预处理一下。预处理主要滤掉空格,跳过注释、换行符等。
②对预处理后的输入串依次扫描单个字符,使用if-while嵌套语句和switch case语句判断字符的类型,具体识别方法可看状态转换图。有时为了确定词性,需要超前扫描,若超前扫描的字符对识别当前单词无用处,则需要退还给输入串,以备识别下一单词字符时使用。
③若读入的字符与单词符号编码表的字符匹配不上,则报错,并输出出错行数。对识别处的单词符号以(单词符号,种别码)二元式的形式输出。
3.实验容
1.流程图
2.程序的变量与函数说明
(1)input
全局字符数组,用来存放输入串
(2)word
全局字符数组,用来存放获取到的单词符号,限定长度为8
(3)ch
全局字符变量,用来存放最新读入的字符
南华大学
计算机科学与技术学院
实 验 报 告
( 2018~2019学年度 第二学期 )
课程名称
编译原理
实验名称
词法分析器的设计与实现
学号
专业
班级
地点
教师
1.实验目的及要求
实验目的
加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。
2.单词符号的编码
单词符号
种别码
单词符号
种别码
main
0
>
26
if
1
>=
27
else
2
<
28
while
3
<=
29
do
4
!
30
for
5
!=
31
switch
6
=
32
case
7
==
33
int
8
(
34
double
9
)
35
float
10
{
36
long
11
}
37
void
12
;
38
+13ຫໍສະໝຸດ :39+=
14
|
40
++
15
{
return 1;
}
return 0;
}
void main()
{
init();//输入字符串
line=0;
p=0;
do{
scaner();
switch(syn)
{
case -1:
printf("you have input a wrong string in line %d\n",line);
break;
(4)syn
全局整型变量,表示单词符号的编码
(5)p
全局整型变量,表示当前字符在input数组的位置
(6)m
全局整型变量,表示最新读入的字符在word数组的下标
(7)line
全局整型变量,当前行数
(8)keyword
全局字符数组,存放关键字
(9)init()
获取输入串
(10)isKey()
判断关键字的函数,若参数数组中是关键字,则把syn置为该关键字对应的编码并返回1,否则返回0
return 1;
else
return 0;
}
//判断是不是字母
int isLetter(char c)
{
if ((c<='z'&&c>='a')||(c>='A'&&c<='Z'))
return 1;
else
return 0;
}
int isSpace(char c)
{
if (c==' '||c=='\t'||c=='\n')
void scaner(void);
//获取输入串
void init()
{
int i=0;
printf("\n please input a string(end with '#'):\n");
do{
scanf("%c",&ch);
input[i++]=ch;
}while(ch!='#');
}
//判断是不是关键字
实验要求
1.对单词的构词规则有明确的定义;
2.编写的分析程序能够正确识别源程序中的单词符号;
3.识别出的单词以<种别码,值>的形式保存在符号表中,正确设计和维护符号表;
4.对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成整个源程序的词法分析;
2.实验步骤
1.词法分析规则
3.源程序
#include <stdio.h>
#include <string.h>
char input[1000];//输入串
char word[8];//获取到的单词
char ch;
int syn;//种别码
int p;
int m;
int line;//行数
//关键字
char keyword[][8]={"main","if","else","while","do","for","switch","case","int","double","float","long","void"};
(11)isLetter()
判断字母的函数,若参数字符是字母,则返回1,否则返回0
(12)isDigit()
判断数字的函数,若参数字符是数字,则返回1,否则返回0
(13)isSpace()
判断空白符的函数,若参数字符是空格、TAB或换行符,则返回1,否则返回0
(14)scaner()
扫描输入串的函数,对读出的字符进行判断,若是单词符号表中的符号,则将syn置为对应的编码
<标识符>::=<字母>|<标识符><字母>|<标识符><数字>
<常数>::=<数字>|<数字序列><数字>
<数字序列>::=<数字序列><数字>|<数字>|<.>
<字母>::=a|b|c|……|x|y|z
<数字>::=0|1|2|3|4|5|6|7|8|9
<运算符>::=<关系运算符>|<算术运算符>|<逻辑运算符>|<位运算符>|<赋值运算符>
int isKey(char *str)
{
int n;
for(n=0;n<13;n++)
{
if(strcmp(str,keyword[n])==0)
{
syn=n;
return 1;
}
}
return 0;
}
//判断是不是数字
int isDigit(char c)
{
if (c>='0'&&c<='9')
<算数运算符>::=+|-|*|/|...|--
<关系运算符>::=<|>|!=|>=|<=|==
<逻辑运算符>::=&&| || |!
<位运算符>::=&| | |!
<赋值运算符>::==|+=|-=|/=|*=
<分界符>::=,|;|(|)|{|}|:| // |/**/
<保留字>::=main|if|else|while|do|for|...|void