东南大学编译原理词法分析器实验报告

合集下载

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

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

编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的: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)关键字:"begin","end","if","then","else","while","write","read", "do", "call","const","char","until","procedure","repeat"(2)运算符:"+","-","*","/","="(3)界符:"{","}","[","]",";",",",".","(",")",":"(4)其他标记如字符串,表示以字母开头的标识符(5)空格、回车、换行符跳过(6)运行结果在屏幕上以如下格式显示:1 $无符号整数begin $关键字if $关键字+ $运算符;$界符a $普通标识符//“$“为美元符号,不是大写字母S测试功能时,可以多次设置包含不同字符,关键字的待解析文件,但要保证输入文件和后缀名时准确无误,仔细察看运行结果,检测该分析器的分析结果是否正确四、源代码:#include <iostream>#include<string>using namespace std;#define MAX 22char ch =' ';string key[15]={"begin","end","if","then","else","while","write","read","do", "call","const","char","until","procedure","repeat"};int Iskey(string c){ //关键字判断int i;for(i=0;i<MAX;i++) {if(key[i].compare(c)==0) return 1;}return 0;}int IsLetter(char c) { //判断是否为字母if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))) return 1;else return 0;}int IsDigit(char c){ //判断是否为数字if(c>='0'&&c<='9') return 1;else return 0;}void analyse(FILE *fpin){string arr="";while((ch=fgetc(fpin))!=EOF) {arr="";if(ch==' '||ch=='\t'||ch=='\n'){}else if(IsLetter(ch)){while(IsLetter(ch)||IsDigit(ch)) {if((ch<='Z')&&(ch>='A')) ch=ch+32;arr=arr+ch;ch=fgetc(fpin);}fseek(fpin,-1L,SEEK_CUR);if (Iskey(arr)){cout<<arr<<"\t$关键字"<<endl;}else cout<<arr<<"\t$普通标识符"<<endl;}else if(IsDigit(ch)){while(IsDigit(ch)||ch=='.'&&IsDigit(fgetc(fpin))){arr=arr+ch;ch=fgetc(fpin);}fseek(fpin,-1L,SEEK_CUR);cout<<arr<<"\t$无符号实数"<<endl;}else switch(ch){case'+':case'-' :case'*' :case'=' :case'/' :cout<<ch<<"\t$运算符"<<endl;break;case'(' :case')' :case'[' :case']' :case';' :case'.' :case',' :case'{' :case'}' :cout<<ch<<"\t$界符"<<endl;break;case':' :{ch=fgetc(fpin);if(ch=='=') cout<<":="<<"\t$运算符"<<endl;else {cout<<"="<<"\t$运算符"<<endl;;fseek(fpin,-1L,SEEK_CUR);}}break;case'>' :{ch=fgetc(fpin);if(ch=='=') cout<<">="<<"\t$运算符"<<endl;if(ch=='>')cout<<">>"<<"\t$输入控制符"<<endl;else {cout<<">"<<"\t$运算符"<<endl;fseek(fpin,-1L,SEEK_CUR);}}break;case'<' :{ch=fgetc(fpin);if(ch=='=')cout<<"<="<<"\t$运算符"<<endl;else if(ch=='<')cout<<"<<"<<"\t$输出控制符"<<endl;else if(ch=='>') cout<<"<>"<<"\t$运算符"<<endl;else{cout<<"<"<<"\t$运算符"<<endl;fseek(fpin,-1L,SEEK_CUR);}}break;default : cout<<ch<<"\t$无法识别字符"<<endl;}}}void main(){char in_fn[30];FILE * fpin;cout<<"请输入源文件名(包括路径和后缀名):";for(;;){cin>>in_fn;if((fpin=fopen(in_fn,"r"))!=NULL) break;else cout<<"文件路径错误!请输入源文件名(包括路径和后缀名):";}cout<<"\n********************分析如下*********************"<<endl;analyse(fpin);fclose(fpin);cout<<endl;cout<<"按任意键结束"<<endl;int a;cin>>a;}运行结果截图:输入:输出:生成的单词表目标文件:。

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

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

编译原理实验报告实验名称:编写词法分析程序实验类型:设计性实验指导教师:*****专业班级:软件工程1401姓名:****学号:**********实验地点:东六E座301实验成绩:_________________日期:2016 年5 月8 日实验一编写词法分析程序一、实验目的1.通过设计、调试词法分析程序,掌握词法分析程序的设计工具(有穷自动机),进一步理解自动机理论2.掌握正则文法和正则表达式转换成有穷自动机的方法及有穷自动机实现的方法3.确定词法分析程序的输出形式及标识符与关键字的区分方法4.加深对理论知识的理解二、实验设计1.设计原理:对源程序代码从头到尾扫描,将符合词法语言规则的单词输出,包括:标识符、保留字、无符号整数、分界符、运算符、注释分离;判断程序的词法是否正确TEST语言的词法规则如下:1)、标识符:字母打头,后接任意字母或数字。

2)、保留字:标识符的子集,包括:if,else,for,while,do, int,write,read。

3)、无符号整数:由数字组成,但最高位不能为0,允许一位的0。

4)、分界符:(、)、;、{、}5)、运算符:+、-、*、/、=、<、>、>=、<=、!=、==6)、注释符:/* */2.设计方法:1)用正则表达式或正则文法描述程序设计语言的词法规则,通常采用正则表达式;一个正则表达式对应一条词法规则2)为每个正则表达式构造一个NFA,用来识别正则表达式描述的单词将每一个NFA合并、化简得到最简的DFA3)将多个NFA合并为一个NFA4)将NFA转换成等价的DFA。

5)最小化DFA6)确定单词的输出形式。

7)化简后的DFA+单词输出形式⇒构造词法分析程序3.设计过程:1)将TEST语言的六个语法规则分别转换成正则表达式2)为每个正则表达式构造一个NFA,用来识别正则表达式描述的单词3)将5个NFA转换成一个NFA,再将NFA化简确定化。

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

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

编译原理词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

二、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。

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

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

2.2 各种单词符号对应的种别码:2.3 词法分析程序的功能:输入:所给文法的源程序字符串。

输出:二元组(syn,token或sum)构成的序列。

其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。

例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的C语言程序源代码:#include <stdio.h>#include <string.h>char prog[80],token[8],ch;int syn,p,m,n,sum;char *rwtab[6]={"begin","if","then","while","do","end"};scaner();void scanner_example (FILE *fp);main(){FILE *fp;fp=fopen("D:\\1.txt","r");//打开文件scanner_example (fp);scaner();}void scanner_example (FILE *fp){do{ch=fgetc (fp);prog[p++]=ch;}while (ch!='#');p=0;do{scaner();switch(syn){case 11:printf("( %-10d%5d )\n",sum,syn);break;case -1:printf("you have input a wrong string\n");default: printf("( %-10s%5d )\n",token,syn);break;}}while(syn!=0);}scaner(){ sum=0;for(m=0;m<8;m++)token[m++]=NULL;ch=prog[p++];m=0;while((ch==' ')||(ch=='\n'))ch=prog[p++];if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))){ while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) {token[m++]=ch;ch=prog[p++];}p--;syn=10;for(n=0;n<6;n++)if(strcmp(token,rwtab[n])==0){ syn=n+1;break;}}else if((ch>='0')&&(ch<='9')){ while((ch>='0')&&(ch<='9')){ sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=11;}else switch(ch){ case '<':token[m++]=ch;ch=prog[p++];if(ch=='='){ syn=22;token[m++]=ch;}else{ syn=20;p--;}break;case '>':token[m++]=ch;ch=prog[p++];if(ch=='='){ syn=24;token[m++]=ch;}else{ syn=23;p--;}break;case '+': token[m++]=ch;ch=prog[p++];if(ch=='+'){ syn=17;token[m++]=ch;}else{ syn=13;p--;}break;case '-':token[m++]=ch;ch=prog[p++];if(ch=='-'){ syn=29;token[m++]=ch;}else{ syn=14;p--;}break;case '!':ch=prog[p++];if(ch=='='){ syn=21;token[m++]=ch;}else{ syn=31;p--;}break;case '=':token[m++]=ch;ch=prog[p++];if(ch=='='){ syn=25;token[m++]=ch;}else{ syn=18;p--;}break;case '*': syn=15;token[m++]=ch;break;case '/': syn=16;token[m++]=ch;break;case '(': syn=27;token[m++]=ch;break;case ')': syn=28;token[m++]=ch;break;case '{': syn=5;token[m++]=ch;break;case '}': syn=6;token[m++]=ch;break;case ';': syn=26;token[m++]=ch;break;case '\"': syn=30;token[m++]=ch;break;case '#': syn=0;token[m++]=ch;break;case ':':syn=17;token[m++]=ch;break;default: syn=-1;break;}token[m++]='\0';}四、结果分析:输入begin x:=9: if x>9 then x:=2*x+1/3; end # 后经词法分析输出如下序列:(begin 1)(x 10)(:17)(= 18)(9 11)(;26)(if 2)……如图所示:五、总结:词法分析的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

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

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

编译原理词法分析实验报告实验一词法分析一、实验目的通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。

并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。

编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。

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

二、实验内容(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数组中存放的字符,判断分离出关键字、标示符、数字、运算符、标示符。

编译原理实验整体(2)词法分析器实验报告

编译原理实验整体(2)词法分析器实验报告
{
int index = stIndexOf("//");
String tmpstr=line.substring(index);
int tmpint = tmpstr.length();
for(int k=0;k<tmpint;k++)
{
i++;
}
token = tmpstr;
{"if",6,"IF"}, {"int",7,"INT"}, {"return",8,"RETURN"},
{"void",9,"VOID"}, {"while",10,"WHILE"},
{"printf",41,"OUTPUT"}, {"scanf",42,"INPUT"},
{"main",43,"MAIN"}, {"function",44,"function"}
if (ch == '\0') {
haveMistake = true;
break;
}
for (int k = 0; k < 4; k++) {
char tmpstr[] = stConDFA[s].toCharArray();
if (in_stConDFA(ch, tmpstr[k])) {
token1 += ch;
理论基础:有限自动机、正规文法
词法分析器:执行词法分析的程序

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

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

一、实验目的设计一个简单的词法分析器,从而进一步加深对词法分析器工作原理的明白得。

二、实验要求一、该个词法分析器要求至少能够识别以下几类单词:(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)。

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

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

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

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

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

(遇到错误时可显示“Error!”,然后跳过错误部分继续进行)设计思想:设计该词法分析器的过程中虽然没有实际将所有的状态转移表建立出来,但是所用的思想是根据状态转移表实现对单词的识别。

首先构造一个保留字表,然后,每输入一个字符就检测应该进入什么状态,并将该字符连接到d串后继续输入,如此循环,最后根据所在的接受状态以及保留字表识别单词。

符号表:记号类别属性值ws - -const 保留字 1var 保留字 1call 保留字 1begin 保留字 1if 保留字 1while 保留字 1do 保留字 1odd 保留字 1end 保留字 1then 保留字 1procedure 保留字 1= 运算符 2< 运算符 2<= 运算符 2<> 运算符 2> 运算符 2>= 运算符 2* 运算符 2+ 运算符 2- 运算符 2/ 运算符 2:= 运算符 2ident 标识符 3number 常数 4 ( 分隔符 5) 分隔符 5; 分隔符 5, 分隔符 5. 分隔符 5状态转换图:①标识符及保留字:letter or digittStart letter②number:③关系操作符:0 21 435startdigit.digit E+ | -digitdigitdigitdigitEdigit otherother④分隔符:start< other =(<=, 2) >= other>=* * (<>, 2)(<,2)(=, 2)(>=, 2)(>, 2):=(:=,2)⑤算术运算符:使用环境:Windows xp 下的visual c++6.0程序测试: input1 : int a,b;start;( ),.( ; ,5)( (,5)( ),5) ( , ,5)( . ,5)start+- * /( + ,2) ( -,2)( *,2) ( / ,2). a=b+2;input2:while(a>=0)do7x=x+6.7E+23;end;input3:begin:x:=9if x>0 then x:=x+1;while a:=0 dob:=2*x/3,c:=a;end;output1: 3,int 3,a 5,,3,b 5,;3,a2,=3,b2,+4,2 5,; output2:output2:1,while5,(3,a2,>=4,05,)1,doerror line 32,=3,x2,+4,6.7E+235,;1,end5,;output3:output3:1,beginerror line 13,x2,:=4,91,if3,x2,>4,01,then3,x2,:=3,x2,+4,15,;1,while3,a2,:=4,01,do 3,b 2,:= 4,2 2,* 3,x 2,/4,35,,3,c2,:=3,a5,;1,end5,;测试结果与预期结果一致源程序代码:#include<stdio.h>#include<string.h>void main(){int i=0,j,k=0,state=1,f=0,linenum=1;chara[11][10]={"const","var","call","begin","if","while","do","odd","end","then","proc edure"};char b,d[40]={"\0"};freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);b=getchar();while(b!=EOF)/*判断所输入字符是否为结束符*/{if(b==' '||b=='\n'||b=='\t')/*滤过空格、换行等分隔符号*/{ if(b='\n') linenum++;b=getchar();}else if((b>='a'&&b<='z')||(b>='A'&&b<='Z'))/*识别标识符以及保留字*/{d[i++]=b;b=getchar();while((b>='a'&&b<='z')||(b>='A'&&b<='Z')||(b>='0'&&b<='9')){d[i++]=b;b=getchar();}for(j=0;j<11;j++)/*查询保留字表确定该单词是否是保留字*/{ if(strcmp(d,a[j])==0){ printf("1,%s\n",d);k=1;break;}}if(k==0)/*在保留字表中没有查到该单词,是标识符*/printf("3,%s\n",d);for(j=0;j<=i;j++)d[j]='\0';i=0;k=0;}else if(b>='0'&&b<='9')/*识别常数*/{ d[i++]=b;b=getchar();while(f!=1){switch (state) {case 1:if(b>='0'&&b<='9') {state=1;d[i++]=b;b=getchar();}else if(b=='.') { state=2;d[i++]=b;b=getchar();}else if(b=='E') { state=4;d[i++]=b;b=getchar();}else state=7;break;case 2:if(b>='0'&&b<='9') {state=3;d[i++]=b;b=getchar();}else state=8;break;case 3:if(b>='0'&&b<='9') {state=3;d[i++]=b;b=getchar();}else if(b=='E') { state=4;d[i++]=b;b=getchar();}else state=7;break;case 4:if(b=='+'||b=='-') { state=5;d[i++]=b;b=getchar();}else if(b>='0'&&b<='9'){ state=6;d[i++]=b;b=getchar();} else state=8;break;case 5:if(b>='0'&&b<='9'){ state=6;d[i++]=b;b=getchar();}else state=8;break;case 6:if(b>='0'&&b<='9'){ state=6;d[i++]=b;b=getchar();}else state=7;break;case 7: f=1;break;case 8: f=1;break;}}if(state==7&&(b<'a'||b>'z')&&(b<'A'||b>'Z'))printf("4,%s\n",d);else if(state==7&&(b>='a'&&b<='z')||(b>='A'&&b<='Z'))/*数字后接字母的出错控制*/{while((b>='a'&&b<='z')||(b>='A'&&b<='Z')){ d[i++]=b;b=getchar();}printf("error line %d\n",linenum);}else printf("error line %d\n",linenum);for(j=0;j<=i;j++)d[j]='\0';i=0;f=0;state=1;}else if(b=='<')/*识别'<'、'<='和'<>'*/{ d[i++]=b;b=getchar();if(b=='='||b=='>'){ d[i++]=b;b=getchar();printf("2,%s\n",d);for(j=0;j<=i;j++)d[j]='\0';i=0;}else{ printf("2,%s\n",d);for(j=0;j<=i;j++)d[j]='\0';i=0;}}else if(b=='>')/*识别'>'和'>='*/{ d[i++]=b;b=getchar();if(b=='='){ d[i++]=b;b=getchar();printf("2,%s\n",d);for(j=0;j<=i;j++)d[j]='\0';i=0;}else{ printf("2,%s\n",d);for(j=0;j<=i;j++)d[j]='\0';i=0;}}else if(b==':')/*识别':='*/{ d[i++]=b;b=getchar();if(b=='='){ d[i++]=b;b=getchar();printf("2,%s\n",d);}else printf("error line %d\n",linenum);for(j=0;j<=i;j++)d[j]='\0';i=0;}else if(b=='*'||b=='+'||b=='-'||b=='/'||b=='=')/*识别运算符*/{ printf("2,%c\n",b);b=getchar();}else if(b=='('||b==')'||b==','||b==';'||b=='.')/*识别分隔符*/{ printf("5,%c\n",b);b=getchar();}else{ printf("error line %d\n",linenum);b=getchar();}}}实验心得:此次实验让我了解了如何设计、编制并调试词法分析程序,并加深了我对词法分析器原理的理解;熟悉了直接构造词法分析器的方法和相关原理,并学会使用c语言直接编写词法分析器;同时更熟练的掌握用c语言编写程序,实现一定的实际功能。

编译原理词法分析报告

编译原理词法分析报告

实验一:词法分析一、实验目的:1、通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。

并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。

2、编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本关键字、标识符、常数、运算符、分隔符五大类。

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

(遇到错误时可显示“Error”,然后跳过错误部分继续显示)二、实验预习提示1、词法分析器的功能和输出格式词法分析器的功能是输入源程序,输出单词符号。

词法分析器的单词符号常常表示成以下的二元式(单词种别码,单词符号的属性值)。

本实验中,采用的是一类符号一种别码的方式。

2、单词的BNF表示<标识符>-> <字母><字母数字串><字母数字串>-><字母><字母数字串>|<数字><字母数字串>|<下划线><字母数字串>|ε<无符号整数>-> <数字><数字串><数字串>-> <数字><数字串> |ε<加法运算符>-> +<减法运算符>->-<大于关系运算符>->><大于等于关系运算符>-> >=3、“超前搜索”方法词法分析时,常常会用到超前搜索方法。

如当前待分析字符串为“a>+”,当前字符为’>’,此时,分析器到底是将其分析为大于关系运算符还是大于等于关系运算符呢?显然,只有知道下一个字符是什么才能下结论。

于是分析器读入下一个字符’+’,这时可知应将’>’解释为大于运算符。

但此时,超前读了一个字符’+’,所以要回退一个字符,词法分析器才能正常运行。

在分析标识符,无符号整数等时也有类似情况。

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

编译原理词法分析器语法分析器实验报告
}
void analyse(char Vn[],char Vt[])
{
int i,j,m,p,q,length,t,h;
char w,X;
char str[100];
opt0:
scanf("%s",str);
for(i=0;i<strlen(str);i++)
{
if(!find(str[i],Vt))
getchar();
}
}
opt3:
printf("请输入要分析的字符串,且以#结束:\n");
analyse(Vn, Vt);
printf("********************请选择***********************\n");
printf(" 1:输入字符串\n");
printf(" 2:输入新分析表\n");
{
printf("%c",str[t]); //显示剩余字符串
}
if(find(X,Vt)&& X!='#') //分析栈的栈顶元素和剩余输入串的第一个元素相比较
{
if(X==w)
{
printf("%15c匹配\n",X);
j++;
w=str[j];
goto opt1;
}
else
error();
}
else
sum=0;
while((ch>='0'&&ch<='9'))
{
sum=sum*10+ch-'0';

编译原理实验报告(词法分析器语法分析器)

编译原理实验报告(词法分析器语法分析器)

编译原理实验报告实验一一、实验名称:词法分析器的设计二、实验目的:1,词法分析器能够识别简单语言的单词符号2,识别出并输出简单语言的基本字.标示符.无符号整数.运算符.和界符。

三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

2、程序流程图(1)主程序(2)扫描子程序3、各种单词符号对应的种别码五、实验容: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语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术。

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

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

编译原理实验—词法分析器一、实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。

同时增强编写和调试程序的能力。

二、实验内容及要求对某特定语言A ,构造其词法规则。

该语言的单词符号包括:保留字(见左下表)、标识符(字母大小写不敏感)、整型常数、界符及运算符(见右下表) 。

功能要求如下所示:·按单词符号出现的顺序,返回二元组序列,并输出。

·出现的标识符存放在标识符表,整型常数存放在常数表,并输出这两个表格。

·如果出现词法错误,报出:错误类型,位置(行,列)。

·处理段注释(/* */),行注释(//)。

·有段注释时仍可以正确指出词法错误位置(行,列)。

三、实验过程1、词法形式化描述使用正则文法进行描述,则可以得到如下的正规式:其中ID表示标识符,NUM表示整型常量,RES表示保留字,DEL表示界符,OPR表示运算符。

A→(ID | NUM | RES | DEL | OPR) *ID→letter(letter | didit)*NUM→digit digit*letter→a | … | z | A | … | Zdigit→ 0 | … | 9RES→ program | begin | end | var | int | and | or | not | if | then | else | while | doDEL→( | ) | . | ; | ,OPR→+ | * | := | > | < | = | >= | <= | <>如果关键字、标识符和常数之间没有确定的算符或界符作间隔,则至少用一个空格作间隔。

空格由空白、制表符和换行符组成。

2、单词种别定义;A语言中的单词符号及其对应的种别编码如下表所示:单词符号种别编码单词符号种别编码3、状态转换图;语言A的词法分析的状态转换图如下所示:空格符,制表符或回车符字母或数字4、java旗舰版5、关键算法的流程图及文字解释;程序中用到的函数列表:A类定义各种类函数以及包含主函数public static void main()变量ch储存当前最新读进的字符的地址strToken存放当前字符串main() //主函数Analysis()//分析函数,每次读入一行文件,进行识别处理;char GetChar(); //取得当前位置的字符的内容放入ch,并提前指向下一个字符;char GetNextChar();//取得当前位置的下一位置的字符,String ConCat(); //将ch指向的字符连接到strToken后面isLetter(); //判断ch指向的字符是否字母isDigit(); //判断ch指向的字符是否数字add(p,str); //向p表中插入当前strToken的字符串Boolean findKeyWord(str); //检测当前strToken中的字符串是否保留字,若是,则执行getKeyWordKey(str),返回保留字的id,否则,判别其是否是已存在的标示符,若是,返回标示符的id以及该标示符在表中的位置;findPunctuation()//判断是否是一个保留的符号;getindex() //返回已经识别的标示符或者是数字的位置下标;Boolean exist(); //检测当前strToken中的字符串是否在标识符表中已存在,若是,则返回true,否则返回falsevoid callError(); //出错处理过程,将错误的位置报告出来(1)main()函数的流程图如下:)具体分析流程图:开始类初始化,变量的初始化,准备执行main()函数调用Analyse()函数分析输出结果表结束Analyse(str)函数读取第一个字符赋给变量Ch继续判读IndexoutofBound6、测试报告(测试用例,测试结果);首先输入一个不含错误的程序(两种注释)进行检测:运行后在控制台上得到的结果如下所示:得到的二元组序列如下:经检验,输出的是正确的二元组序列。

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

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

实验LEX词法分析器自动生成器一、实验内容:用词法分析自动生成器LEX构造一个简单词法分析器,它能识别文件新行并为其添加行号,并将分析结果发送到屏幕上。

二、实验目的:1.掌握LEX源程序的编写方法。

2.掌握自动生成词法分析器LEX的使用方法和工作原理。

LEX源程序*.L通过LEX编译程序,产生一个C语言版本的词法分析程序*.C。

然后通过C语言编译器,将词法分析程序*.C转换成一个可执行文件*.EXE。

再编制一个测试文本文件*.TXT。

用生成的词法分析程序的可执行文件,对测试程序进行词法分析.三、实验要求1.写好实验预习报告;2.编写上机源程序和测试程序;3.写出实验结果;4.实验完后要上交实验报告;四、相关说明LEX上机过程部分:1)利用编辑器如EDIT编写LEX源程序和测试程序,如SHIYAN11.L和TEST.TXT;2)用LEX编译器编译LEX源程序SHIYAN11.L,格式为:LEX SHIYAN11.L↙如果LEX源程序没有语法错误,将得到一个用C语言描述的没有语法错误词法分析器SHIYAN11.C;3)在TC环境下,对SHIYAN11.C进行编译、连接,从而得到可执行的词法分析器SHIYAN11.EXE;4)利用SHIYAN11.EXE对TEST.TXT进行词法分析,格式为:SHIYAN0.EXE<TEST.TXT↙如果没有写测试程序TEST.TXT,则可测试其他某个程序如SHIYAN11.L。

LEX上机过程如下图所示(alt+c):五、实验器材硬件:PC机一台软件:Turbo C、LEX.EXE六、参考程序1.LEX源程序:shiyan11.L%{#include "stdio.h"int lineno=1;()%}line .*\n%%{line} {printf("%2d %s",lineno++,yytext);}%%main(){yylex();return 0;}2.shiyan11.EXE分析shiyan11.L的实验效果如下图所示:。

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

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

编译原理词法分析器实验报告1. 引言编译原理是计算机科学中的重要概念,它涉及将高级语言程序转换为计算机可执行的低级指令。

词法分析是编译过程中的第一个阶段,它负责将源代码分解为词法单元,为后续的语法分析做准备。

本实验旨在设计和实现一个基本的词法分析器,以了解词法分析的原理和实际应用。

2. 实验目标本实验的主要目标是实现一个基本的词法分析器,能够识别并提取源代码中的各种词法单元。

具体而言,我们将设计一个针对某种编程语言的词法分析器,能够识别关键字、标识符、算术运算符、括号、常量等。

3. 实验环境为了完成本实验,我们需要使用以下工具和环境:•一种编程语言,例如Python、Java或C++•一个文本编辑器,例如Visual Studio Code或Sublime Text•一个命令行终端4. 实验步骤4.1 定义词法规则首先,我们需要定义词法分析器的词法规则。

这些规则描述了编程语言中各种词法单元的模式。

例如,关键字可以被定义为由特定字符组成的字符串,标识符可以被定义为以字母开头并由字母和数字组成的字符串。

4.2 实现词法分析器接下来,我们将根据定义的词法规则,使用编程语言实现一个词法分析器。

在实现过程中,我们可以使用正则表达式来匹配和提取各种词法单元。

4.3 编写测试用例完成词法分析器的实现后,我们需要编写一些测试用例来验证其正确性。

测试用例应该包含各种可能的输入情况,以确保词法分析器能够正确地识别和提取词法单元。

4.4 运行测试用例最后,我们将使用编写的测试用例来运行词法分析器,并检查输出是否符合预期。

如果测试通过,说明词法分析器能够正常工作;否则,我们需要检查代码并进行调试。

5. 实验结果经过实验,我们成功地设计并实现了一个基本的词法分析器。

该词法分析器能够按照预定义的词法规则,正确地识别和提取源代码中的各种词法单元。

在运行测试用例时,词法分析器能够产生符合预期的输出,表明其具有良好的准确性和可靠性。

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

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

编译原理_词法分析器实验报告一.实验题目和要求。

题目:设计PL / 0语言的词法分析器。

要求:单词(关键字);begin end if then else while write read docall const var procedure repeat until运算符:+ - * / := = <>(#) < <= > >=界符:, . ; ( )标识符:字母打头的字母数字串,长度不超过10.常数:整数,所含数字的个数不超过14.返回单词形式:二元式(种别,属性值)二.实验平台。

PC机: Windows XP操作系统编程环境: Turbo C 2.0编程语言: C语言三.实验算法说明。

定义2个全局变量char ch和char strtoken分别用来存放最新读入的源程序字符和构成单词符号的字符串。

然后用各个子函数的功能和读文件内容的操作,实现对源程序的词法分析,分别进行关键字,标识符,常数,运算符和界符的分析确认,然后将对应的二元式结果输出。

首先用户输入要读文件的名称,然后程序会把文件的内容读到定义的够大的字符数组str(相当于词法分析的一个缓冲区)里,然后开始从str里一个一个的读出字符并放在专门用来暂时存放单词数组strtoken里进行词法分析,若符合语言的规则,则打印出相关的说明信息,即该字符或字符串的二元式信息,可以清楚的明白该字符的种别和属性值。

如果读入的字符或字符串是非法的,即不是语法规定或是没有意义的字符或字符串,程序会提示相关的错误信息并进行一定四.程序子函数功能说明。

1.void getChar( ) 将下一个输入字符读到ch中,搜索指示器前移一个字符的位置。

2. void getBc( ) 检查ch中的字符是否为空白,若是,则调用getChar( ),直到ch中进入一个非空的字符。

3.void retract( ) 将搜索指示器回调一个字符位置,将ch置为空白字符。

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

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

编译原理实验报告姓名:关海超学号:200807010209专业:计算机科学与技术班级:08—02班一、实验目的通过设计调试词法分析程序,实现从源程序中分出各种单词的方法;加深对课堂教学的理解;提高词法分析方法的实践能力。

二、词法分析器的实现1、词法分析过程的考虑词法分析器的任务是将程序源代码看做一个字符串,只需从中分离出一个个具有独立意义的单词(包括标识符,符号和常量)即可,而无需考虑其在上下文环境中的正确性。

基于此认识,词法分析的过程可如下描述:本程序中用户源程序存储在文件“E:\prog.txt”文件中,程序首先调用readFromFile()函数将源程序代码从文件中读出,放到数组中暂存,然后主函数调用scaner()函数对其进行逐个扫描,分离出的每个独立单词进行分类判断,构成二元组形式,再将其输出的文件“E:\result.txt”中进行保存。

2、各种单词符号对应的种别码0 标识符21 ret 42 ++ 63 ||1 整型常量22 sho 43 -- 64 ?:2 auto 23 sig 44 - 65 =3 brea 24 siz 45 * 66 +=4 case 25 sta 46 & 67 -=5 char 26 str 47 / 68 *=6 cons 27 swi 48 % 69 /=7 cont 28 typ 49 + 70 %=8 defa 29 uni 50 - 71 >>=9 do 30 uns 51 << 72 <<=10 dou 31 voi 52 >> 73 &=11 els 32 vol 53 < 74 ^=12 enu 33 whi 54 <= 75 |=13 ext 34 ( 55 > 76 ,14 flo 35 ) 56 >= 77 '15 for 36 [ 57 == 78 ;16 got 37 ] 58 != 79 :17 if 38 -> 59 & 80 \{18 int 39 . 60 ^ 81 }19 lon 40 ! 61 | 82 //20 reg 41 ~ 62 &&3、关键数据结构的描述计数器count:将二元组写入文件时通过count判断是否是首次写入,若是则清空文件,否则追加写入;字符串常量endStr:其值为“end”,在分析判断每一单词的种类时,该字符串作为rwtab表的结束标志;数组prog[200]:暂存从文件中读取的源程序代码,该词法分析器约定源代码长度不超过199;数组token[20]:暂存每次分离出的单个具有独立意义的单词,该词法分析器约定每个单词的长度不超过19;结构体result:存放一个单词的种别码和单词本身的值,在写入文件时以结构体中的元素为单位依次写入;4、程序结构的描述本程序采用结构化设计方法,共有两个文件,六个模块,分别介绍如下:rwtab.h文件包含一个模块,即各种单词符号对应的种别码,作为外部文件被main.cpp文件引用。

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

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

编译原理实验报告词法分析器制作与应用设计思想(1)程序主体结构部分:说明部分%%规则部分%%辅助程序部分(2)主体结构的说明在这里说明部分告诉我们使用的LETTER,DIGIT, IDENT(标识符,通常定义为字母开头的字母数字串)和STR(字符串常量,通常定义为双引号括起来的一串字符)是什么意思.这部分也可以包含一些初始化代码.例如用#include来使用标准的头文件和前向说明(forward ,references).这些代码应该再标记"%{"和"%}"之间;规则部分&gt;可以包括任何你想用来分析的代码;我们这里包括了忽略所有注释中字符的功能,传送ID名称和字符串常量内容到主调函数和main函数的功能.(3)实现原理程序中先判断这个句语句中每个单元为关键字、常数、运算符、界符,对与不同的单词符号给出不同编码形式的编码,用以区分之。

PL/0语言的EBNF表示<常量定义>::=<标识符>=<无符号整数>;<标识符>::=<字母>={<字母>|<数字>};<加法运算符>::=+|-<乘法运算符>::=*|/<关系运算符>::==|#|<|<=|>|>=<字母>::=a|b|…|X|Y|Z<数字>::=0|1|2|…|8|9三:设计过程1.关键字:void,main,if,then,break,int,Char,float,include,for,while,printfscanf 并为小写。

2."+”;”-”;”*”;”/”;”:=“;”:”;”<“;”<=“;”>“;”>=“;”<>“;”=“;”(“;”)”;”;”;”#”为运算符。

3.其他标记如字符串,表示以字母开头的标识符。

编译原理课程实验报告(词法分析器及语法分析器)

编译原理课程实验报告(词法分析器及语法分析器)

编译原理实验报告班级:软件0501班学号:**********姓名:***词法分析器与语法分析器I. 问题描述设计、编制并调试一个词法分析子程序,完成识别语言单词的任务;设计、编制、调试一个语法分析程序,并用它对词法分析程序所提供的单词序列进行语法检查和结构分析。

ii. 设计简要描述界面需求:为了更加形象的模拟过程,此实验使用图形界面。

要求从图形界面上输入输入串,点击词法分析,可以将词法分析后识别的单词符号显示,点击语法分析,可以将语法分析的堆栈过程显示,并且显示结果(是否是符合文法的句子),清空则可以将所有置空。

功能分析:1、由用户输入输入串;2、用户点击“词法分析”,可以将词法分析后识别的单词符号显示。

3、用户点击语法分析,可以将语法分析的堆栈过程显示,并且显示结果(是否是符合文法的句子)4、用户点击清空,则将界面所有组件置为空思路描述:一、设计构想:本实验决定编写一个简易C语言的词法分析器和语法分析器。

使其能够识别while,if等关键字,可以判断赋值语句、条件语句、循环语句。

二、文法分析1、需要识别的关键字及其识别码有:关键字识别码关键字识别码关键字识别码main 0 - 11 ;22int 1 * 12 > 23char 2 / 13 < 24if 3 ( 14 >= 25else 4 ) 15 <= 26for 5 [ 16 == 27while 6 ] 17 != 28ID 7 { 18 ERROR -1NUM 8 } 19= 9 , 20+ 10 : 212、文法〈程序〉→ mai n()〈语句块〉〈语句块〉→{〈语句串〉}〈语句串〉→〈语句〉;〈语句串〉|〈语句〉;〈语句〉→〈赋值语句〉|〈条件语句〉|〈循环语句〉〈赋值语句〉→ ID =〈表达式〉;〈条件语句〉→ if〈条件〉〈语句块〉〈循环语句〉→ while〈条件〉〈语句块〉〈条件〉→(〈表达式〉〈关系符〉〈表达式〉)〈表达式〉→〈表达式〉〈运算符〉〈表达式〉|(〈表达式〉)|ID|NUM〈运算符〉→+|-|*|/〈关系符〉→<|<=|>|>=|=|!>转化为符号表示:S→ main() K|空K→ { C }C→Y;C |空Y→F | T | XF→ ID = BT→ if J KX→ while J KJ→( B G B )B→ B Z B |( B )| ID | NUMZ→ + | - | * | /G→< | <= | > | >= | == | !>表示含义:S:程序 K:语句块 C:语句串 Y:语句 F :赋值语句T:条件语句 X:循环语句 J:条件 B:表达式 I:项 Z :运算符G:关系符3、LL(1)分析表(1),求出first集及follow集:FIRST(S)={mian}FIRST(K)={{}FIRST(C)= FIRST(Y)= {ID,if,while,空};FIRST(Y)= FIRST(F)+ FIRST(T)+ FIRST(X)={ID,if,while};FIRST(F)={ID};FIRST(T)={if};FIRST(X)={while};FIRST(J)= FIRST(B)={};FIRST(B)={(,ID,NUM };FIRST(Z)={+,-,*,/}FIRST(G)={<,<= ,>,>=,==,!= };FOLLO W(S)={#};FOLLO W(K)={;};FOLLO W(C)={}};FOLLO W(Y)={;}FOLLO W(F)={;};FOLLO W(T)={;};FOLLO W(X)={;};FOLLO W(J)={{,;};FOLLO W(B)={+,-,*,/,),<,<= ,>,>=,==,!=,;};FOLLO W(B’)={+,-,*,/,),<,<= ,>,>=,==,!=,;};FOLLO W(Z)={(,ID,NUM };FOLLO W(G)={(,ID,NUM };(2)消除左递归,拆分文法关系并编号0、S→ 空1、S→ main() K2、K→ { C }3、C→Y;C4、C→空5、Y→ F6、Y→ T7、Y→ X8、F→ ID = B9、T→ if J K10、X→ while J K11、J→( B G B )12、 B→( B )B'13、B→ ID B'14、B→ NUM B'15、B'→ BZB B'16、B'→空17、Z→ +18、Z→ -19、Z→ *20、Z→ /21、 G→ <22、 G→ <=23、 G→ >24、 G→ >=25、 G→ ==26、 G→ !=(3)构造LL (1)分析表(注:在表中用上一步的编号表示所需要的产生式)iii. 详细设计描述 项目构架:各函数功能介绍:main 空 () { } ; = if while ID num + - * / < <= > >= == != # S 10 K 2 C 4 4 3 3 3 Y 6 7 5 F 8 T 9 X10 J11 B1213 14B '16 15 16 16 15 15 16 16 16 16 16 16 16 16 16 16 Z 17 18 19 20G21 22 232425261、word.wordList包(存储了关键字):word:此类是定义了存储关键字的结构:包括String型的关键字,和int型的识别符。

(完整)编译原理实验报告(词法分析器 语法分析器)

(完整)编译原理实验报告(词法分析器 语法分析器)

编译原理实验报告实验一一、实验名称:词法分析器的设计二、实验目的:1,词法分析器能够识别简单语言的单词符号2,识别出并输出简单语言的基本字。

标示符。

无符号整数.运算符.和界符。

三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号.2、程序流程图(1)主程序(2)扫描子程序3、各种单词符号对应的种别码五、实验内容: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语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术.三、实验原理:1、算术表达式语法分析程序的算法思想首先通过关系图法构造出终结符间的左右优先函数f(a),g(a)。

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

词法分析设计1. 实验目的通过本实验的编程实践,了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。

2. 实验内容用C++语言实现对C++语言子集的源程序进行词法分析。

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

3. 实验原理本次实验采用NFA->DFA->DFA0的过程:对待分析的简单的词法(关键词/id/num/运算符/空白符等)先分别建立自己的FA,然后将他们用产生式连接起来并设置一个唯一的开始符,终结符不合并。

待分析的简单的词法(1)关键字:"asm","auto","bool","break","case","catch","char","class","const","const_cast"等(2)界符(查表)";",",","(",")","[","]","{","}"(3)运算符"*","/","%","+","-","<<","=",">>","&","^","|","++","--"," +=","-=","*=","/=","%=","&=","^=","|="relop:(4)其他单词是标识符(ID)和整型常数(SUM),通过正规式定义。

id/keywords:digit:(5)空格有空白、制表符和换行符组成。

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

空白、制表符和换行符:4. 相关自动机描述DFA:DFA0:5.流程图5. 核心数据结构描述(1)生成的token序列由name、type、attr保存。

struct token{string name;string type;int attr;};(2)本文的大多数数据结构都用map来保存,优点是查找方便,大大提高时间复杂度。

map<string,int> Keywords; //保存关键字map<string,int> Sep; //保存界符map<string,int> Relop; //保存比较运算符map<string,int> Op; //保存其他运算符map<string,int>id; //保存输入字符串中的idmap<string,int>num; //保存数字vector<token>Token; //保存token序列,大小未知,所以采用vector保存6. 核心算法描述(1)void addToken(string s,int type)s为找到的字符串,type 为可能类型。

将分析出来的token()序列添加到Token序列表中。

如果是类型为1,查看关键词表,若找到,其类型为关键词并将其以类型为关键词存储到Token表中;若未找到,则查找id表,若找到,说明该id 已经出现过,否则添加新的id到id表中,将该i字符串以类型为id添加到Token表中。

如果类型为2,在界符表中查找,如果找到以类型为界符存储到Token表中,同理其他几种类型。

可能类型为1--5,如果出现其他类型表示是词法分析器中发现额错误,将错误信息记录下来。

void addToken(string s,int type){switch(type){case 1:l_it=Keywords.find(s);if (l_it!=Keywords.end()){token t={s,"keywords",l_it->second};Token.push_back(t);}else{l_it=id.find(s);if (l_it==id.end()){id[s]=idNum;token t={s,"id",idNum++};Token.push_back(t);}else {token t={s,"id",l_it->second};Token.push_back(t);}}break;case 2:l_it=Sep.find(s);if (l_it!=Sep.end()){token t={s,"separatrix",l_it->second};Token.push_back(t);}break;case 3:l_it=Op.find(s);if (l_it!=Op.end()){token t={s,"op",l_it->second};Token.push_back(t);}break;case 4:l_it=Relop.find(s);if (l_it!=Relop.end()){token t={s,"relop",l_it->second};Token.push_back(t);}break;case 5:l_it=num.find(s);if (l_it==num.end()){num[s]=nNum;token t={s,"num",nNum++};Token.push_back(t);}else {token t={s,"num",l_it->second};Token.push_back(t);}break;default: //errortoken t={s,"id",-1};Token.push_back(t);break;}}(2)void lexical() 词法分析器,按字符读入文法并对其进行处理。

从状态0开始处理,如果是空白符则一直在状态0,如果第一个字符为字母,继续往后寻找,直至不是字母或是数字结束;若第一个字符为数字,将其拼凑成一个数字,数字可以有小数点等,详细见状态转换图,注意以数字开头容易出现一种例如3a类型的错误,所以以数字开头的一定要往下多找一个,看最后一个数字后面是否为空白符或界符或者其他允许出现的符号,如果后面紧跟着字母则报错。

如上同理分析运算符等。

注意每次处理完遇到一个字符串都要将其送到addToken()添加到Token表中并回到状态0,继续往下处理。

void lexical(){fstream ln("E:\ln.txt");char ch,tempch;int state=0;string s="",key="";while(!ln.eof()){switch(state){case 0: ch=ln.get();s=ch;if (ch==13||ch==10||ch==32||ch==9) {state=0; s="";}else if (ch=='<') state=1;else if (ch=='=') state=6;else if (ch=='>') state=9;else if (isLetter(ch)) state=13;else if (isDigit(ch)) state=15;else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='&'||ch=='|'){ state=20; tempch=ch;}else if (ch=='^') state=44;else if (isSep(ch)!=-1) state=47;else if (isOp(s)!=-1) state=48;else if (isRelop(s)!=-1) state=49;else state=50; //errorbreak;case 1: ch=ln.get();if(ch=='='||ch=='>') state=2;else if(ch=='<') state=4;else state=5;break;case 2:s+=ch;addToken(s,4);state=0;break;case 4:s+=ch;addToken(s,3);state=0;break;case 5: //* addToken(s,4);ln.seekg(-1,ios::cur);state=0;break;case 6: ch=ln.get();if(ch=='=') state=7;else state=8;break;case 7:s+=ch;addToken(s,4);state=0;break;case 8: //* addToken(s,3);ln.seekg(-1,ios::cur);state=0;break;case 9: ch=ln.get();if(ch=='=') state=10;else if(ch=='>') state=11;else state=12;break;case 10:s+=ch;addToken(s,4);state=0;break;case 11:s+=ch;addToken(s,3);state=0;break;case 12: //* state=0;addToken(s,4);ln.seekg(-1,ios::cur);break;case 13: ch=ln.get();if(isDigit(ch)||isLetter(ch)) s+=ch;else state=14;break;case 14: //*state=0;addToken(s,1);ln.seekg(-1,ios::cur);break;case 15: ch=ln.get();if (isDigit(ch)) s+=ch;else if (ch=='.'){s+=ch;state=16;}else state=18;break;case 16: ch=ln.get();s+=ch;if (isDigit(ch)) state=17;else state=50; //error break;case 17: ch=ln.get();if (isDigit(ch)){s+=ch;state=17;}else state=18;break;case 18: //*if (isLetter(ch)){s+=ch;state=50;}else{addToken(s,5);ln.seekg(-1,ios::cur);state=0;}break;case 20: ch=ln.get();if(ch==tempch||ch=='=') state=21;else state=23;break;case 21:s+=ch;addToken(s,3);state=0;break;case 23:addToken(s,3);ln.seekg(-1,ios::cur);state=0;break;case 44: ch=ln.get();if (ch=='=') state=45;else state=46;break;case 45:s+=ch;addToken(s,3);break;case 46:addToken(s,3);break;case 47:addToken(s,2);state=0;break;case 48:addToken(s,3);state=0;break;case 49:addToken(s,4);state=0;break;case 50: //errorwhile((ch=ln.get())!=EOF){if(isSep(ch)!=-1||ch==13||ch==10||ch==32||ch==9) break;else s+=ch;}addToken(s,6); //errorstate=0;break;default:break;}}}7. 测试用例待测字符串:void fun(){int a=2,b=3,3a;a++;b--;a+=b;b*=a;int c=a+4;int d=b*5;}产生结果在out.txt中(注意,无论输入输出文件都要保存在E盘根目录下)8. 出现的问题与解决方案本实验的难点就是进行有效地进行状态如转换,先对每一个简单部分,如空白符、id 、digit 等画出自动机状态,然后由NFA->DFA ,添加一个唯一的初始状态,产生式连接。

相关文档
最新文档