编译原理课设报告 C—编译器_第1页
编译原理课设报告 C—编译器_第2页
编译原理课设报告 C—编译器_第3页
编译原理课设报告 C—编译器_第4页
编译原理课设报告 C—编译器_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

编译原理课程设计实验报告书课设名称:C编译器班 级:学 号:姓 名: 指导老师: 2009年月 日 一、 程序简介本程序对符合C文法的源程序进行词法分析、语法分析、语义分析,并根据分析结果依次输出token链的内容、移进规约过程、符号表、参数表、函数列表和四元式链。词法分析和语义分析报错时可以指出在第几行。二、 主要算法及数据结构和函数模块1、 词法分析(1)主要算法这部分对源文件进行分析,允许/* */注释。从源文件依次读取字符,对字符进行分析,组成字符串、数字、关系符等固定含义的token符,并把它们添加到token链中,如果遇到非法字符报错并退出程序。 (2)数据结构#define INT 1/int#define VOID 2/void #define IF 3 / if#define ELSE 4 / else#define WHILE 5 / while#define RETURN 6 / return#define CONSTANT 7 /int型#define ID 8 /标识符#define RELOP 9 /关系符 、=、=、!=#define ADDOP 10 / +和-#define MULOP 11 / *和/#define L_BRACKET 12 /代表 #define R_BRACKET 13 /代表 #define L_PARENTHESE 14 /代表 (#define R_PARENTHESE 15 /代表 )#define L_BPARENTHESE 16 /代表 #define R_BPARENTHESE 17 /代表 #define SEMICOLON 18 /代表 ;#define COMMA 19 /代表 ,#define EQUATER 20 /代表 = #define $ 21 /终结符 typedef struct token/*词法分析中的 token结构体*char *name;/字符串int type;/类型int LineNum;/所在行数struct token *next;token;token *TokenHead,*TokenTail;(3)函数模块void LexicalAnalyzer();/词法分析int IsLetter(char ch);/判断是否是字母int IsDigit(char ch);/判断是否是数字void Concat(char strToken,char ch,int &strNum);/把字符连接到字符串尾int Reserve(char strToken);/判断字符串是否为关键字void ProcError(char ch,int num);/错误处理void TokenInsert(char *str,int type,int num,int LineNum);/添加Token链节点2、 语法分析(1) 主要思想这部分对Token链进行分析,利用自底向上的分析方法,构建SLR(1)分析表的过程是手工完成的。语法分析的同时构建语法树,移进时创建叶子,规约时创建节点。(2) 数据结构 typedef struct pank/*语法 action表结构体*char sr;/移进或归约int state;/转到的状态编号pank;pank action9721;/action表int go_to9729;/语法 go_to表typedef struct stack/*语法分析栈结构体*int state;/状态int word;/符号编码stack;typedef struct Tree_Node/*语法分析树*int code;/记录字符串对应编号char *word;/记录字符串int Rnum;/记录规约式的编号int LineNum;/记录字符所在行数char *place;/传递变量名称int E_type;/传递变量的类型struct Tree_Node *child1;struct Tree_Node *child2;struct Tree_Node *para;Tree_Node;Tree_Node *Head,*Tail;typedef struct ivan/*语法产生式结构体*int left;/产生式的左部int len;/产生式右部的长度ivan;ivan css56; /css56存的是55条规约式的左边非终结符的编号和右边规约的个数*/char *Grammar56; /*Grammar56存的是55条规约式char *Str29; /*Str29存的是29个非终结符(3) 函数模块void ParseAnalyzer();/语法分析void yufa_initialize(void);/ACTION 和GOTO表的初始化void CreatLeaf(int code,char *str,int LineNum);/创建语法树的叶子void CreatNode(int code,int Rnum,int num,char *str);/创建语法树的节点void OutPutTree(Tree_Node *p);/输出语法树3语义分析 (1)主要算法 这部分对语法树从左到右进行遍历,节点记录了规约式的编号,遍历到节点时就进行相应处理。语义分析主要检查变量、函数是否被定义或重定义,同时产生四元式。(2)数据结构typedef struct LF/*语义分析中四元式结构体*/int k;/四元式的编号char *op;/操作符char *op1;/操作数char *op2;/操作数char *result;/结果struct LF *next;/语义四元式向后指针struct LF *Ltrue;/回填true链向前指针struct LF *Lfalse;/回填false链向前指针LF;LF *L_four_head,*L_four_tail,*L_true_head,*L_true_tail;LF *L_false_head,*L_false_tail;/四元式链,true链,false链typedef struct symb/语义分析时的符号表int flag;/是否为数组int num;/数组长度char *word;/变量名称int addr;/变量地址struct symb *next;symb;symb *symb_head10,*symb_tail10;/语义符号链表typedef struct queue/*语义分析时的参数表*/char *word;/参数名char *type;/参数类型struct queue *next;queue;queue *queue_head10,*queue_tail10;typedef struct prob/*语义分析时的函数表*/int code;/函数起始位置char *type;/返回值类型char *name;/函数名symb *Sym;/对应符号表queue *Queue;/对应参数表prob;prob prob_head10;(3)函数模块void SemanticAnalyzer(Tree_Node *p);/语义分析void YuYIFenXi(Tree_Node *p);/语义分析void add_symb(symb *temp);/向语义符号表链中加一个结点void add_queue(queue *temp);/向参数链表中加入一个节点void add_prob(prob *temp);/向函数链表中加一个节点int CharToInt(char *w);/将字符串转化为整型char* num_to_char(int num);/将数字转化为char*类型;void add_L_four(LF *temp);/向四元式链中加一个结点void add_L_true(LF *temp);/向true链中加一个结点void add_L_false(LF *temp);/向false链中加一个结点void add_symb(symb *temp);/向语义符号表链中加一个结点void output_yuyi();/输出中间代码四元式和最后符号表char *newop(int m);/把数字变成字符串char *id_numtoname(int num);/把编号转换成相应的变量名int lookup(char *m);/变量声明检查int Look_up(char *m);/检查函数是否已经声明void OutPutSymb();/输出符号表void OutPutQueue();/输出参数表void OutPutProb();/输出函数表void OutPutFour();/输出四元式三、 所做工作负责词法分析。/#define MAX 1999;int Lexabc=0;int Lextokennum=0;int Lexerror1=0,Qiantao=0;int LexLines=1,LexColumns=0;int StrToken1=0;char ch= ,LexStrToken10;char ch1= ;int wrong=0;int Token,j=1;int Main=0; /判断原程序是否有主函数int error1=0;fstream LexFile;char infilename100;fstream file,outfile;struct key/用来存储关键字与专用符号char keystring7; /存储关键字和专用符号int value; /用一个简单数字对应一个关键字或专用符号Key28=main,1,else,2,if,3,int,4,return,5,void,6,while,7,+,8,-,9,*,10,/,11,12,14,=,15,=,16,!=,17,=,18,;,19,20,(,21,),22,23,24,25,26,ID,27,NUM,28; /关键字表/注意:以上结构体实现了一个数字对关键字字符串和专用符号的替代,这些/数字在整个编译器的设计与实现当中起到了很好的作用struct token /用来记录词法分析得到的单词符号的相关信息char lexeme10;/单词符号int list;/类型long int value;/单词符号的属性值int lines;/所在行int columns;/所在列LexToken1000,token1;/token1struct Lexerror/存储词法分析的错误信息char errorwords10;/非法单词符号int lines;/所在行int columns;/所在列int type;/错误类型LexError1100;void LexError(int errortype)/错误处理strcpy(LexError1Lexerror1.errorwords,LexStrToken);LexError1Lexerror1.lines=LexLines;LexError1Lexerror1.columns=LexColumns;LexError1Lexerror1.type=errortype;Lexerror1+=1;void openfile(char* filename)/打开源文件file.open(filename,ios:in|ios:binary);if(file.fail()=1)coutOpenfilenameFailed!endl;getch();exit(0);void openLexFile()/打开词法分析结果文件outfile.open(Lex.txt,ios:out|ios:binary);if(outfile.fail()coutOpen File Lex.txt Failed!endl;getch();exit(0);void WriteFile(token temp)/写入文件outfile.write(char*)&temp,sizeof(temp);char GetChar()/读字符file.get(ch);LexColumns+=1;if(ch=n)LexLines+=1;LexColumns=0;return ch;void GetBC()/略过空白符while(ch= )&(file.eof()=0)|(ch=n)&(file.eof()=0)|(ch=t)&(file.eof()=0)GetChar();void Concat()/字符归入字符串LexStrTokenStrToken1=ch;StrToken1+=1;bool IsLetter(char ch)if(ch=a)|(ch=A)return 1;return 0;bool IsDigit(char ch)if(ch=0)return 1;return 0;int Reserve()/获取单词符号的属性值ch= ;for(int i=0;i28;i+)if(strcmp(LexStrToken,Keyi.keystring)=0)return i+1;if(IsDigit(LexStrToken0)return 28; return 27;void Retract()/读文件指针回退一个字符file.seekg(-1l,ios:cur);LexColumns-=1; /?ch= ;void InsertID()/存单词符号int list;list=Reserve();strcpy(LexTokenLextokennum.lexeme,LexStrToken);LexTokenLextokennum.list=list;LexTokenLextokennum.columns=LexColumns;LexTokenLextokennum.lines=LexLines;LexTokenLextokennum.value=-1999;if(list=28) LexTokenLextokennum.value=atoi(LexStrToken);Lextokennum+=1;void Break()/跳过非法字符while(GetChar()!= )&(file.eof()=0) ;void LexOut()/词法输出for(int j=0;(j100)&(LexTokenj.lexeme0!=0);j+)cout setw(6)LexTokenj.lexeme, ;if(LexTokenj.list!=28) coutsetw(3)-endl;else coutsetw(3)LexTokenj.value0)cout*词法错误*endl;for(j=0;(j100)&(LexError1j.lines!=0);j+)cout*j+1.LexError1j.lines行LexError1j.columns列;if(LexError1j.type=2)coutLexError1j.errorwords 为非法标志符!endl;cout*endl;else cout程序无词法错误!endl;cout词法分析完成!任意键返回主菜单endl;getch();void Lex_main()int code;while(!file.eof()GetBC();if(file.eof() break;if(IsLetter(ch)while(IsLetter(ch)|IsDigit(ch)Concat();GetChar();Retract();code=Reserve();InsertID();else if(IsDigit(ch)while(IsDigit(ch)Concat(); GetChar();if(IsLetter(ch)Concat();LexError(2);Break();else InsertID();Retract();else if(ch=)|(ch=)|(ch=!)Concat();GetChar();if(ch=)Concat();InsertID();elseInsertID();Retract();else if(ch=/)GetChar();if(ch=*)if(Qiantao=1)LexError(3);Break();elseQiantao=1;for(;)ch1=ch;GetChar()

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论