编译原理实验报告(共27页).docx
精选优质文档-倾情为你奉上目录专心-专注-专业专业:计算机科学与技术学生姓名: 学 号: 完成时间:2022年5月3日编译原理实验报告实验一 词法分析器的设计与实现1)实验目的 掌握正规式、状态转换图、C语言单词符号的划分及词法分析器的实现 掌握词法分析程序的作用和接口。2)实验内容设计及实现C语言程序的词法分析器。3)实验要求 对任给的一个C语言源程序,能够虑掉空格、回车换行符、tab键及注释。 识别各类单词符号,如关键字、标识符、运算符、常数、界符,结果以二元式形式输出。并构造符号表。 输出有词法错误的单词及所在行号。4)实验原理根据扫描到的单词符号的第一个字符的种类,分别转到相应的程序进行处理。这些程序的功能就是识别以相应字符开头的各类单词符号。5)实验步骤 根据C语言各类单词的正规式,构造能识别各类单词的状态转换图。 根据状态转换图,构造识别各类单词的词法分析器。6)状态转化图及词法分析程序#include "ctype.h"#include "string.h"#include "stdio.h" FILE *fp;int id;void main() char cbuffer;char alphaprocess(char buffer);char digitprocess(char buffer);char otherprocess(char buffer); if (fp=fopen("example.c","r")=NULL) /*以只读方式打开文件"example.c",NULL在 stdio.h文件中已被定义为0*/ printf("error"); else cbuffer=fgetc(fp); /*文件不为空则从文件中取字符*/ while (cbuffer!=EOF) /*EOF文件结束标志*/ if(cbuffer=' '|cbuffer='n') /*掠过空格和回车符*/ cbuffer=fgetc(fp); id=4; else if(isalpha(cbuffer) cbuffer=alphaprocess(cbuffer); /*检查cbuffer是否为字母,是则调用alphaprocess()函数*/ else if (isdigit(cbuffer) cbuffer=digitprocess(cbuffer); /*检查cbuffer是否为数字09,是则调用digitprocess()函数*/ else cbuffer=otherprocess(cbuffer); /*非上述两者则调用otherprocess()函数*/ char alphaprocess(char buffer) int search(char searchchar,int wordtype); /*函数声明*/int atype; int i=-1;char alphatp20; /*字符数组存储从文件中读取的字符*/ while(isalpha(buffer)|(isdigit(buffer)|buffer='_') /*标识符的组成成分*/ alphatp+i=buffer; /*将当前读取的字符存如数组*/ buffer=fgetc(fp); /*读取下一个字符*/ alphatpi+1='0' /*字符串以'0'作为结束标志*/ atype=search(alphatp,1); /*调用函数,判断当前字符串是否为关键字*/ if(atype!=0) /*是关键字则输出该关键字,编号为1,并输出该关键字在关键字表中的位子*/ printf("(%s, (1,%d)n",alphatp,atype); id=1; /*关键字的ID为1*/ else printf("(%s ,2)n",alphatp); /*为标识符时,编号为2*/ id=2; /*标识符的ID为2*/ return(buffer); /*判断字符串是否为关键字*/int search(char searchchar,int wordtype)char * key32="auto","break","case","char","const","continue","default","do", "double","else","enum","extern","float","for","goto","if","int","long", "register","return","short","signed","sizeof","static","struct", "volatile","while","switch","typedef","union","unsigned","void" /*设置数组指针存储c语言中的32个关键字*/ int i; int p; switch (wordtype) case 1:for (i=0;i<=31;i+) if (strcmp(keyi,searchchar)=0) /*比较字符串,为关键字则定位该关键字的序号*/ p=i+1; break; else p=0;return(p); char digitprocess(char buffer)int i=-1;char digittp20;while (isdigit(buffer)|buffer='.'|buffer='e'|buffer='E')/考虑数字为小数和指数时的情况 digittp+i=buffer; buffer=fgetc(fp); /*同上*/ digittpi+1='0'printf("(%s ,3)n",digittp); /*输出该数字,编号为3*/id=3; /*设置ID为3*/return(buffer);char otherprocess(char buffer) int n=0; char ch20; ch0=buffer; ch1='0'if(ch0='%'|ch0='') buffer=fgetc(fp); ch1=buffer; ch2='0' printf("(%s ,5)n",ch); id=4; buffer=fgetc(fp); return(buffer);if(ch0='&')buffer=fgetc(fp); if(buffer!='&') printf("(%s ,5)n",ch); id=4; return(buffer); if(buffer='&') ch1=buffer; ch2='0' printf("(%s ,4)n",ch); id=3; buffer=fgetc(fp); return(buffer); if(ch0=','|ch0=''|ch0=''|ch0=''|ch0='('|ch0=')') printf("(%s ,5)n",ch); buffer=fgetc(fp); id=4; return(buffer); if(ch0='*'|ch0='/') printf("(%s ,4)n",ch); buffer=fgetc(fp); id=4; return(buffer); if(ch0='='|ch0='!'|ch0='<'|ch0='>') buffer=fgetc(fp); if(buffer='=') /*防止'=','!=','<=','>='符号的分离*/ ch1=buffer; ch2='0' printf("(%s ,4)n",ch); else printf("(%s ,4)n",ch);id=4;return(buffer); buffer=fgetc(fp); id=4; return(buffer); if(ch0='+'|ch0='-') if(id=4) /*如果'+','-'前ID为4的字符则可能为正负数或'+','-',否则为加减号*/ for(int i=1;i<10;i+) buffer=fgetc(fp); if(buffer='+') ch1='+'ch2='0' id=4; printf("(%s ,4)n",ch); buffer=fgetc(fp);id=4;return(buffer); if(buffer='-') ch1='-' ch2='0' id=4; printf("(%s ,4)n",ch); buffer=fgetc(fp);id=4;return(buffer); if(buffer=',')|(buffer='')|(buffer='+')|(buffer='-')|(buffer=')') break; /*防止将+562;+562,+562+,+562-,+561)作为整体输出*/ chi=buffer; chi+1='0' printf("(%s ,3)n",ch); id=3; /buffer=fgetc(fp); return(buffer); ch2='0' printf("(%s ,wrong word!)n",ch); buffer=fgetc(fp); id=4; return(buffer);7)测试实验二 语法分析器的设计与实现1)实验目的掌握自上而下语法分析方法、自下而上语法分析方法分析思路。2)实验内容 设计及实现能够识别表达式的预测分析程序。文法如下:GE:E->E+T|T T->T*F|F F->(E)|i 设计及实现能够识别表达式的LR分析程序。 文法如下:GE:E->E+T|T T->T*F|F F->(E)|i3)实验要求 对已给的一个二元式形式表达式,能够检查有无语法错误。并指定出错位置。 将表达式的语法分析过程输出。4)实验原理根据自上而下和自下而上的语法分析思想实现语法分析程序。5)实验步骤 根据文法构造语法分析表。 编写总控程序实现语法分析。6)语法分析程序#include "stdafx.h"#include "malloc.h"#include "stdio.h"#include "string.h"#define STACK_INIT_SIZE 20#define SENTENCE_LEN 10#define true 1#define false 0/分析表存储。为了计算对应关系方便,为每个数组多分配一个空间,/vn0,vt0,candistring0,并不使用/ 每个候选式与vn,vt的关系是:(i-1)*6+j,i为vn的标号,j为vt的下标 /用?替代 char vn6='0','E','A','T','B','F' char vt7='0','i','+','*','(',')','#' char candistring314= "0","AT","", "", "AT", "", "","", "AT+","", "", "?","?","BF", "", "", "BF", "", "","", "?","BF*","", "?","?","i", "", "", ")E(","", ""/ i/E TE'/栈结构设计 struct stack char *base; char *top; int stacksize; ; /栈初始化 intInitStack(stack &s)s.base=(char *)malloc(STACK_INIT_SIZE*sizeof(char);if (!s.base) printf("stack overflow!n");return 0;s.top=s.base-1;s.stacksize=STACK_INIT_SIZE;return 1;/说明空间分配成功/入栈操作,成功返回1。只入栈,没有判断栈是否满int PushStack(stack &s,char chstring4)int i=0;while (chstringi!='0')s.top +;*(s.top)=chstringi;i+; return 1;/出栈操作。未判断栈是否空。若成功,返回出栈符号。char PopStack(stack &s)char ch; ch=*(s.top) ; s.top-; return ch;int Search(char resultstring4,char vnchar,char inputchar )int i,j;/查询非终结符的编号存入ifor(i=1;i<6;i+)if(vnchar=vni)break;/查询与输入符号同的终结符的编号存入jfor(j=1;j<7;j+)if(inputchar=vtj) break; strcpy(resultstring, candistring(i-1)*6+j); if (resultstring="") return 0; else return 1; /初始化化sentence,读取句子,并将最后字符之后增加int readsentence(char s) int i;scanf("%s",s);i=0; while(si!='0')i+;si='#'si+1='0' return 1;/判断x是否为vt。/和char vt7='0','i','+','*','(',')','#'中除#元素进行比较。 int xIsVt(char x)int flag;int i=1;flag=false; while(!flag && i<5 )if (x=vti)flag=true;else i+;if (flag)return 1; /说明x是终结符elsereturn 0;/出错处理void errordo(char ch)printf("%c is wrong here!n",ch);/分析过程输出void OutputAnalyse(int outnum,stack &s,char senstringSENTENCE_LEN,char nowi,char vnchar,char results4) char pSTACK_INIT_SIZE="" /r7用来存储所用产生式 char r7; char *q=s.base; int i=0,j=0; /输出编号 printf("%-5d",outnum); /输出栈中内容 while(q<=s.top)pi=*q;i+;q+; pi='0' printf("%-20s%",p); /输出句子中剩余内容 q=&(senstringnowi); printf("%10s",q); /输出所用产生式 if (results0='0') printf("n"); elser0=vnchar;r1='-'r2='>' i=0;/找到逆候选式的末尾之后while(resultsi!='0') i+;/找到逆候选式的末尾符号resulti i-;/存储候选式正序内容j=3;while(i>=0) rj=resultsi;j+;i-;rj='0' printf("%20sn",r); int main(int argc, char* argv)/flag用来标识识别过程是否继续int flag;int i=0;char sentenceSENTENCE_LEN; /存储要识别的句子。/ch用于读取识别句子中的字符,X用于存储上托出去的栈顶符号char ch,x;/results用来存储查找分析表的结果char results4=""/outnum描述输出编号 int outnum=0;/定义存储分析过程的栈stack s;/为栈分配空间InitStack(s);/初始化化sentence,读取句子,并将最后字符之后增加。readsentence(sentence);/初始化栈和输入符号PushStack(s,"#E");ch=sentencei; /初始化输出内容printf("%-5d%-20s%10s%20sn",outnum,"符号栈","输入串","产生式");outnum+; /识别句子是否合法,并将分析过程输出/flag用来标识识别过程是否继续flag=true; /通过循环反复执行匹配、推导,成功或出错处理操作while(flag) x=PopStack(s); if (xIsVt(x) if(x=ch) OutputAnalyse(outnum,s,sentence,i+1,x,""); outnum+; i+; ch=sentencei; else errordo(ch);/ch的出现是语法错误 break; else if(x='#')if(x=ch)flag=false;printf("%-5d%-20s%10s%20sn",outnum,"#","#","");printf("分析成功!");else errordo(ch);break; else if(Search(results,x,ch) if(results0!='?')PushStack(s,results); OutputAnalyse(outnum,s,sentence,i,x,results); outnum+; else errordo(ch);break; return 0;7)测试