编译原理课程报告无符号数的词法分析程序
编译原理词法分析实验报告
编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的: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对象。
五、实验总结:通过本次实验,我熟悉了编译原理中词法分析的基本概念和原理,并掌握了正则表达式的使用方法。
我成功完成了一个简单的词法分析器的设计与实现,实现了源代码中每个词法单元的识别与输出。
这次实验对我深化了对编译原理中词法分析的理解,并提高了我的编程能力。
编译原理词法分析和语法分析报告 代码(C语言版)
admit=0;
for(in=0;in<cal-1;in++){str[in]=str[in+1];}
str[in]='\0';
cal--;
r_find=r_find->next;
}//:入栈~
if(r_find->line_States==s_find->num&&r_find->rank_Letter==str[0]&&r_find->name=='r'){//:规约
词法分析
三、词法分析程序的算法思想:
算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
3.1主程序示意图:
否
是
扫描子程序主要部分流程图
是是
否
字母
数字其他
运算符、符号
界符等符号
否
是
词法分析程序的C语言程序源代码:
//词法分析函数: void scan()
//数据传递:形参fp接收指向文本文件头的文件指针;
//全局变量buffer与line对应保存源文件字符及其行号,char_num保存字符总数。
void scan()
{
char ch;
int flag,j=0,i=-1;
while(!feof(fp1))
{
ch=fgetc(fp1);
flag=judge(ch);
struct Sign *next;
编译原理实验报告
编译原理实验报告班级姓名:学号:自我评定:实验一词法分析程序实现一、实验目的与要求通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。
二、实验内容根据教学要求并结合学生自己的兴趣和具体情况,从具有代表性的高级程序设计语言的各类典型单词中,选取一个适当大小的子集。
例如,可以完成无符号常数这一类典型单词的识别后,再完成一个尽可能兼顾到各种常数、关键字、标识符和各种运算符的扫描器的设计和实现。
输入:由符合或不符合所规定的单词类别结构的各类单词组成的源程序。
输出:把单词的字符形式的表示翻译成编译器的内部表示,即确定单词串的输出形式。
例如,所输出的每一单词均按形如(CLASS,VALUE)的二元式编码。
对于变量和常数,CLASS字段为相应的类别码;VALUE字段则是该标识符、常数的具体值或在其符号表中登记项的序号(要求在变量名表登记项中存放该标识符的字符串;常数表登记项中则存放该常数的二进制形式)。
对于关键字和运算符,采用一词一类的编码形式;由于采用一词一类的编码方式,所以仅需在二元式的CLASS字段上放置相应的单词的类别码,VALUE字段则为“空”。
另外,为便于查看由词法分析程序所输出的单词串,要求在CLASS字段上放置单词类别的助记符。
三、实现方法与环境词法分析是编译程序的第一个处理阶段,可以通过两种途径来构造词法分析程序。
其一是根据对语言中各类单词的某种描述或定义(如BNF),用手工的方式(例如可用C语言)构造词法分析程序。
一般地,可以根据文法或状态转换图构造相应的状态矩阵,该状态矩阵同控制程序便组成了编译器的词法分析程序;也可以根据文法或状态转换图直接编写词法分析程序。
构造词法分析程序的另外一种途径是所谓的词法分析程序的自动生成,即首先用正规式对语言中的各类单词符号进行词型描述,并分别指出在识别单词时,词法分析程序所应进行的语义处理工作,然后由一个所谓词法分析程序的构造程序对上述信息进行加工。
编译原理实验报告-词法分析
词法分析实验报告一、实验目的1.编制一个词法分析程序。
2.加深对词法分析原理的理解。
二、实验要求1.待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。
(2)运算符和界符: = + - * / < <= <> > >= = ; ( ) .(3)其他单词是标识符(IDENT)和整型常数(NUMBER),通过以下正规式定义:IDENT = letter (letter | digit)*NUMBER = digit digit*(4)空格有空白、制表符和换行符组成。
空格一般用来分隔IDENT、NUMBER、运算符、界符和关键字,词法分析阶段通常被忽略。
2.各种单词符号对应的类别值:表各种单词符号对应的类别码3.词法分析程序的功能:输入:所给文法的源程序字符串,以“.”结束。
输出:二元组(sym,token或number)构成的序列。
其中:sym为单词种别码;token为存放的单词自身字符串;number为整型常数。
例如:对源程序begin x:=9;if x<10 then x:=(x+10)*2 end.的源文件,经过词法分析后输出如下序列:(17,begin)(1,x)(16,:=)(2,9)(15,;)……4.词法分析程序的设计词法分析采用状态转换图方法:三、实验设计方法从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
主程序示意图:⑴关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:图3-11.主要技术难点a)设计各种单词符号对应的符号表b)实现输入字符数字和单词符号及其对应单词种别码的正确输出。
编译原理实验报告(词法分析器语法分析器)
编译原理实验报告实验一一、实验名称:词法分析器的设计二、实验目的: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)功能描述:该程序是实现一个词法分析器,词法分析器的功能是输入源程序,输出单词符号。
词法分析器的单词符号常常表示成以下的二元式(单词种别码,单词符号的属性值)。
本实验中,采用的是将单词分为五种的方法。
识别关键字: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数组中存放的字符,判断分离出关键字、标示符、数字、运算符、标示符。
编译原理课程设计词法分析
{
while((ch>='0')&&(ch<='9'))
{
sum=sum*10+ch-'0'; //ch中数字本身是当做字符存放的
ch=prog[p++];
}
if(ch=='.')
{
isDecimal=1;
ch=prog[p++];
while((ch>='0')&&(ch<='9'))
if(strcmp(token,rwtab[n])==0)
{
syn=n+1;
break;
}
}
elseif((ch>='0')&&(ch<='9'))
{
IsNum:
if(isSignal==1)
{
//token[m++]='-';
}
while((ch>='0')&&(ch<='9'))
{
sum=sum*10+ch-'0'; //ch中数字本身是当做字符存放的
sum为整型常数。
例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:
(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……
《编译原理》实验报告
ch2=='e'||ch2=='$' )
zf=1; elsh
zf=0; } if(ch1=='e'){ if(ch2>='0' && ch2<='9' && h<=1||ch2=='+'||ch2=='-')
zf=1; else zf=0; } if(ch1=='+' || ch1=='-'){
if(i==0) break; if(ch2>='0' && ch2<='9'||ch2=='$') zf=1; else zf=0; } if (zf==0) break; else i++; } if(zf==0) printf("Input number are error!\n"); else printf("Input number are right!\n"); }
(完整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=='.')。
编译原理实验 (词法语法分析报告 附源代码
编译原理实验报告******************************************************************************* ******************************************************************************* PL0语言功能简单、结构清晰、可读性强,而又具备了一般高级程序设计语言的必须部分,因而PL0语言的编译程序能充分体现一个高级语言编译程序实现的基本方法和技术。
PL/0语言文法的EBNF表示如下:<程序>::=<分程序>.<分程序> ::=[<常量说明>][<变量说明>][<过程说明>]<语句><常量说明> ::=CONST<常量定义>{,<常量定义>};<常量定义> ::=<标识符>=<无符号整数><无符号整数> ::= <数字>{<数字>}<变量说明> ::=VAR <标识符>{, <标识符>};<标识符> ::=<字母>{<字母>|<数字>}<过程说明> ::=<过程首部><分程序>{; <过程说明> };<过程首部> ::=PROCEDURE <标识符>;<语句> ::=<赋值语句>|<条件语句>|<当循环语句>|<过程调用语句>|<复合语句>|<读语句><写语句>|<空><赋值语句> ::=<标识符>:=<表达式><复合语句> ::=BEGIN <语句> {;<语句> }END<条件语句> ::= <表达式> <关系运算符> <表达式> |ODD<表达式><表达式> ::= [+|-]<项>{<加法运算符> <项>}<项> ::= <因子>{<乘法运算符> <因子>}<因子> ::= <标识符>|<无符号整数>| ‘(’<表达式>‘)’<加法运算符> ::= +|-<乘法运算符> ::= *|/<关系运算符> ::= =|#|<|<=|>|>=<条件语句> ::= IF <条件> THEN <语句><过程调用语句> ::= CALL 标识符<当循环语句> ::= WHILE <条件> DO <语句><读语句> ::= READ‘(’<标识符>{,<标识符>}‘)’<写语句> ::= WRITE‘(’<表达式>{,<表达式>}‘)’<字母> ::= a|b|…|X|Y|Z<数字> ::= 0|1|…|8|9【预处理】对于一个pl0文法首先应该进行一定的预处理,提取左公因式,消除左递归(直接或间接),接着就可以根据所得的文法进行编写代码。
《编译原理》课程实验报告(词法分析)
信息科学与工程学院__《编译原理》_实验报告系别计算机科学与工程专业计算机科学与应用班级_____计122_______学号_____10123544_____姓名_____ 陈柏君_________指导教师金登男2014学年第二学期1.实验题目:词法分析2.实验日期:2015.4.9-2015.4.163.实验环境(操作系统,开发语言)操作系统:Windows开发语言:C4.实验要求4.1.用C语言开发词法分析程序PL0Compiler。
4.2.修改PL/0词法,将其定义为一种新的语言,例如称其为PL/1语言,并完成PL/1语言的词法分析程序。
5.实验步骤5.1.用PL/0语言编写PL/0测试用例源程序,将其命名为Test0.pl。
5.2.用C语言开发PL/0词法分析程序PL0Compiler。
PL0Compiler读入Test0.pl,识别出一个个单词,并将这些单词流依序同时输出到屏幕和文件中。
被输出的每个单词应包括(1)单词序号(2)单词字符串(3)单词类型(4)单词值(如果是标识符,其值是字符串;如果是数,其值是数值;如果是符号,其值是ASCII代码…)在程序开发过程中,应设立断点,单步运行词法分析程序,依次输出一个个单词。
分析和理解词法分析程序,解释词法分析程序中的数据和变量变化的原因和输出结果。
5.3.研究其他程序设计语言,找出与PL/0词法不同的构词法则(例如C语言的标识符的组成规则与PL/0标识符的组成规则有所不同)。
据此修改PL/0的某些词法(例如,将PL/0标识符组成规则修改为C语言的标识符的组成规则),将其定义为一种新的语言,例如称其为PL/1语言。
5.4.用PL/1语言编写PL/1测试用例源程序,将其命名为Test1.pl。
5.5.开发PL/1词法分析程序PL1Compiler。
(可通过修改原PL0Compiler,实现PL/1语言的词法分析功能)。
5.6.PL1Compiler读入Test1.pl,识别出一个个单词,并将这些单词流依序同时输出到屏幕和文件中。
编译原理词法分析器实验报告
编译原理词法分析器实验报告1. 引言编译原理是计算机科学中的重要概念,它涉及将高级语言程序转换为计算机可执行的低级指令。
词法分析是编译过程中的第一个阶段,它负责将源代码分解为词法单元,为后续的语法分析做准备。
本实验旨在设计和实现一个基本的词法分析器,以了解词法分析的原理和实际应用。
2. 实验目标本实验的主要目标是实现一个基本的词法分析器,能够识别并提取源代码中的各种词法单元。
具体而言,我们将设计一个针对某种编程语言的词法分析器,能够识别关键字、标识符、算术运算符、括号、常量等。
3. 实验环境为了完成本实验,我们需要使用以下工具和环境:•一种编程语言,例如Python、Java或C++•一个文本编辑器,例如Visual Studio Code或Sublime Text•一个命令行终端4. 实验步骤4.1 定义词法规则首先,我们需要定义词法分析器的词法规则。
这些规则描述了编程语言中各种词法单元的模式。
例如,关键字可以被定义为由特定字符组成的字符串,标识符可以被定义为以字母开头并由字母和数字组成的字符串。
4.2 实现词法分析器接下来,我们将根据定义的词法规则,使用编程语言实现一个词法分析器。
在实现过程中,我们可以使用正则表达式来匹配和提取各种词法单元。
4.3 编写测试用例完成词法分析器的实现后,我们需要编写一些测试用例来验证其正确性。
测试用例应该包含各种可能的输入情况,以确保词法分析器能够正确地识别和提取词法单元。
4.4 运行测试用例最后,我们将使用编写的测试用例来运行词法分析器,并检查输出是否符合预期。
如果测试通过,说明词法分析器能够正常工作;否则,我们需要检查代码并进行调试。
5. 实验结果经过实验,我们成功地设计并实现了一个基本的词法分析器。
该词法分析器能够按照预定义的词法规则,正确地识别和提取源代码中的各种词法单元。
在运行测试用例时,词法分析器能够产生符合预期的输出,表明其具有良好的准确性和可靠性。
编译原理词法分析程序设计实验报告
编译原理词法分析程序设计实验报告【实验目的】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实现基本的词法分析器,能够分析关键字、标识符、数字、运算符(需要有“==”或“:=”之类需要超前搜索的运算符)以及其他一些符号。
编译原理的词法分析实现
一、实验内容识别无符号数的自动机。
二、实验要求根据无符号数的状态转换图(教材P51图3-3)写int isNumber(char *w);若w是无符号数,返回1,否则返回0。
三、实验目的理解词法分析中词“无符号数”的识别。
源程序#include<iostream.h>#include<ctype.h>#define LETTER 0#define DIGIT 1#define POINT 2#define OTHER 3#define POWER 4#define PLUS 5#define MINUS 6#define ClassNo 100#define ClassOther 200#define EndState -1#define N 500int Class;static int CurrentState;int EXCUTE(int state , int symbol){switch(state){case 0:switch(symbol){case DIGIT: CurrentState=1;Class=ClassNo;break;case POINT: CurrentState=3;Class=ClassNo;break;default:Class=ClassOther;CurrentState=EndState;}break;case 1:switch(symbol){case DIGIT: break;case POINT: CurrentState=2;break;case POWER: CurrentState=4;break;case LETTER: break;default:Class=ClassOther;CurrentState=EndState;}break;case 2:switch(symbol){case DIGIT: break;case POWER: CurrentState=4;break;case LETTER: break;default:Class=ClassOther;CurrentState=EndState;}break;case 3:switch(symbol){case DIGIT: CurrentState=2;break;default:Class=ClassOther;CurrentState=EndState;}break;case 4:switch(symbol){case DIGIT: CurrentState=6;break;case MINUS: CurrentState=5;break;case PLUS: CurrentState=5;break;default:Class=ClassOther;CurrentState=EndState;}break;case 5:switch(symbol){case DIGIT: CurrentState=6;break;default:Class=ClassOther;CurrentState=EndState;}break;case 6:switch(symbol){case DIGIT: break;case LETTER: break;default:Class=ClassOther;CurrentState=EndState;}break;}return CurrentState;}int getChar(char c){if(isdigit(c))return DIGIT;if(c=='.')return POINT;if(c=='E'||c=='e')return POWER;if(c=='+')return PLUS;if(c=='-')return MINUS;if(c=='\0')return LETTER;return OTHER;}int isNumber(char *w){int i=0;int nc;CurrentState=0;while(w[i]!='\0'){nc=getChar(w[i]);if(CurrentState != EndState){EXCUTE(CurrentState,nc);}elsebreak;i++;}nc=getChar(w[i]);if(CurrentState != EndState){EXCUTE(CurrentState,nc);}if(Class==100)return 1;elsereturn 0;}int main(){int t;cout<<"输入测试数据的个数"<<endl;cin>>t;cout<<"输入测试数据"<<endl;while(t--){char w[N];cin>>w;if(isNumber(w)==1)cout<<"Yes"<<endl;elsecout<<"No"<<endl;}return 0;}运行结果1)整数。
编译原理课程报告无符号数的词法分析程序
一.实验内容:掌握词法分析的基本思想,并用高级语言编写无符号数(包括整形和实数)的词法分析程序。
二.实验要求:从键盘上输入一串字符(包括字母,数字等),最后以”;”结束,编写程序识别出其中的无符号数。
三.实验源代码:#include<iostream>#include<cctype>#include<cstring>#include<cmath>using namespace std;int w=0; //尾数累加器int p=0; //指数累加器int j=0; //十进制小数位数计数器int e=1; //用来记录十进制数的符号,当指数为正时为1,为负时为-1int i=0; //用来标志元素位置int d=0; //用来表示每个数值型元素对应的数值const int N=40;//用来确定输入识别符的最大长度char data[N];//存放输入的识别符bool is_digit; //标志是否是数字string CJ1;//确定是整形还是实型double CJ2;//记数值//函数声明void check(char c);//检查首字母是否是数字的函数void deal_integer(char c);//处理识别符的整数部分void deal_point(char c);//用来处理小数部分void deal_index(char c);//用来处理指数部分void s_next();// 确定实型void z_next();//确定整型void last();// 计算CJ2void error();//程序中错误处理程序void deal();//处理函数主体int main(){ //主函数cout<<"please input your data,and its maximum length is "<<N<<":"<<endl;//等待用户输入识别符cin>>data;deal();//处理函数主体last();// 计算CJ2system("pause");return 0;}void check(char c) //判断输入的首字母是否是数字{is_digit=isdigit(c);while(is_digit!=true){//输入的首字母不是数字时cout<<"\nError! Try again.."<<endl;//要求重新输入cin>>data;check(data[0]);}}void deal_integer(char c){//处理识别符的整数部分d=(int)c-48;w=w*10+d;i++;if(isdigit(data[i])!=0)//下一个仍是数值时,调用程序本身deal_integer(data[i]);}void deal_point(char c){//用来处理小数部分int temp=i;if(isdigit(c)!=0)//是数值字符时deal_integer(c);else{ error(); //错误处理程序deal();//处理函数主体}j=i-temp;//记录十进制小数位数}void deal_index(char c){//用来处理指数部分if(c=='-') {e=-1;i++;}//是'-'号时else {if(c=='+') i++;//是'+' 号时else {if(isdigit(c)==false) //非数值字符时{ error();//错误处理程序deal();//处理函数主体}else{ d=(int)c-48;//把输入字符转换为整型goto pro2;}}}if(isdigit(data[i])!=0)pro1: d=(int)(data[i])-48;pro2: p=p*10+d;i++;if(isdigit(data[i])!=0)//是数值字符时goto pro1;else if(data[i]!='\0'){//非结束标志error();//错误处理程序deal();//处理函数主体}else s_next(); // 确定实型}void s_next(){// 确定实型i--;//退一个字符CJ1="实型";}void z_next(){//确定整型i--;//退一个字符CJ1="整型";}void last(){// 计算CJ2CJ2=w*pow((double)10,e*p-j);cout<<CJ1<<": "<<CJ2<<endl;//输出}void error(){//程序中错误处理程序cout<<"\nError! Try again.."<<endl;//重新输入数据cin>>data;p=0;w=0;j=0; //所有全局变量重新初始化e=1;i=0;d=0;//exit(0);}void deal(){check(data[0]);//判断输入的首字母是否是数字deal_integer(data[i]);//处理识别符的整数部分if(data[i]=='.'){ deal_point(data[++i]);//用来处理小数部分if(data[i]=='e'||data[i]=='E')//如果是e或E时deal_index(data[++i]);//用来处理指数部分else if(data[i]!='\0'){ error();//错误处理程序deal();//处理函数主体}else s_next();// 确定实型}else { if(data[i]=='e'||data[i]=='E')//如果是e或E时{ deal_index(data[++i]);//用来处理指数部分//CJ1="整型";}else if(data[i]!='\0'){ //非结束标志error();//错误处理程序deal();//处理函数主体}elsez_next();//确定整型}}四.实验结果截图:本科实验报告课程名称:编译原理实验项目:逆波兰式生成程序实验地点:迎西校区4506机房专业班级:学号:学生姓名:指导教师:2012年5月一.实验内容掌握语法分析的基本思想,并用高级语言编写逆波兰式生成程序。
编译原理语法分析程序
编译原理语法分析程序河北工业大学班级:软件121班姓名:张汉青注意先在执行目录下添加test.txt.源代码:#include<stdio.h>#include<stdlib.h>#include<ctype.h>#include<math.h>#include<afx.h>#include<string.h>#define DIGIT 1 //d#define POINT 2 //.#define OTHER 3 //other#define POWER 4 //即E#define PLUS 5 //+#define MINUS 6 //-#define UCON 7 //无符号数#define EndState -1 //结束状态int n=0,p=0,e=0,w=0; //用于计算无符号数的值int uint=0; //保存无符号整数double ufloat=0.0; //保存无符号实数char KeyWord[5][6]={{"if"},{"begin"},{"end"},{"then"},{"else"}}; //保留字CString Word=""; //临时保存词法分析程序的一个单词int row=0;//////程序记数器bool TZ=false;///表示程序没有出错FILE *fp;////源代码文件FILE *fp2;///词法输出文件//////函数原型声明int CharToInt(char c);int Judge(char c);int Identify(int state,char c,FILE *fp2,CString & w);int LookUp(char* p,char q[][6]);CString FirstisChar(char charactor,FILE *fp,FILE* fp2); CString Lexical(FILE* fp,FILE* fp2);void ZC();void E();void T();void F();///////////////////void main(){if((fp=fopen("test.txt","r"))==NULL){printf("文件打开失败!");exit(1);}if((fp2=fopen("result.txt","w"))==NULL){printf("文件打开失败!");exit(1);}ZC();printf("\n处理结束!\n");fclose(fp);fclose(fp2);}//总控程序void ZC(){while(Word!="EOF"){E();if(Word!="EOF"){if(Word!="#" || TZ==true)//出错{row++;//程序计数器加1printf("\n");printf("第%d句有错误!\n",row);while(Word!="#"){if(Word=="EOF"){return;}else{Word=Lexical(fp,fp2);}}}else{row++;//程序计数器加1printf("\n");printf("第%d句正确!\n",row);}}else{return;}}}////E产生式void E(){T();if(Word=="PL"||Word=="MI"){T();}else{return;}}////T产生式void T(){F();if(Word=="MU"||Word=="DI"){T();}else{return;}}//F产生式void F(){Word=Lexical(fp,fp2);//调用词法分析程序if(Word=="ID" || Word=="FCON" || Word=="ICON") {Word=Lexical(fp,fp2);return;}else if(Word=="LB"){E();if(Word=="RB"){Word=Lexical(fp,fp2);return;}else{TZ=true;//报错return;}}else{TZ=1;//报错return;}}/////词法分析程序CString Lexical(FILE* fp,FILE* fp2){char charactor;CString w="";while( (charactor=fgetc(fp))!=EOF ){/////第一个字符是单词if( (charactor>='a') && (charactor<='z') ){w=FirstisChar(charactor,fp,fp2);return w;}/////无符号数else if( (charactor>='0') &&(charactor<='9') ){fseek(fp,-1,1); //文件指针回溯int State=0; //初始状态char ch; //扫视字符while( (ch=fgetc(fp))!=EOF ){//////printf("ch=");/////putchar(ch);////printf("state=%d",State);//////printf("\n");State=Identify(State,ch,fp2,w);if(State==EndState){//////////////////printf("执行啦啦\n");fseek(fp,-1,1);//指针回溯break;}}}else if( charactor=='<' ){charactor=fgetc(fp);if(charactor=='='){w="LE";fprintf(fp2,"(LE, )");}else if(charactor=='>'){w="NE";fprintf(fp2,"(NE, )");}else{w="LT";fprintf(fp2,"(LT, )");}}////////////else if( charactor=='=' ) {w="EQ";fprintf(fp2,"(EQ,)");}////////else if( charactor=='>' ) {charactor=fgetc(fp);if( charactor=='=' ){w="GE";fprintf(fp2,"(GE, )");}else{w="GT";fprintf(fp2,"(GT, )");}}/////////else if( charactor==':'){charactor=fgetc(fp);////////////printf("执行了!");if( charactor == '=' ){w="IS";fprintf(fp2,"(IS, )");}else{w="";}}////////else if( charactor=='+' ){w="PL";fprintf(fp2,"(PL, )");}//////else if( charactor=='-' ){w="MI";fprintf(fp2,"(MI, )");}else if( charactor=='*' ){w="MU";fprintf(fp2,"(MU, )");}else if( charactor=='/' ){w="DI";fprintf(fp2,"(DI, )");}else if( charactor==' '){continue;}else if(charactor=='\t' || charactor=='\r' ||charactor=='\n') {continue;}else if(charactor=='('){w="LB";fprintf(fp2,"((, )");}else if(charactor==')'){w="RB";fprintf(fp2,"((, ))");}else if(charactor==';'){w="#";fprintf(fp2,"#");}else{w="";break;}return w;}if(charactor==EOF){w="EOF";return w;}return w;}///////词法分析程序中的,第一个字符是字母CString FirstisChar(char charactor,FILE* fp,FILE* fp2){//if( (charactor>='a') && (charactor<='z') )char Token[32];int i=0;Token[i]=charactor;///////////////////////////putchar(charactor);//printf("\n");while( (charactor=fgetc(fp))!=EOF ){if( ( (charactor>='a') && (charactor<='z') ) || ( (charactor>='1') && (charactor<='9') ) ){i++;Token[i]=charactor;///////////////////////////putchar(charactor);//printf("\n");}else{int tag=0;//标志,0表示标示符,非零表示保留字fseek(fp,-1,1);//指针回溯i++;Token[i]='\0';//字符串结束标志tag=LookUp(Token,KeyWord);//输出对应的保留字switch(tag){case 0:fprintf(fp2,"(ID,%s)",Token);return "ID";case 1:fprintf(fp2,"(IF, )");return "IF";case 2:fprintf(fp2,"(BEGIN, )");return "BEFIN";case 3:fprintf(fp2,"(END, )");return "END";case 4:fprintf(fp2,"(THEN, )");return "THEN";case 5:fprintf(fp2,"(ELSE, )");return "ELSE";}break;}}}/*字符型转换成整型形参为字符型返回值为整型*/int CharToInt(char c){return c-48;}/*判断输入字符的类型形参位字符型表示需要判断的字符返回值为整型表示该字符的类型*/int Judge(char c){int symbol;if(c>='0'&&c<='9') //为数字{symbol=DIGIT;}else if(c=='.') //为.{symbol=POINT;}else if(c=='E') //为E{symbol=POWER;}else if(c=='-'){symbol=MINUS;}else if(c=='+'){/////printf("执行+++++++++\n");symbol=PLUS;/////////////printf("symbol=?%d\n",symbol);}else //其他{symbol=OTHER;}return symbol;}/*识别过程形参为整型表示当前状态和字符型表示扫视字符返回值为整型表示后继状态*/int Identify(int state,char c,FILE*fp2,CString & word){int symbol;symbol=Judge(c);//判断字符的类型(数字、点、E、+、-或其他)switch(state){case 0:switch(symbol){case DIGIT:n=0;p=0;e=1;w=CharToInt(c);break;case POINT:w=0;n=0;p=0;e=1;state=3;break;default:state=EndState;word="";break;}break;case 1:switch(symbol){case DIGIT:w=w*10+CharToInt(c);state=1;break;case POINT:state=2;break;case POWER:state=4;break;default:uint=w;fprintf(fp2,"(ICON,%d)",uint);word="ICON";state=EndState;break;}break;case 2:switch(symbol){case DIGIT:n++;w=w*10+CharToInt(c);state=2;break;case POWER:state=4;default:ufloat=w*pow(10,e*p-n);fprintf(fp2,"(FCON,%lf)",ufloat);state=EndState;word="FCON";break;}break;case 3:switch(symbol){case DIGIT:n++;w=w*10+CharToInt(c);state=2;break;default:state=EndState;word="";break;}break;case 4:switch(symbol){case DIGIT:p=p*10+CharToInt(c);state=6;break;case MINUS:e=-1;state=5;break;case PLUS:state=5;break;default:state=EndState;word="";break;}break;case 5:switch(symbol){case DIGIT:////////////printf("执行状态5\n");p=p*10+CharToInt(c);state=6;break;default:state=EndState;word="";break;}break;case 6:switch(symbol){case DIGIT:p=p*10+CharToInt(c);state=6;break;default:///////////////printf("执行状态6\n");ufloat=w*pow(10,e*p-n);fprintf(fp2,"(FCON,%lf)",ufloat);state=EndState;word="FCON";break;}break;}return state;}int LookUp(char* p,char q[][6]){int tag=0;//标志,为0表示标示符,非零表示保留字for(int i=0;i<5;i++){if( strcmp(p,*(q+i)) ==0 ){tag=i+1;break;}}return tag;}。
编译原理词法分析,语法分析实验报告
char left[50];
/* 左部 */
char right[50][50];
/* 右部 */
char first[50][50],follow[50][50];
/* 各产生式右部的 FIRST 和左部的 FOLLOW 集合 */
char first1[50][50];
/* 所有单个符号的 FIRST 集合 */
int i,j,k,result=1,mark=0;
char temp[20];
temp[0]=c;
temp[1]='\0';
merge(empt,temp,1);
if(in(c,empty)==1)
return(1);
for(i=0;;i++)
{
if(i==count)
return(0);
if(left[i]==c)
}
/*******************************************
将单个符号或符号串并入另一符号串 ********************************************/
void merge(char *d,char *s,int type)
{
/*d 是目标符号串, s 是源串, type=1,源串中的‘ ^ ’一并并入目串;
int count=0;
/* 分解的产生式的个数 */
int number;
/* 所有终结符和非终结符的总数 */
char start;
/* 开始符号 */
char termin[50];
/* 终结符号 */
char non_ter[50];
编译原理实习设计——词法分析程序
图三:实数的识别
} 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); }
!= ^ % %= = == && & | || , ; ( ) [ ] { } + ++ += - ―― -= * *= / /=
编译原理实验报告(一)----词法分析程序
结束
是 转关键字和标识符处理
是 转数字处理
是 转运算符处理
)[p--8]
{[p--23] char[k--0] ch[i--5] ;[p--13]
关闭所有文件
下面简要分析一下词法分析程序的运行流程:
能否打开所要编译的 C 语言文 件
能
判断当前字符是否是文件结束符
否
报错 是
否
是
从源判程断序当中前读字入符一是行否到是数’组\n缓’ 冲区
否
判断当前字符是否是字母
否 判断当前字符是否是数字
否 判断当前字符是否是运算符
否
【程序调试】 现有源程序 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]
"fclose","exit","r","read","close","w","fprintf"};
词法分析程序生成实验
无符号数的词法分析程序一、实验课程的性质、目的和任务1.培养学生初步掌握编译原理实验的技能。
2.验证所学理论、巩固所学知识并加深理解。
3.对学生进行实验研究的基本训练。
二、实验内容掌握词法分析的基本思想,并用高级语言编写无符号数的词法分析程序。
三、实验要求从键盘上输入一串字符(包括字母、数字等),最后以“;”结束,编写程序识别出其中的无符号数。
四、无符号数语法规则<无符号数>→<无符号实数>│<无符号整数><无符号实数>→<无符号整数>.<数字串>[E<比例因子>]│<无符号整数>E<比例因子><比例因子>→<有符号整数><有符号整数>→[+│-]<无符号整数><无符号整数>→<数字串><数字串>→<数字>{<数字>}<数字>→0 1 2 3 (9)五、实验流程图六、实验源代码#include<stdio.h>#include<stdlib.h>#include <errno.h>#include<ctype.h>#include<math.h>#define N 50char UnsignedNumber[N] ;/*用来储存提取出来的无符号数字符串*/ /*识别已经提取出来的无符号数字符串*/void ReadUnsignedNumber(){int w=0 ;int p=0 ;int j=0 ;int i=0 ;short e=1 ;short d=0 ;double DataValue ;while(isdigit(UnsignedNumber[i])){d=UnsignedNumber[i]-48 ;w=w*10+d ;i++ ;}if(UnsignedNumber[i]=='.'){i++ ;while(isdigit(UnsignedNumber[i])){d=UnsignedNumber[i]-48 ;w=w*10+d ;j++ ;i++ ;}if(UnsignedNumber[i]=='\0'){DataValue=w*pow(10,e*p-j) ;printf("The value of %s is %f\n",UnsignedNumber,DataV alue) ;}else if(UnsignedNumber[i]=='e'||UnsignedNumber[i]=='E'){i++ ;if(UnsignedNumber[i]=='-'){e=-1 ;i++ ;}else if(UnsignedNumber[i]=='+'){i++;}do{d=UnsignedNumber[i]-48 ;p=p*10+d ;i++ ;}while(isdigit(UnsignedNumber[i]));DataValue=w*pow(10,e*p-j) ;printf("The value of %s is %f\n",UnsignedNumber,DataV alue) ;}}else if(UnsignedNumber[i]=='e'||UnsignedNumber[i]=='E'){ i++ ;if(UnsignedNumber[i]=='-'){e=-1 ;i++ ;}else if(UnsignedNumber[i]=='+'){i++;}do{d=UnsignedNumber[i]-48 ;p=p*10+d ;i++;}while(isdigit(UnsignedNumber[i])) ;DataValue=w*pow(10,e*p-j) ;printf("The value of %s is %f\n",UnsignedNumber,DataV alue) ; }else{DataValue=w ;printf("The value of %s is %f\n",UnsignedNumber,DataV alue) ;}if (errno == ERANGE){printf("Overflow condition occurred!\n");}}int main(){char ch ;int i ;int flag=0 ;printf("Please input the data with ';' to end!\n") ;ch=getchar() ;/*扫描输入的字符串,从中提取无符号数字符串*/while(ch!=';'){i=0 ;while(!isdigit(ch)){if(ch==';'){break ;}ch=getchar() ;}while(isdigit(ch)){UnsignedNumber[i]=ch ;i++ ;ch=getchar() ;}if(ch=='.'){UnsignedNumber[i]=ch ;i++ ;ch=getchar() ;while(isdigit(ch)){UnsignedNumber[i]=ch ;i++ ;ch=getchar() ;}if(ch=='e'||ch=='E'){UnsignedNumber[i]=ch ;i++ ;ch=getchar() ;if(!isdigit(ch)){if(ch=='+'||ch=='-'){UnsignedNumber[i]=ch ;i++ ;ch=getchar();if(!isdigit(ch)){i-- ;UnsignedNumber[i]='\0' ;}else{do{UnsignedNumber[i]=ch ;i++ ;ch=getchar() ;}while(isdigit(ch)) ;if(ch=='.'){printf("The data you input is wrong!\n") ;exit(1) ;}else{UnsignedNumber[i]='\0' ;}}}else{i-- ;UnsignedNumber[i]='\0' ;}}else{do{UnsignedNumber[i]=ch ;i++ ;ch=getchar() ;}while(isdigit(ch)) ;if(ch=='.'){printf("The data you input is wrong!\n") ;exit(1) ;}else{UnsignedNumber[i]='\0' ;}}}else{UnsignedNumber[i]='\0' ;}}else if(ch=='e'||ch=='E'){UnsignedNumber[i]=ch ;i++ ;ch=getchar() ;if(!isdigit(ch)){if(ch=='+'||ch=='-'){UnsignedNumber[i]=ch ;i++ ;ch=getchar();if(!isdigit(ch)){i-- ;UnsignedNumber[i]='\0' ;}else{do{UnsignedNumber[i]=ch ;i++ ;ch=getchar() ;}while(isdigit(ch)) ;if(ch=='.'){printf("The data you input is wrong!\n") ;exit(1) ;}else{UnsignedNumber[i]='\0' ;}}}else{UnsignedNumber[i]='\0' ;}}else{do{UnsignedNumber[i]=ch ;i++ ;ch=getchar() ;}while(isdigit(ch)) ;if(ch=='.'){printf("The data you input is wrong!\n") ;exit(1) ;}else{UnsignedNumber[i]='\0' ;}}}else{UnsignedNumber[i]='\0' ;}if(i!=0){ReadUnsignedNumber() ;flag=1 ;}if(flag==0){printf("Sorry!There is no unsigned number in your data!\n") ;}}return 0 ;}七、实验结果。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一.实验内容:掌握词法分析的基本思想,并用高级语言编写无符号数(包括整形和实数)的词法分析程序。
二.实验要求:从键盘上输入一串字符(包括字母,数字等),最后以”;”结束,编写程序识别出其中的无符号数。
三.实验源代码:#include<iostream>#include<cctype>#include<cstring>#include<cmath>using namespace std;int w=0; //尾数累加器int p=0; //指数累加器int j=0; //十进制小数位数计数器int e=1; //用来记录十进制数的符号,当指数为正时为1,为负时为-1int i=0; //用来标志元素位置int d=0; //用来表示每个数值型元素对应的数值const int N=40;//用来确定输入识别符的最大长度char data[N];//存放输入的识别符bool is_digit; //标志是否是数字string CJ1;//确定是整形还是实型double CJ2;//记数值//函数声明void check(char c);//检查首字母是否是数字的函数void deal_integer(char c);//处理识别符的整数部分void deal_point(char c);//用来处理小数部分void deal_index(char c);//用来处理指数部分void s_next();// 确定实型void z_next();//确定整型void last();// 计算CJ2void error();//程序中错误处理程序void deal();//处理函数主体int main(){ //主函数cout<<"please input your data,and its maximum length is "<<N<<":"<<endl;//等待用户输入识别符cin>>data;deal();//处理函数主体last();// 计算CJ2system("pause");return 0;}void check(char c) //判断输入的首字母是否是数字{is_digit=isdigit(c);while(is_digit!=true){//输入的首字母不是数字时cout<<"\nError! Try again.."<<endl;//要求重新输入cin>>data;check(data[0]);}}void deal_integer(char c){//处理识别符的整数部分d=(int)c-48;w=w*10+d;i++;if(isdigit(data[i])!=0)//下一个仍是数值时,调用程序本身deal_integer(data[i]);}void deal_point(char c){//用来处理小数部分int temp=i;if(isdigit(c)!=0)//是数值字符时deal_integer(c);else{ error(); //错误处理程序deal();//处理函数主体}j=i-temp;//记录十进制小数位数}void deal_index(char c){//用来处理指数部分if(c=='-') {e=-1;i++;}//是'-'号时else {if(c=='+') i++;//是'+' 号时else {if(isdigit(c)==false) //非数值字符时{ error();//错误处理程序deal();//处理函数主体}else{ d=(int)c-48;//把输入字符转换为整型goto pro2;}}}if(isdigit(data[i])!=0)pro1: d=(int)(data[i])-48;pro2: p=p*10+d;i++;if(isdigit(data[i])!=0)//是数值字符时goto pro1;else if(data[i]!='\0'){//非结束标志error();//错误处理程序deal();//处理函数主体}else s_next(); // 确定实型}void s_next(){// 确定实型i--;//退一个字符CJ1="实型";}void z_next(){//确定整型i--;//退一个字符CJ1="整型";}void last(){// 计算CJ2CJ2=w*pow((double)10,e*p-j);cout<<CJ1<<": "<<CJ2<<endl;//输出}void error(){//程序中错误处理程序cout<<"\nError! Try again.."<<endl;//重新输入数据cin>>data;p=0;w=0;j=0; //所有全局变量重新初始化e=1;i=0;d=0;//exit(0);}void deal(){check(data[0]);//判断输入的首字母是否是数字deal_integer(data[i]);//处理识别符的整数部分if(data[i]=='.'){ deal_point(data[++i]);//用来处理小数部分if(data[i]=='e'||data[i]=='E')//如果是e或E时deal_index(data[++i]);//用来处理指数部分else if(data[i]!='\0'){ error();//错误处理程序deal();//处理函数主体}else s_next();// 确定实型}else { if(data[i]=='e'||data[i]=='E')//如果是e或E时{ deal_index(data[++i]);//用来处理指数部分//CJ1="整型";}else if(data[i]!='\0'){ //非结束标志error();//错误处理程序deal();//处理函数主体}elsez_next();//确定整型}}四.实验结果截图:本科实验报告课程名称:编译原理实验项目:逆波兰式生成程序实验地点:迎西校区4506机房专业班级:学号:学生姓名:指导教师:2012年5月一.实验内容掌握语法分析的基本思想,并用高级语言编写逆波兰式生成程序。
二.实验要求将非后缀式用来表示的算术表达式转换为用逆波兰式来表示的算术表达式。
三.实验过程1、逆波兰式生成的实验设计思想及算法(1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。
(2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“#”。
(3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。
(4)如果不是数字,该字符则是运算符,此时需比较优先关系。
做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。
如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。
倘若不是的话,则将此运算符栈顶的运算符从栈中弹出,将该字符入栈。
(5)重复上述操作(1)-(2)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。
2.实验的源程序代码如下:#include<stdio.h>#include<math.h>#define max 100char ex[max]; /*存储后缀表达式*/void trans(){ /*将算术表达式转化为后缀表达式*/char str[max]; /*存储原算术表达式*/char stack[max]; /*作为栈使用*/char ch;int sum,i,j,t,top=0;printf("*****************************************\n");printf("*输入一个求值的表达式,以#结束。
*\n");printf("******************************************\n");printf("算数表达式:");i=0; /*获取用户输入的表达式*/do{i++;scanf("%c",&str[i]);}while(str[i]!='#' && i!=max);sum=i;t=1;i=1;ch=str[i];i++;while(ch!='#'){switch(ch){case '(': /*判定为左括号*/top++;stack[top]=ch;break;case ')': /*判定为右括号*/while(stack[top]!='('){ex[t]=stack[top];top--;t++;}top--;break;case '+': /*判定为加减号*/case '-':while(top!=0&&stack[top]!='('){ex[t]=stack[top];top--;t++;}top++;stack[top]=ch;break;case '*': /*判定为乘除号*/case '/':while(stack[top]=='*'||stack[top]=='/'){ex[t]=stack[top];top--;t++;}top++;stack[top]=ch;break;case ' ':break;default:while(ch>='0'&&ch<='9'){ /*判定为数字*/ ex[t]=ch;t++;ch=str[i];i++;}i--;ex[t]='#';t++;}ch=str[i];i++;}while(top!=0){ex[t]=stack[top];t++;top--;}ex[t]='#';printf("\n\t原来表达式:");for(j=1;j<sum;j++)printf("%c",str[j]);printf("\n\t后缀表达式:",ex);for(j=1;j<t;j++)printf("%c",ex[j]);}void compvalue(){ /*计算后缀表达式的值*/ float stack[max],d; /*作为栈使用*/char ch;int t=1,top=0; /*t为ex下标,top为stack下标*/ch=ex[t];t++;while(ch!='#'){switch(ch){case '+':stack[top-1]=stack[top-1]+stack[top];top--;break;case '-':stack[top-1]=stack[top-1]-stack[top];top--;break;case '*':stack[top-1]=stack[top-1]*stack[top];top--;break;case '/':if(stack[top]!=0)stack[top-1]=stack[top-1]/stack[top];else{printf("\n\t除零错误!\n");exit(0); /*异常退出*/}top--;break;default:d=0;while(ch>='0'&&ch<='9'){d=10*d+ch-'0'; /*将数字字符转化为对应的数值*/ch=ex[t];t++;}top++;stack[top]=d;}ch=ex[t];t++;}printf("\n\t计算结果:%g\n",stack[top]);}main(){trans();compvalue();}3.程序的运行结果如下:四.实验总结(心得)通过本实验的学习,主要掌握了逆波兰式算法的含义,结合书本知识,让我更加清楚此算法实现的主要过程,以及使用该算法的好处,通过对程序实现的分析,对于逆波兰式算法的细节了解的更加清楚,从中学到了很多的东西。