logo资料库

编译原理实验报告(有源程序和具体分析步骤).pdf

第1页 / 共52页
第2页 / 共52页
第3页 / 共52页
第4页 / 共52页
第5页 / 共52页
第6页 / 共52页
第7页 / 共52页
第8页 / 共52页
资料共52页,剩余部分请下载后查看
编译原理实验报告 姓名:布凡 学号:04070008 指导老师:蒋宗礼 完成日期:2007-6-19
实验一:词法分析 1. 实验目的 实现一个词法分析程序,将输入字符串流分解成终结符流供语法分析使用。 2. 实验内容 编制一个能够分析三种整数、三种浮点数、标识符、主要运算符和主要关键字的词法分 析程序。 3. 实验要求 编写能识别下列正规式的词法分析程序。 标识符 <字母>(<字母>|<数字字符 >)*(ε|_|.)(<字母>|<数字字符 >)* 十进制实数 (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|8|9)(0|1|2|3|4|5|6|7|8|9) * 八进制实数 0(0|1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7) * .(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) * .(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) * 十进制整数 0 | (1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9) * 八进制整数 0(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 do 4. 词法的状态转换图 ε 1---9 0---9 . 0---9 1 2 5 6 7 0---9 0---7 . 0 0---7 8 9 0---7 . 0---f x 12 0---7 11 10 0---f . 0---f 0---f 13 14 15 ε ε 3 3 0---9| a---z | A---Z 0---9| a---z | A---Z a---z | A---Z .|_ a---z | A---Z|0--9 16 17 18 + - * / > < = ( ) ; # || { } && == # 19 2
temp.code=28; 5. 词法分析的数据结构 typedef struct{ int code; //分析出的词元的编号 char value[VALUELEN];// 分析出的词元 的值(标识符或数值) }Elem; 6.词法分析的算法 Elem Scan() { Elem temp; int vlen=0; GetBC(); if(curchar=='#') { temp.value[vlen++]='\0'; } if(IsLetter(curchar)) { while(IsLetter(curchar)||IsDigit(curchar)) { } while(IsLetter(curchar)||IsDigit(curchar)) if(curchar=='_'||curchar=='.') { Concat(temp.value,vlen); { Concat(temp.value,vlen); GetChar(); } Concat(temp.value,vlen); GetChar(); return temp; GetChar(); 3 { return temp; temp.value[0]='\0'; if(curchar=='0') { if(temp.code!=0) } temp.value[vlen++]='\0'; temp.code=IsKeyWord(temp.value); Retract(); } else if(IsDigit(curchar)) { Concat(temp.value,vlen); GetChar(); if(!IsOctDigit(curchar)&&curchar!='.'&&curc har!='x'&&curchar!='X')//int10 (0) temp.code=2; else if(curchar=='.')//real10 (0.) Concat(temp.value,vlen); GetChar(); { while(IsDigit(curchar)) { Concat(temp.value,vlen); temp.code=5; temp.value[vlen++]='\0'; temp.value[vlen++]='\0'; Retract(); return temp; GetChar(); Retract(); return temp; } if(IsDigit(curchar)) } {
{ } { } else { if(IsHexDigit(curchar)) Concat(temp.value,vlen); GetChar(); return temp; Error(3); temp.code=-1; } else if(curchar=='x'||curchar=='X')//int16 real16 GetChar(); { while(IsHexDigit(curchar)) Concat(temp.value,vlen); temp.code=3; temp.value[vlen++]='\0'; ToDecimal(temp.value,16); Concat(temp.value,vlen); GetChar(); if(IsHexDigit(curchar)) { while(IsHexDigit(curchar)) { if(curchar!='.') { Retract(); return temp; } } 4 } } return temp; else { Retract(); } else { GetChar(); return temp; Concat(temp.value,vlen); temp.code=6; temp.value[vlen++]='\0'; ToDecimal(temp.value,1616); } Error(3); temp.code=-1; Error(4); temp.code=-1; } else //int8 real8 while(IsOctDigit(curchar)) { Concat(temp.value,vlen); temp.code=1; temp.value[vlen++]='\0'; GetChar(); return temp; } if(curchar!='.') { Retract(); } {
} Retract(); return temp; } GetChar(); GetChar(); if(IsOctDigit(curchar)) { ToDecimal(temp.value,8); Concat(temp.value,vlen); while(IsOctDigit(curchar)) { Concat(temp.value,vlen); temp.code=4; temp.value[vlen++]='\0'; ToDecimal(temp.value,88); Error(3); temp.code=-1; while(IsDigit(curchar)) { Concat(temp.value,vlen); temp.code=2; return temp; } else //int10 or real10 { GetChar(); } if(curchar!='.') { temp.value[vlen++]='\0'; } else { return temp; } } 5 temp.value[vlen++]='\0'; Retract(); } { } Retract(); return temp; GetChar(); GetChar(); if(IsDigit(curchar)) { return temp; } else { Concat(temp.value,vlen); while(IsDigit(curchar)) Concat(temp.value,vlen); temp.code=5; Error(3); temp.code=-1; } else if(curchar=='+') { temp.code=12; } else if(curchar=='-') { temp.code=13; } else if(curchar=='*') { temp.code=14; temp.value[vlen++]='\0'; return temp; temp.value[vlen++]='\0'; return temp; return temp; temp.value[vlen++]='\0'; } }
temp.value[vlen++]='\0'; return temp; temp.value[vlen++]='\0'; return temp; temp.value[vlen++]='\0'; return temp; return temp; } else if(curchar=='/') { temp.code=15; } else if(curchar=='>') { temp.code=16; } else if(curchar=='<') { temp.code=17; } else if(curchar=='=') { GetChar(); temp.code=27; temp.code=18; } else if(curchar=='(') { temp.code=19; } else if(curchar==')') { temp.code=20; return temp; } if(curchar=='=') { temp.value[vlen++]='\0'; Retract(); return temp; temp.value[vlen++]='\0'; temp.value[vlen++]='\0'; return temp; temp.value[vlen++]='\0'; return temp; temp.value[vlen++]='\0'; return temp; } else if(curchar==';') { temp.code=21; } else if(curchar=='{') { temp.code=22; temp.value[vlen++]='\0'; return temp; } else if(curchar=='}') { temp.code=23; } else if(curchar=='|') { temp.code=-1; return temp;} temp.code=24; } else if(curchar=='&') { Error(1); temp.code=-1; temp.code=25; } GetChar(); if(curchar!='&') { temp.value[vlen++]='\0'; return temp; temp.value[vlen++]='\0'; return temp; GetChar(); if(curchar!='|') { Error(1); temp.value[vlen++]='\0'; return temp; return temp; } 6
temp.value[vlen++]='\0'; return temp; else if(curchar=='!') { temp.code=26; } else{ Error(0); temp.code=-1; return temp; } } 5.测试用例和结果 测试用例 0 92+data> 0x3f 00 while a+acc>xx|| !(bb then a=b else a=b-1+c; ==# 测试结果 INT10 0 INT10 92 + IDN data > INT16 63 INT8 0 WHILE IDN a + IDN acc > IDN xx || ! ( IDN b < IDN a ) DO IDN x = IDN x - INT10 1 ; IDN a = REAL10 6.2 + IDN a * REAL16 136.500000 REAL8 28.312500 ; IF IDN a > IDN b THEN IDN a = IDN b ELSE IDN a = IDN b - INT10 1 + IDN c ; == 7
实验二/三:语法制导的三地址代码生成程序 1. 实验目的 通过实现一个词法及语义分析程序掌握计算机语言的语法分析程序设计与属性文法应 用的实现方法。 2. 实验内容 编制一个 LR(1)自动生成程序,并用生成的 LR(1)分析表进行语法分析,生成三地址 代码。 3. 实验要求 1,自动生成 LR(1)分析表 2,采用 LR(1)分析法分析用类 c 语言文法编制的程序段。 3,从文件中读入源程序段。 4,根据下文中语法制导定义给出的属性文法生成三地址码。 4.文法的定义(消除二义性之后) S'→ S # S → U S → M U → while ( C ) S1 U → if ( C ) S1 U → if ( C ) M else U M → if ( C ) M else M M → id = E ; M → {B} B → S B → S B C → C || P C → P P → P && Q P → Q Q → ! Q Q → ( C ) Q → E > E Q → E < E Q → E == E E → E + T E → E - T E → T T → F 8
分享到:
收藏