编译原理实习设计——词法分析程序

合集下载

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

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

编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的: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。

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

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

编译原理词法分析实验报告词法分析实习报告实习题目设计一个表达式的文法①表达式中的运算按运算符优先级由高到低依次有:+、-、*、/、↑其中+、-是左结合,*、/、↑右结合。

②表达式中的运算对象可以为标识符、无正负号常量。

设计的文法G[<表达式>]=(VN,VT,P,<表达式>)其中,VN={<表达式>,<无正负号常量>,<标志符>,<数字>,<字母>} VT={ a…z,A…Z,0…9}P={<表达式>→DE↑<表达式>∣DE;DE→ME/DE∣ME;ME→SE*ME∣SE;SE→SE-AE∣AE;AE→AE +<表达式>∣<表达式>∣<标识符>∣<无正负号常量>;〈标识符〉→〈字母〉|〈标识符〉〈字母〉|〈标识符〉〈数字〉;〈无正负号常量〉→〈数字〉|〈无正负号常量〉〈数字〉;〈字母〉→a|b|…|x|y|z|A|B|…|X|Y|Z;〈数字〉→1│2│3│4│5│6│7│8│9│0}词法分析程序设计思路词法分析就是逐个读入源程序字符并按照构词规则切分成一系列单词.单词是语言中具有独立意义的最小单位,根据设计的文法可以判断出表达式中的单词种类有标识符,运算符,常量。

字母或数字识别各类单词符号的状态转换图所用数据结构FILE *fp;//用于存放原表达式文件FILE *outp;//用于存放单词输出结果char ch;//用于存储当前读取的字符char *operatornum[5]={"+","-","*","/","|"};//用于存放运算符源码#include#include#include#include#include#include#includeFILE *fp;//用于存放原表达式文件FILE *outp;//用于存放单词输出结果char ch;//用于存储当前读取的字符char *operatornum[5]={"+","-","*","/","|"};//用于存放运算符/////////////////////////////////////////////////////////////////// /////////////////////// bool search(char searchstr[])//匹配运算符{int i;for(i=0;i<=4;i++)if(strcmp(operatornum[i],searchstr)==0)return(true);return(false);}/////////////////////////////////////////////////////////////////// //////////////////////// char letterprocess (char ch)//字母处理函数{int i=-1;char letter[20];while (isalnum(ch)!=0){letter[++i]=ch;ch=fgetc(fp);}letter[i+1]='\0';printf("<标示符,%s>\n",letter);fputs("<标示符,",outp);fputs(">\n",outp);return(ch);}/////////////////////////////////////////////////////////////////// //////////////////////// char numberprocess(char ch)//数字处理程序{int i=-1;char num[20];while (isdigit(ch)!=0)//如果为数字{num[++i]=ch;ch=fgetc(fp);}if(isalpha(ch)!=0)//如果为字母{while(isspace(ch)==0)//如果为空格{num[++i]=ch;ch=fgetc(fp);}num[i+1]='\0';printf("错误!非法标识符:%s\n",num);return(ch);}num[i+1]='\0';printf("<常数,%s>\n",num);fputs("<常数,",outp);fputs(num,outp);return(ch);}/////////////////////////////////////////////////////////////////// /////////////////////////// char otherprocess(char ch)//其它符号(运算符和非法字符)的处理{int i=-1;char other[20];if (isspace(ch)!=0){ch=fgetc(fp);return(ch);}while ((isspace(ch)==0)&&(isalnum(ch)==0)){other[++i]=ch;ch=fgetc(fp);}other[i+1]='\0';if (search(other)){ printf("<运算符,%s>\n",other);fputs("<运算符,",outp);fputs(other,outp);fputs(">\n",outp);}elseprintf("错误!非法字符:%s\n",other);return (ch);}/////////////////////////////////////////////////////////////////////////////////////////////int main (){char str,c;printf("**********************************词法分析器************************************\n");outp=fopen("二元式表.txt","w");if ((fp=fopen("源程序.txt","r"))==NULL)printf("源程序无法打开!\n");else{str =fgetc(fp);while (str!=EOF){if (isalpha(str)!=0)str=letterprocess(str);else{if (isdigit(str)!=0)str=numberprocess(str);elsestr=otherprocess(str);}};printf("词法分析结束,谢谢使用!\n");printf("点任意键退出!\n");}c=getch();}输入从存放源文件的目录下的源程序.txt 中读取表达式输出从将结果存放到源文件的目录下的二元式表.txt 中问题分析词法分析相对而言较为简单,词法分析的目的就是识别出一个个的单词符号,为进一步进行语法分析打下坚实的基础。

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

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

编译原理实验词法分析实验报告一、实验目的词法分析是编译过程的第一个阶段,其主要任务是从左到右逐个字符地对源程序进行扫描,产生一个个单词符号。

本次实验的目的在于通过实践,深入理解词法分析的原理和方法,掌握如何使用程序设计语言实现词法分析器,提高对编译原理的综合应用能力。

二、实验环境本次实验使用的编程语言为_____,开发工具为_____。

三、实验原理词法分析的基本原理是根据编程语言的词法规则,将输入的字符流转换为单词符号序列。

单词符号通常包括关键字、标识符、常量、运算符和界符等。

词法分析器的实现方法有多种,常见的有状态转换图法和正则表达式法。

在本次实验中,我们采用了状态转换图法。

状态转换图是一种有向图,其中节点表示状态,有向边表示在当前状态下输入字符的可能转移。

通过定义不同的状态和转移规则,可以实现对各种单词符号的识别。

四、实验步骤1、定义单词符号的类别和编码首先,确定实验中要识别的单词符号种类,如关键字(if、else、while 等)、标识符、整数常量、浮点数常量、运算符(+、、、/等)和界符(括号、逗号等)。

为每个单词符号类别分配一个唯一的编码,以便后续处理。

2、设计状态转换图根据单词符号的词法规则,绘制状态转换图。

例如,对于标识符的识别,起始状态为“起始状态”,当输入为字母时进入“标识符中间状态”,在“标识符中间状态”中,若输入为字母或数字则继续保持该状态,直到遇到非字母数字字符时结束识别,确定为一个标识符。

3、编写词法分析程序根据状态转换图,使用所选编程语言实现词法分析器。

在程序中,通过不断读取输入字符,根据当前状态进行转移,并在适当的时候输出识别到的单词符号。

4、测试词法分析程序准备一组包含各种单词符号的测试用例。

将测试用例输入到词法分析程序中,检查输出的单词符号是否正确。

五、实验代码以下是本次实验中实现词法分析器的核心代码部分:```include <stdioh>include <ctypeh>//单词符号类别定义typedef enum {KEYWORD,IDENTIFIER,INTEGER_CONSTANT,FLOAT_CONSTANT,OPERATOR,DELIMITER} TokenType;//关键字列表char keywords ={"if","else","while","for","int","float","void"};//状态定义typedef enum {START,IN_IDENTIFIER,IN_INTEGER,IN_FLOAT,IN_OPERATOR} State;//词法分析函数TokenType getToken(char token, int tokenLength) {State state = START;int i = 0;while (1) {char c = getchar();switch (state) {case START:if (isalpha(c)){state = IN_IDENTIFIER;tokeni++= c;} else if (isdigit(c)){state = IN_INTEGER;tokeni++= c;} else if (c =='+'|| c ==''|| c ==''|| c =='/'|| c =='('|| c ==')'|| c ==';'|| c ==','){state = IN_OPERATOR;tokeni++= c;} else if (c ==''){state = IN_FLOAT;tokeni++= c;} else if (c == EOF) {tokeni ='\0';tokenLength = i;return -1;} else {tokeni ='\0';tokenLength = i;return -2;}break;case IN_IDENTIFIER:if (isalpha(c) || isdigit(c)){tokeni++= c;} else {ungetc(c, stdin);tokeni ='\0';tokenLength = i;//检查是否为关键字for (int j = 0; j < sizeof(keywords) / sizeof(keywords0); j++){if (strcmp(token, keywordsj) == 0) {return KEYWORD;}}return IDENTIFIER;}break;case IN_INTEGER:if (isdigit(c)){tokeni++= c;} else if (c ==''){state = IN_FLOAT;tokeni++= c;} else {ungetc(c, stdin);tokeni ='\0';tokenLength = i;return INTEGER_CONSTANT;}break;case IN_FLOAT:if (isdigit(c)){tokeni++= c;} else {ungetc(c, stdin);tokeni ='\0';tokenLength = i;return FLOAT_CONSTANT;}break;case IN_OPERATOR: tokeni ='\0';tokenLength = i;return OPERATOR; break;}}}int main(){char token100;int tokenLength;TokenType tokenType;while ((tokenType = getToken(token, &tokenLength))!=-1) {switch (tokenType) {case KEYWORD:printf("Keyword: %s\n", token);break;case IDENTIFIER:printf("Identifier: %s\n", token);break;case INTEGER_CONSTANT:printf("Integer Constant: %s\n", token);break;case FLOAT_CONSTANT:printf("Float Constant: %s\n", token);break;case OPERATOR:printf("Operator: %s\n", token);break;case DELIMITER:printf("Delimiter: %s\n", token);break;}}return 0;}```六、实验结果对准备的测试用例进行输入,得到的词法分析结果如下:测试用例 1:```int main(){int num = 10;float pi = 314;if (num > 5) {printf("Hello, World!\n");}}```词法分析结果:```Keyword: int Identifier: main Delimiter: (Delimiter: ){Identifier: num Operator: =Integer Constant: 10;Identifier: float Identifier: pi Operator: =Float Constant: 314;Keyword: ifDelimiter: (Identifier: numOperator: >Integer Constant: 5){Identifier: printfDelimiter: (String: "Hello, World!\n" Delimiter: );}```测试用例 2:```for (int i = 0; i < 10; i++){double result = i 25;```词法分析结果:```Keyword: for Delimiter: (Keyword: int Identifier: i Operator: =Integer Constant: 0;Identifier: i Operator: <Integer Constant: 10;Identifier: i Operator: ++)Identifier: doubleIdentifier: resultOperator: =Identifier: iOperator:Float Constant: 25;}```通过对多个测试用例的分析,词法分析器能够正确识别出各种单词符号,实验结果符合预期。

编译原理实习设计——词法分析程序

编译原理实习设计——词法分析程序

图三:实数的识别
} 27 { * 26 * 25 ] * 24 [ * 23 ( * 22 ) * 21 ; *
20 , * * | 19 18 非| 17 | * * 16 & 15 非& 14 & * = 13 * 12 非= 11 = * 10 # * 9 = * 8 非= 7 %
* 6 ^ * 5 = * 4 非= 3 ! * 2
if(c=='>' || c=='"') { Output("$ID", string); for(int p=0; p<k; p++) { string[p]=NULL; } break; } else if( c=='.' || IsLetter(c) IsDigit(c) ) { string[k++]=c; } } break; } j++; } c=Get_ch(++j); } if(IsLetter(c) || c=='_') { k=0; string[k++]=c; j++; while(1) { c=Get_ch(j); if(IsLetter(c) || c=='_' || IsDigit(c)) { string[k++]=c; } else { if(IsKeyword(string) ) { Output("$keyword", string); }
!= ^ % %= = == && & | || , ; ( ) [ ] { } + ++ += - ―― -= * *= / /=

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

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

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

二、实验要求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、实验目的从左至右逐个字符的对源程序进行扫描,产生一个个单词符号,把字符串形式的源程序改造成单词符号形式的中间程序。

2、实验内容表C语言子集的单词符号及内码值单词符号种别编码助记符内码值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 LQ= 12 = --; 13 ; --输入源程序如下if a==1 a=a+1;else a=a+2;输出对应的单词符号形式的中间程序3、实验过程实验上机程序如下:#include "stdio.h"#include "string.h"int i,j,k;char s ,a[20],token[20];int letter(){if((s>=97)&&(s<=122))return 1;else return 0;}int Digit(){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(){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 you source program,end('#'):\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!='#');i=1;memset(token,0,sizeof(char)*10);j=0;get();while(s!='#'){if(s==' '||s==10||s==13)get();else{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(Digit()||letter()){token[j]=s;j=j+1;get();}retract();k=lookup();if(k==0)printf("(6,%s)\n",token); elseprintf("(%d,null)\n",k); break;case'0':case'1':case'2':case'3':case'4':case'5':case'6':case'7':case'8':case'9':while(Digit()){token[j]=s;j=j+1;get();}retract();printf("(%d,%s)\n",7,token); break;case'+':printf("(+,null)\n"); break;case'-':printf("(-,null)\n"); break;case'*':printf("(*,null)\n"); break;case'<':get();if(s=='=')printf("(relop,LE)\n"); else{retract();printf("(relop,LT)\n");}break;case'=':get();if(s=='=')printf("(relop,EQ)\n"); else{retract();printf("(=,null)\n");}break;case';':printf("(;,null)\n"); break;default:printf("(%c,error)\n",s);break;}memset(token,0,sizeof(char)*10);j=0;get();}}}4、实验结果实验结果分析:if是关键字,对应种别编码为2,输出(2,null)a是标识符,对应种别编码为6,值为a,输出(6,a)==的助记符是relop,内码值为LE,输出(relop,LE)1是常数,对应种别编码为7,值为1,输出(7,1)a是标识符,对应种别编码为6,值为a,输出(6,a)=是赋值符号,直接输出,(=,null)a是标识符,对应种别编码为6,值为a,输出(6,a)+是运算符,直接输出(=,null)1是常数,对应种别编码为7,值为1,输出(7,1);是语句结束符号,直接输出(;,null)else是关键字,对应种别编码为3,输出(3,null)a是标识符,对应种别编码为6,值为a,输出(6,a)=是赋值符号,直接输出,(=,null)a是标识符,对应种别编码为6,值为a,输出(6,a)+是运算符,直接输出(=,null)2是常数,对应种别编码为7,值为2,输出(7,2);是语句结束符号,直接输出(;,null)#是输入结束标志编译原理实验语法分析程序实验二:语法分析程序1、实验目的:将单词组成各类语法单位,讨论给类语法的形成规则,判断源程序是否符合语法规则3、实验内容:给定文法:G[E]:E→E+E|E-E|E*E|E/E|(E)E→0|1|2|3|4|5|6|7|8|9首先把G[E]构造为算符优先文法,即:G’[E]:E→E+T|TT→T-F|FF→F*G|GG→G/H|HH→(E)|i得到优先关系表如下:+ - * / i ( ) # + ·><·<·<·<·<··>·> - ·>·><·<·<·<··>·> * ·>·>·><·<·<··>·> / ·>·>·>·><·<··>·>i ·>·>·>·>·>·>( <·<·<·<·<·<·=) ·>·>·>·>·>·> # <·<·<·<·<·<·=构造出优先函数+ - * / i ( ) #f 6 8 10 12 12 2 12 2g 5 7 9 11 13 13 2 2要求输入算术表达式:(1+2)*3+2*(1+2)-4/2输出其对应的语法分析结果4、实验过程:上机程序如下:#include "stdio.h"#include "string.h"char a[20],optr[10],s,op;int i,j,k,opnd[10],x1,x2,x3;int operand(char s){if((s>=48)&&(s<=57))return 1;else return 0;}int f(char s){switch(s){case'+':return 6;case'-':return 8;case'*':return 10;case'/':return 12;case'(':return 2;case')':return 12;case'#':return 2;default:printf("error");}}int g(char s){switch(s){case'+':return 5;case'-':return 7;case'*':return 9;case'/':return 11;case'(':return 13;case')':return 2;case'#':return 2;default:printf("error");}}void get(){s=a[i];i=i+1;}void main(){printf("请输入算数表达式,并以‘#’结束:\n");i=0;do{scanf("%c",&a[i]);i++;}while(a[i-1]!='#');i=0;j=0;k=0;optr[j]='#';get();while((optr[j]!='#')||(s!='#')){if(operand(s)){opnd[k]=s-48;k=k+1;get();}else if(f(optr[j])<g(s)){j=j+1;optr[j]=s;get();}else if(f(optr[j])==g(s)){if(optr[j]=='('&&s==')'){j=j-1;get();}else if(optr[j]=='('&&s=='#'){printf("error\n");break;}else if(optr[j]=='#'&&s==')'){printf("error\n");break;}}else if(f(optr[j])>g(s)){op=optr[j];j=j-1;x2=opnd[k-1];x1=opnd[k-2];k=k-2;switch(op){case'+':x3=x1+x2;break;case'-':x3=x1-x2;break;case'*':x3=x1*x2;break;case'/':x3=x1/x2;break;}opnd[k]=x3;k=k+1;printf("(%c,%d,%d,%d)\n",op,x1,x2,x3);}else{printf("error\n");break;}}if(j!=0||k!=1)printf("error\n");}5、实验结果:实验结果分析:(1+2)*3+2*(1+2)-4/2#因为‘)’优先级大于‘*’,先计算1+2=3,并输出(+,1,2,3)原式变为:3*3+2*(1+2)-4/2#因为‘*’优先级大于‘+’,先计算3*3=9,并输出(*,3,3,9)原式变为:9+2*(1+2)-4/2#因为‘)’优先级大于‘-’,先计算1+2=3,并输出(+,1,2,3)原式变为:9+2*3-4/2#因为‘*’优先级大于‘-’,先计算2*3=6,并输出(*,2,3,6)原式变为:9+6-4/2#因为‘/’优先级大于‘#’,先计算4/2=2,并输出(/,4,2,2)原式变为:9+6-2#因为‘-’优先级大于‘#’,先计算6-2=4,并输出(-,6,2,4)原式变为:9+4#因为‘+’优先级大于‘#’,计算9+4=13,并输出(+,9,4,13)原式变为13#优先级等于#,跳出while循环,运算结束!。

编译原理词法分析实验

编译原理词法分析实验

编译原理词法分析实验编译原理是计算机科学中的重要课程,它研究的是如何将高级语言翻译成机器语言的过程。

而词法分析则是编译原理中的一个重要环节,它负责将源程序中的字符序列转换成有意义的词素序列。

本文将介绍编译原理词法分析实验的相关内容。

1. 实验背景。

编译原理词法分析实验是计算机相关专业的重要实践环节,通过实验可以加深对编译原理词法分析相关知识的理解,提高学生的实际动手能力和解决问题的能力。

2. 实验内容。

编译原理词法分析实验通常包括以下内容:(1)词法分析器的设计与实现,学生需要设计并实现一个简单的词法分析器,能够识别出源程序中的各种词素,并进行相应的处理。

(2)正规表达式的应用,学生需要掌握正规表达式的基本语法和应用,用于描述词法分析中的各种词素模式。

(3)有限自动机的构建,学生需要学习有限自动机的基本原理和构建方法,用于实现词法分析器中的词素识别过程。

3. 实验步骤。

编译原理词法分析实验的具体步骤如下:(1)分析源程序,学生需要先对给定的源程序进行分析,了解其中包含的各种词素类型和相应的识别规则。

(2)设计词法分析器,学生根据源程序的特点,设计词法分析器的识别模式和处理方法,通常采用正规表达式描述词素的模式,再将其转换为有限自动机。

(3)实现词法分析器,学生根据设计的词法分析器,使用编程语言实现相应的词法分析器程序。

(4)测试与调试,学生需要对实现的词法分析器进行测试和调试,确保其能够正确识别源程序中的各种词素,并进行相应的处理。

4. 实验意义。

编译原理词法分析实验对于学生的意义在于:(1)加深理论知识,通过实验,学生能够更加深入地理解编译原理词法分析的相关理论知识,巩固课堂学习成果。

(2)提高实践能力,实验能够提高学生的实际动手能力和解决问题的能力,培养学生的编程思维和实践能力。

(3)促进团队合作,在实验过程中,学生通常需要分组合作完成词法分析器的设计与实现,促进了学生之间的团队合作能力。

5. 实验总结。

编译原理词法分析实验

编译原理词法分析实验

编译原理词法分析实验一、实验目的本实验旨在通过编写一个简单的词法分析器,了解编译原理中词法分析的基本原理和实现方法。

二、实验材料1. 计算机编程环境2. 编程语言三、实验步骤1. 了解词法分析的概念和作用。

词法分析是编译器中的第一个阶段,它的主要任务是将源代码中的字符序列转化为有意义的标识符,如关键字、操作符、常量和标识符等。

2. 设计词法分析器的流程和算法。

词法分析器的主要原理是通过有限状态自动机来识别和提取标识符。

在设计过程中,需考虑各种可能出现的字符序列,并定义相应的状态转移规则。

3. 根据设计的流程和算法,使用编程语言编写词法分析器的代码。

4. 编译并运行词法分析器程序,输入待分析的源代码文件,观察程序的输出结果。

5. 分析输出结果,检查程序是否正确地提取了源代码中的标识符。

四、实验结果经过词法分析器的处理,源代码将被成功地转化为有意义的标识符。

结果可以通过以下几个方面来验证:1. 关键字和操作符是否被正确识别和提取。

2. 常量和标识符是否被正确识别和提取。

3. 检查程序的错误处理能力,如能否发现非法字符或非法标识符。

4. 输出结果是否符合预期,可与自己编写的语法规则进行对比。

5. 对于特殊情况,如转义字符等是否正确处理。

五、实验总结通过本次实验,我深入了解了编译原理中词法分析的重要性和基本原理。

编写词法分析器的过程中,我学会了使用有限状态自动机来识别和提取标识符,并通过实践巩固了相关知识。

此外,我还对源代码的结构有了更深入的了解,并且掌握了如何运用编程语言来实现词法分析器。

通过本次实验,我不仅提升了自己的编程技术,也对编译原理有了更深入的认识和理解。

六、实验心得通过实验,我深刻体会到了词法分析在编译过程中的重要性。

合理设计和实现词法分析器,可以大大提高编译器的效率和准确性。

同时,通过编写词法分析器的代码,我不仅锻炼了自己的编程能力,还提升了对编译原理的理解和掌握。

这次实验让我更加深入地了解了编译原理中的词法分析,也为我今后在编程领域的发展打下了坚实的基础。

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

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

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

编译原理实验报告实验名称:编写词法分析程序实验类型:设计性实验指导教师:*****专业班级:软件工程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化简确定化。

2021年编译原理实验报告词法分析程序的设计

2021年编译原理实验报告词法分析程序的设计

试验2 词法分析程序设计一、试验目掌握计算机语言词法分析程序开发方法。

二、试验内容编制一个能够分析三种整数、标识符、关键运算符和关键关键字词法分析程序。

三、试验要求1、依据以下正规式, 编制正规文法, 画出状态图;标识符<字母>(<字母>|<数字字符>)*十进制整数0 | ((1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*)八进制整数0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)*十六进制整数0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)*运算符和界符+ - * / > < = ( ) ;关键字if then else while do2、依据状态图, 设计词法分析函数int scan( ), 完成以下功效:1)从文本文件中读入测试源代码, 依据状态转换图, 分析出一个单词,2)以二元式形式输出单词<单词种类, 单词属性>其中单词种类用整数表示:0: 标识符1: 十进制整数2: 八进制整数3: 十六进制整数运算符和界符, 关键字采取一字一符, 不编码其中单词属性表示以下:标识符, 整数因为采取一类一符, 属性用单词表示运算符和界符, 关键字采取一字一符, 属性为空3、编写测试程序, 反复调用函数scan( ), 输出单词种别和属性。

四、试验环境PC微机DOS操作系统或Windows 操作系统Turbo C 程序集成环境或Visual C++ 程序集成环境五、试验步骤1、依据正规式, 画出状态转换图;2、依据状态图, 设计词法分析算法;观察状态图, 其中状态2、4、7、10(右上角打了星号)需要回调一个字符。

申明部分变量和函数:ch: 字符变量, 存放最新读进源程序字符。

strToken: 字符串变量, 存放组成单词符号字符串。

编译原理实验一 词法分析

编译原理实验一     词法分析

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

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

二、实验内容:如源程序为C语言。

输入如下一段:main(){int a=-5,b=4,j;if(a>=b)j=a-b;else j=b-a;}要求输出如图:(2,”main”)(5,”(”)(5,”)”)(5,”{”)(1,”int”)(2,”a”)(4,”=”)(3,”-5”)(5,”,”)(2,”b”)(4,”=”)(3,”4”)(5,”,”)(2,”j”)(5,”;”)(1,”if”)(5,”(”)(2,”a”)(4,”>=”)(2,”b”)(5,”)”)(2,”j”)(4,”=”)(2,”a”)(4,”-”)(2,”b”)(5,”;”)(1,”else”)(2,”j”)(4,”=”)(2,”b”)(4,”-”)(2,”a”)(5,”;”)(5,”}”)在示例程序的基础上,增加对自加、自减、正负号的判断。

三、源程序:#include<iostream>using namespace std;FILE *fp;char cbuffer;char *key[8]={"if","else","for","while","do","return","break","continue"};int atype,id=4;int search(char searchchar[ ],int wordtype) /*判断单词是保留字还是标识符*/{int i=0;int p;switch (wordtype){case 1:for (i=0;i<=7;i++){if (strcmp(key[i],searchchar)==0){ p=i+1; break; } /*是保留字则p为非0且不重复的整数*/ else p=0; /*不是保留字则用于返回的p=0*/}return(p);}}char alphaprocess(char buffer){ int atype; /*保留字数组中的位置*/int i=-1;char alphatp[20];while ((isalpha(buffer))||(isdigit(buffer))||buffer=='_'){alphatp[++i]=buffer;buffer=fgetc(fp);} /*读一个完整的单词放入alphatp数组中*/alphatp[i+1]='\0';atype=search(alphatp,1);/*对此单词调用search函数判断类型*/if(atype!=0){ printf("%s, (1,%d)\n",alphatp,atype-1); id=1; }else{ printf("(%s ,2)\n",alphatp); id=2; }return buffer;}char digitprocess(char buffer){int i=-1;char digittp[20];while ((isdigit(buffer))){digittp[++i]=buffer;buffer=fgetc(fp);}digittp[i+1]='\0';printf("(%s ,3)\n",digittp);id=3;return(buffer); }char otherprocess(char buffer){char ch[20];ch[0]=buffer;ch[1]='\0';if(ch[0]==','||ch[0]==';'||ch[0]=='{'||ch[0]=='}'||ch[0]=='('||ch[0]==')') { printf("(%s ,5)\n",ch);buffer=fgetc(fp);id=4;return(buffer);}if(ch[0]=='*'||ch[0]=='/'){ printf("(%s ,4)\n",ch);buffer=fgetc(fp);id=4;return(buffer);}if(ch[0]=='='||ch[0]=='!'||ch[0]=='<'||ch[0]=='>'){ buffer=fgetc(fp);if(buffer=='='){ ch[1]=buffer;ch[2]='\0';printf("(%s ,4)\n",ch);}else {printf("(%s ,4)\n",ch);id=4;return(buffer);}buffer=fgetc(fp);id=4;return(buffer);}if(ch[0]=='+'||ch[0]=='-'){if(id==4){ /*在当前符号以前是运算符,则此时为正负号*/ int i=1;buffer=fgetc(fp);ch[1]=buffer;ch[2]='\0';if(ch[0] == ch[1]){printf("(%s,3)\n",ch);buffer=fgetc(fp);return buffer;}while(isdigit(ch[i])){ch[++i] = fgetc(fp);}ch[i] = '\0';id=3;printf("(%s ,3)\n",ch);return(buffer);}buffer=fgetc(fp);ch[1]=buffer;if(ch[0] == ch[1]){ch[2]='\0';printf("(%s,3)\n",ch);buffer=fgetc(fp);return buffer;}ch[1]='\0';printf("(%s ,4)\n",ch);buffer=fgetc(fp);id=4;return(buffer);}}void main(){if ((fp=fopen("example.c","r"))==NULL) /*只读方式打开一个文件*/ printf("error");else{cbuffer = fgetc(fp); /*fgetc( )函数:从磁盘文件读取一个字符*/while (cbuffer!=EOF){if(cbuffer==' '||cbuffer=='\n') /*掠过空格和回车符*/cbuffer=fgetc(fp);elseif(isalpha(cbuffer))cbuffer=alphaprocess(cbuffer);elseif (isdigit(cbuffer))cbuffer=digitprocess(cbuffer);else cbuffer=otherprocess(cbuffer);}}system("pause");}四、实验运行结果:五、实验心得:通过这次实验,更加深了我对编译中的词法分析过程的理解,我将老师所给的示例加以修改,添加了++,--,以及正负号的判断,虽然还有很多实际问题没有考虑进去,例如程序中若有‘//’或者‘/*..*/’时则无法判断出解释语句。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

编译原理词法分析程序设计实验报告【实验目的】1.了解词法分析的主要任务。

2.熟悉编译程序的编制。

【实验内容】根据某文法,构造一基本词法分析程序。

找出该语言的关键字、标识符、整数以及其他一些特殊符号,给出单词的种类和值。

【实验要求】1.构造一个小语言的文法类C小语言文法(以EBNF表示)<程序>::=<分程序>{<分程序>} .<分程序>::=<标识符>’(’<变量说明部分>{,<变量说明部分>}’)’<函数体><变量说明部分>::=int<标识符>{,<标识符>}<函数体>::=’{’[<变量说明部分>;]<语句序列>’}’<语句序列>::=<语句序列>;<语句>|<语句><语句>::=<赋值语句>|<条件语句>|<循环语句>|<函数调用语句><赋值语句>::=<标识符>=<表达式><表达式>::=[+|-]<项>{<加法运算符><项>}<项>::=<因子>{<乘法运算符><因子>}<因子>:=<标识符>|<无符号整数><加法运算符>::= +|-<乘法运算符>::= *|/<条件语句>::=if<条件>’{’<语句序列>’}’[else’{’<语句序列>’}’]<条件>::=<表达式><关系运算符><表达式><关系运算符>::= ==|!=|>|<|>=|<=<循环语句>::=for’(’<表达式>;<条件>;<表达式>’)’ ’{’<语句序列>’}’<函数调用语句>::=<标识符>’(’<标识符>{,<标识符>}|<空>’)’<标识符>::=<字母>{<字母>|<数字>}<无符号整数>::=<数字>{<数字>}<字母>::=a|b|c|…|X|Y|Z<数字>::=0|1|2|…|8|9单词分类情况关键字:int if else for标识符:以字母开头的字母和数字的组合关系运算符:==|!=|>|<|>=|<=加法运算符:+|-乘法运算符:*|/界符:,;{ } ( )2.设计单词的输出形式,单词的种类和值的表示方法种别码单词值如:1 int3.编写词法分析程序cffx.c实现基本的词法分析器,能够分析关键字、标识符、数字、运算符(需要有“==”或“:=”之类需要超前搜索的运算符)以及其他一些符号。

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

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

编译原理试验汇报(一)----词法分析程序【目要求】经过设计编制调试一个具体词法分析程序, 加深对词法分析原理了解。

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

【题目分析】本试验以用户指定想编译以C语言编写文件作为词法分析程序输入数据。

在进行词法分析中, 先自文件头开始以行为单位扫描程序, 将该行字符读入预先设定一个数组缓冲区中, 然后对该数组字符逐词分割, 进行词法分析, 将每个词分割成关键字、标识符、常量和运算符四种词种, 最终产生四个相对应表, 即关键字表、标识符表、常量表和运算符表, 它们以文件形式进行存放。

除此之外, 还产生一个编译后文件, 它指定了每个词在四个表中位置。

【试验过程】下面就词法分析程序汉字件和关键变量进行说明:文件:cpile.c 主程序文件key.txt 关键字文件operation.txt 运算符文件id.txt 标识符文件const.txt 常量文件after_com.txt 编译后产生文件关键变量:FILE *sfp,*nfp,*ifp,*kfp,*cfp,*pfp;char ib[50][20] 标识符表(动态生成)char cb[50][10] 常量表(动态生成)char kb[44][10] 关键字表(预先定义好)char pb[36][5] 运算符表(预先定义好)关键子函数名:int number(char s[],int i); 数字处理函数int letter(char s[],int i); 字符处理函数int operation(char s[],int i); 运算符处理函数void seti (char s[]); 标识符建立函数void setc (char s[]); 常量建立函数void cfile(char s1[], char s2[],int m); 将词和词所在表中位置写入编译后文件 void error1(char s[]); 字符处理犯错汇报void error2(char s[]); 标识符处理犯错汇报void error3(char s[]); 运算符处理犯错汇报void openall(); 打开全部文件void writeall(); 将四个表写入文件void closeall(); 关闭全部文件下面简明分析一下词法分析程序运行步骤:【程序调试】现有源程序a.c清单以下:#include <stdio.h>int main(int argc, char *argv[]) {char ch;int i;ch='a';ch=ch+32 ;i=ch;printf("%d id %c\n",i,ch);/*打印*/ return 0;}运行词法分析程序后, 显示以下结果: after_com.txt文件:#[p--2]include[i--0]<[p--14]stdio.h[i--1]>[p--16]int[k--2]main[i--2]([p--7]int[k--2]argc[i--3],[p--6]char[k--0]*[p--9]argv[i--4]][p--21])[p--8]{[p--23]char[k--0]ch[i--5];[p--13]int[k--2]i[i--6];[p--13]ch[i--5]=[p--15]'[p--19]a[i--7]'[p--19];[p--13]ch[i--5]=[p--15]ch[i--5]+[p--10]32[c--0];[p--13]i[i--6]=[p--15]ch[i--5];[p--13]printf[k--33] ([p--7]"[p--1]d[i--8]id[i--9]%[p--4]c[i--10]\[p--20]n[i--11]"[p--1],[p--6]i[i--6],[p--6]ch[i--5])[p--8];[p--13]return[k--28]0[c--1];[p--13]}[p--25]key.txt 关键字文件:0 char1 short2 int3 unsigned4 long5 float6 double7 struct8 union9 void10 enum11 signed12 const13 volatile14 typedef15 auto16 register17 static18 extem19 break20 case21 continue22 default23 do24 else25 for26 goto27 if28 return29 switch30 while31 sizeof32 txt33 printf34 FILE35 fopen36 NULL37 fclose38 exit39 r40 read41 close42 w43fprintfid.txt 标识符文件:0 include1 stdio.h2 main3 argc4 argv5 ch6 i7 a8 d9 id10 c11 noperation.txt 运算符文件:0 !1 "2 #3 $4 %5 &6 ,7 (8 )9 *10 +11 -12 :13 ;14 <15 =16 >17 ?18 [19 '20 \21 ]22 .23 {24 ||25 }26 !=27 >=28 <=29 ==30 ++31 --32 &&33 /*34*/const.txt 常量文件:0 3210结果完全正确。

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

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

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

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

二、实验内容及要求对某特定语言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、单词种别定义;3、状态转换图;语言A的词法分析的状态转换图如下所示:空格符,制表符或回车符字母或数字4、运行环境介绍;本次实验采用win-tc进行代码的编写和编译及运行程序的运行环境为windows5、关键算法的流程图及文字解释;程序中用到的函数列表:变量ch储存当前最新读进的字符的地址strToken存放当前字符串voidmain() //主函数struct binary *lexicalAnalyze(); //词法分析的主函数,返回一个二元组的指针void GetBC(); //检查ch指向的字符是否为空格、制表或回车符,如果是则调用GetChar()直至不是上述字符void GetChar(); //ch前移一个地址单元int ConCat(); //将ch指向的字符连接到strToken之后int isLetter(); //判断ch指向的字符是否字母int isDigit(); //判断ch指向的字符是否数字int insertId(); //向标识符表中插入当前strToken的字符串int insertConst(); //将strToken的常数插入常数表中int Reserved(); //检测当前strToken中的字符串是否保留字,若是,则返回编码,否则返回0int isId(); //检测当前strToken中的字符串是否在标识符表中已存在,若是,则返回其编号,否则返回0int isConst(); //检测当前strToken中的字符串是否在常数表中已存在,若是,则返回其编号,否则返回0void errProc(int errType); //出错处理过程,errType是错误类型,将错误信息加入错误表中main()函数的流程图如下:lexicalAnalyze()函数的流程图如下所示:Reserved()、isId()和isConst()函数均采用了对链表的遍历算法,errProc()函数通过识别不同的错误编号,向错误链表中添加相应的错误信息。

编译原理实践-PL0的词法分析程序构造

编译原理实践-PL0的词法分析程序构造
编译原理实践-PL0的词法 分析程序构造
通过本次演讲,将带你领略编译原理的奇妙之处,并深入介绍PL0语言的词 法分析及程序构造,让你轻松掌握。
编译原理简介
编译原理是计算机科学的重要基础,涉及源代码的解析、优化和转换过程。它是开发高效程序和语言的 关键。
PL0语言简介
PL0是一种简单且易于学习的编程语言,适合编译原理教学。它具有C语言的 语法特点,是学习编译原理的理想选择。
词法分析的概念和作用
词法分析是编译过程中的第一步,将源代码分解为各种标记(Token)。它有助于语法分析和语义分析的 进行。
PL0的词法规则
PL0的词法规则定义了它的各类标记,如关键字、标识符、运算符和常量。了解规则对于正确理解代码 至关重要。
词法分析程序的设计思路
设词法分析程序需要考虑标识符的判别、关键字的识别等问题。采用有限自动机是一种常用的设计方 法。
PL0的词法分析程序实现
使用C语言编写PL0的词法分析程序,结合有限自动机算法,有效地识别源代 码中的各种标记。
实验结果与总结
通过实验,我们验证了词法分析程序的正确性和性能。深入总结实验结果,对编译原理的学习和应用有 了更深入的理解。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

{ break; } else { pos=ftell(fprogram); fseek(fprogram, pos-1,0); break; } } } else { break; } } } if(ch=='\\') { while(1) { ch=fgetc(fprogram); if(ch!=EOF) { if(ch=='n' || ch=='t' || ch=='\\' || ch=='v' || ch=='b' || ch=='f' || ch=='r' ) { Buffer[i]=ch; i++; WordEnd=1; } else { if(ch==' ' || ch=='\t' || ch=='\n' || ch=='\r') { break; }
图三:实数的识别
} 27 { * 26 * 25 ] * 24 [ * 23 ( * 22 ) * 21 ; *
20 , * * | 19 18 非| 17 | * * 16 & 15 非& 14 & * = 13 * 12 非= 11 = * 10 # * 9 = * 8 非= 7 %
* 6 ^ * 5 = * 4 非= 3 ! * 2
编译原理实习设计 词法分析程序
一.实习目的 构造一个小语言的词法分析程序。 二.实习要求 设计一个包含简单算术表达式、赋值语句、IF语 句的小语言的文法。 根据此文法,构造一个词法分析程序,输入 以“#”为结束符的源程序,输出为各类单词表和 单词串文件。 源程序和输出的单词串均以文件的形式存放。
if((ch=fgetc(fprogram))==EOF) { break; } } } else { break; } } Buffer[i]=ch; i++; } tmpch=ch; } else { break; } } if( IsDigit(ch) || IsLetter(ch) || ch=='.' || ch=='E' || ch=='e' || ch=='-') { while(1) { ch=fgetc(fprogram); if(ch!=EOF) { if(IsDigit(ch) || IsLetter(ch) || ch=='.' || ch=='E' || ch=='e' || ch=='-') { Buffer[i]=ch; i++; WordEnd=1; } else { if(ch==' ' || ch=='\t' || ch=='\n' ||
$NotQU $Weiyu $GESHICONTROL $mo-EQ $EQU $ EQ $and $Wyu $Whuo $Or $douhao $fenhao $Lpar $Rpar $Lmid $Rmid $Lbig $Rbig $Plus $Plus-Plus $Plus-EQ $dec $dec-dec $dec-EQ $Mul $Mul-EQ $Div $Div-EQ
ch=='\r') { break; } else { pos=ftell(fprogram); fseek(fprogram, pos-1,0); break; } } } else { break; } } } if(ch=='=' || ch=='+' || ch=='-' || ch=='*' || ch=='&' || ch=='^' || ch=='%' || ch=='<' || ch=='>' ) { while(1) { ch=fgetc(fprogram); if(ch!=EOF) { if(ch=='=' || ch=='+' || ch=='-' || ch=='*' || ch=='&' || ch=='^' || ch=='%' || ch=='<' || ch=='>' ) { Buffer[i]=ch; i++; WordEnd=1; } else { if(ch==' ' || ch=='\t' || ch=='\n' || ch=='\r' )
||
else { Output("$ID", string); } for(int i=0; i<k; i++) { string[i]=NULL; } break; } j++; } } if(IsDigit(c) ) { k=0; string[k++]=c; j++; while(1) { c=Get_ch(j); if(IsDigit(c) || c=='-' || c=='e' || c=='E' || c=='.') { string[k++]=c; } else { Output("$Digit", string); for(int i=0; i<k; i++) { string[i]=NULL; } break; } j++; } } if(c==';')
!= ^ % %= = == && & | || , ; ( ) [ ] { } + ++ += - ―― -= * *= / /=
四.源程序和结果 1.分析器程序
#include <stdio.h> #include <stdlib.h> #include <string.h> #define Max 120
} return 0; } void Proccess() { int i,j=0; char c; char string[Max]; for(int q=0; q<Max; q++) { string[q]=NULL; } WordEnd==1 ? i=Max*2 : i=Max; while(j<i) { int k=0; c=Get_ch(j); if(c=='#') { j++; while(1) { c=Get_ch(j); if(IsLetter(c) ) { string[k++]=c; } else if(c=='<' || c=='"') { Output("$ID", string); for(int p=0; p<k; p++) { string[p]=NULL; } k=0; while(1) { c=Get_ch(++j);
“双引
* 1
‘单引
空白
0
图四:界符和算符的识别(1)
2.单词符号对照表
单词符号 标志符 整数 浮点数 关键字 ‘ “ ! 助记符 $ID $Int $FLOAT $KeyWord $Syin $Yinhao $Not 内码值 字符串值 数值 数值 字符串值 ‘ “ !
!= ^ % %= = == && & | || , ; ( ) [ ] { } + ++ += - ―― -= * *= / /=
if(c=='>' || c=='"') { Output("$ID", string); for(int p=0; p<k; p++) { string[p]=NULL; } break; } else if( c=='.' || IsLetter(c) IsDigit(c) ) { string[k++]=c; } } break; } j++; } c=Get_ch(++j); } if(IsLetter(c) || c=='_') { k=0; string[k++]=c; j++; while(1) { c=Get_ch(j); if(IsLetter(c) || c=='_' || IsDigit(c)) { string[k++]=c; } else { if(IsKeyword(string) ) { Output("$keyword", string); }
break; case '[': str= "$Lmid"; break; case ']': str= "$Rmid"; break; case '{': str= "$Lbig"; break; case '}': str= "$Rbig"; break; default: break; } return str; } void WriteBuffer() { char tmpch=' '; int i=0; long pos; WordEnd=0; for(int t=0; t<Max*2; t++) { Buffer[t]=NULL; } while(i<Max) { ch=fgetc(fprogram); if(ch!=EOF) { if(ch=='\n' || ch=='\t' || ch==' ') { ch=' '; } if( !(tmpch==' ' && ch==' ') )
相关文档
最新文档