编译原理-实验一(共31页).docx

上传人:飞****2 文档编号:13495181 上传时间:2022-04-29 格式:DOCX 页数:31 大小:101.39KB
返回 下载 相关 举报
编译原理-实验一(共31页).docx_第1页
第1页 / 共31页
编译原理-实验一(共31页).docx_第2页
第2页 / 共31页
点击查看更多>>
资源描述

《编译原理-实验一(共31页).docx》由会员分享,可在线阅读,更多相关《编译原理-实验一(共31页).docx(31页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、精选优质文档-倾情为你奉上实验一 编译程序的分析与验证一、实验目的了解编译程序中LR分析表的作用以及语义加工程序的功能二、实验内容(1) 验证下述程序的正确性while (a=n then a:=a+1 else if ji then i=i+j else while k=h do x:=x+2; m:=n+m+x+y+n*m+x*yend#三、编译程序理解输入文件名,取一个字符,程序扫描,词法分析结果打印,变量名表打印,语句分析栈初始化,符号栈初始化,四元式空白初始化,状态栈加工过程及归约顺序,读结果缓冲区中字符到当前字符中,语句分析,四元式分析结果打印,程序运行结束。具体函数功能介绍:ch

2、ar ch=0;/可用于存放读出的一个字符 int count=0;/词法分析结果缓冲区计数器 static char spelling10=;/存放是别的字 static char line81=;/一行字符缓冲区 char *pline;/line的指针 static char ntab110010;/变量类型名表 struct ntab int tc;/真 int fc;/假 ntab2200;/用于存放布尔表达式的值 int label=0;/指向ntab2的指针 struct rwords char sp10; int sy; ;/匹配表结构体 struct rwords reswo

3、rds10=if,sy_if, do,sy_do, else,sy_else, while,sy_while, then,sy_then, begin,sy_begin, end,sy_end, and,op_and, or,op_or, not,op_not;/初始化匹配表 ,用于关键字的匹配 struct aa int sy1;/存放变量的类型名 int pos;/存放该变量在自己表中的位置 buf1000,/词法分析结果缓冲区 n,/存放二元式当前字符 n1,/表达式当前的字符 E,/非终结符 sstack100,/算术表达式和布尔表达式的符号栈 ibuf100,/算术表达式和布尔表达式

4、的缓冲区 stack1000;/语法分析的符号栈 struct aa oth;/四元式中没有填写的空白位置 struct fourexp/四元式结构体 char op10; struct aa arg1; struct aa arg2; int result; fexp200;int ssp=0;/指向 sstack的指针 struct aa *pbuf=buf;/词法分析结果缓冲区的指针 int nlength=0;/词法分析中记录单词的长度 int lnum=0;/行数计数源程序 int tt1=0;/变量类型名表的指针 FILE *cfile;/源程序文件 /*/int newt=0;/

5、临时变量计数器 int nxq=100;/总是指向下一个要形成的四元式 每次执行gen() int lr;/用于存放action1中的当前状态 int lr1;/用于存放action2,3中的当前状态 int sp=0;/LR分析表栈顶指针 int stack1100;/状态栈1 int sp1=0;/状态栈的指针 int num=0;/算术表达式或布尔表达式的指针 struct ll int nxq1;/指向下一条四元式的指针 int tc1;/真值链 int fc1;/假值链 labelmark10;/记录嵌套中每层布尔表达式e的首地址 int labeltemp10;/记录每层else之

6、前四元式的地址 int pointmark=-1,pointtemp=-1;/labelmark的指针,labelmark的指针 int sign=0;/ sign=1 赋值语句,sign=2 while语句,sign=3 if语句构造程序语句的LR分析表算术表达式的LR分析表布尔表达式的LR分析表readline()/读一行 char ch1; pline=line; ch1=fgetc(cfile);/从文件中取一个 while(ch1!=n)&(ch1!=EOF)/把字符缓冲区填满 *pline=ch1; pline+; ch1=fgetc(cfile); *pline=0;/结尾终结符

7、 pline=line;/字符缓冲区指针重新回到字符缓冲区的第一个字符位置 /*从缓冲区读取一个字符*/readch()/读一个 if(ch=0)/读到尾姐再来一行,行数加一 readline(); lnum+; ch=*pline;/从行缓冲区读取一个字符 pline+;/字符缓冲区指针后移 /*标识符和关键字的识别*/find(char spel)/在变量表中查询 int ss1=0;/ 是否查到的变量的标志(1为查到,0为没查到) int ii=0;/记录查到变量表第几条 while(ss1=0)&(ii=a)&(ch=0)&(ch=9);/数字或小写字母 pline-;/取字时多加的一

8、个,-1可使 *pline指向字符缓冲区行尾 spellingk=0; while(ss=0)&(iii10) if(!strcmp(spelling,reswordsiii.sp)/在关键字表中查询 ss=1;/查到标志置1 iii+; /*关键字匹配*/ if(ss=1)/在关键字表中查到 bufcount.sy1=reswordsiii-1.sy;/关键字名字放入结果缓冲区 else/没查到 bufcount.sy1=ident;/将变量名置入结果缓冲区 j=find(spelling);/变量表查询 ,查到就把变量在变量表的地址赋给j if(j=-1)/没查到就新建一个变量 bufco

9、unt.pos=tt1;/将其在变量表中的地址放入结果缓冲区中的地址栏 strcpy(ntab1tt1,spelling);/将识别的变量名放入变量名表 tt1+; nlength+;/变量名表长加一 else bufcount.pos=j;/查到后,将变量名表中变量的地址放入结果缓冲区该变量的地址栏中 count+;/指向结果缓冲区下一位置 for(k=0;k=0)&(ch=9); bufcount.sy1=intconst;/常量名存入结果缓冲区 bufcount.pos=ivalue;/该常量地址存入结果缓冲区 count+;/ 向结果缓冲区下一位置 pline-;/指向行缓冲区尾字符

10、scan()/扫描主程序readnu()/读取当前结果缓冲区的二元式存入struct aa n中 ,pbuf指向结果缓冲区中下一位置的指针newtemp()/返回目前临时变量数gen(char op1,struct aa arg11,struct aa arg22,int result1)/op1算符,arg11操作数1,arg22操作数2, result1结果merg(int p1,int p2)/ 将链首“指针”分别为p1和p2的两条链合并为一条,并返回新链的链首“指针”(此处的“指针”实际上是四元式的序号,应为整型值)backpatch(int p,int t)/用四元式序号t回填以p为

11、首的链,将链中每个四元式的Result域改写为t的值。change1(int chan)/action1的符号查找排序(i,+,*,(,),#,E,-,/)change2(int chan)/action2的符号查找排序lrparse1(int num)/算数表达式语义分析lrparse2(int num)/ 布尔表达式的分析test(int value) / 测试字符是否为表达式中的值(不包括:)lrparse()/程序语句分析disp1()/打印词法分析结果disp2()/打印四元式分析结果disp3()/打印变量表名main()/主函数四、A语言程序分析与验证五、源码(带注释)#incl

12、ude stdio.h#include string.h#define ACC -2/*/#define sy_if 0#define sy_then 1#define sy_else 2#define sy_while 3#define sy_begin 4#define sy_do 5#define sy_end 6#define a 7#define semicolon 8#define e 9#define jinghao 10#define S 11#define L 12#define tempsy 15#define EA 18#define E0 19#define plus

13、34#define sub 35/减 #define times 36#define div 37/除 #define becomes 38#define op_and 39#define op_or 40#define op_not 41#define rop 42#define lparent 48#define rparent 49#define ident 56#define intconst 57/*/char ch=0;/可用于存放读出的一个字符 int count=0;/词法分析结果缓冲区计数器 static char spelling10=;/存放是别的字 static cha

14、r line81=;/一行字符缓冲区 char *pline;/line的指针 static char ntab110010;/变量类型名表 struct ntab int tc;/真 int fc;/假 ntab2200;/用于存放布尔表达式的值 int label=0;/指向ntab2的指针 struct rwords char sp10; int sy; ;/匹配表结构体 struct rwords reswords10=if,sy_if, do,sy_do, else,sy_else, while,sy_while, then,sy_then, begin,sy_begin, end,

15、sy_end, and,op_and, or,op_or, not,op_not;/初始化匹配表 ,用于关键字的匹配 struct aa int sy1;/存放变量的类型名 int pos;/存放该变量在自己表中的位置 buf1000,/词法分析结果缓冲区 n,/存放二元式当前字符 n1,/表达式当前的字符 E,/非终结符 sstack100,/算术表达式和布尔表达式的符号栈 ibuf100,/算术表达式和布尔表达式的缓冲区 stack1000;/语法分析的符号栈 struct aa oth;/四元式中没有填写的空白位置 struct fourexp/四元式结构体 char op10; str

16、uct aa arg1; struct aa arg2; int result; fexp200;int ssp=0;/指向 sstack的指针 struct aa *pbuf=buf;/词法分析结果缓冲区的指针 int nlength=0;/词法分析中记录单词的长度 int lnum=0;/行数计数源程序 int tt1=0;/变量类型名表的指针 FILE *cfile;/源程序文件 /*/int newt=0;/临时变量计数器 int nxq=100;/总是指向下一个要形成的四元式 每次执行gen() int lr;/用于存放action1中的当前状态 int lr1;/用于存放actio

17、n2,3中的当前状态 int sp=0;/LR分析表栈顶指针 int stack1100;/状态栈1 int sp1=0;/状态栈的指针 int num=0;/算术表达式或布尔表达式的指针 struct ll int nxq1;/指向下一条四元式的指针 int tc1;/真值链 int fc1;/假值链 labelmark10;/记录嵌套中每层布尔表达式e的首地址 int labeltemp10;/记录每层else之前四元式的地址 int pointmark=-1,pointtemp=-1;/labelmark的指针,labelmark的指针 int sign=0;/ sign=1 赋值语句,

18、sign=2 while语句,sign=3 if语句 /*程序语句的LR分析表*/static int action1913= 2,-1,-1,3,4,-1,-1,5,-1,-1,10,1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,ACC,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,6,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,7,-1,-1,-1, 2,-1,-1,3,4,-1,-1,5,-1,-1,-1,9,8, -1,-1,104,-1,-1,-1,104,-1,104,-1,104,-1,-1, -1,1

19、0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,11,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,12,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,105,-1,13,-1,-1,-1,-1, 2,-1,-1,3,4,-1,-1,5,-1,-1,-1,14,-1, 2,-1,-1,3,4,-1,-1,5,-1,-1,-1,15,-1, -1,-1,103,-1,-1,-1,103,-1,103,-1,103,-1,-1, 2,-1,-1,3,4,-1,-1,5,-1,-1,-

20、1,9,16, -1,-1,17,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,102,-1,-1,-1,102,-1,102,-1,102,-1,-1, -1,-1,-1,-1,-1,-1,106,-1,-1,-1,-1,-1,-1, 2,-1,-1,3,4,-1,-1,5,-1,-1,-1,18,-1, -1,-1,101,-1,-1,-1,101,-1,101,-1,101,-1,-1;/*算术表达式的LR分析表*/static int action1149= 3,-1,-1,2,-1,-1,1,-1,-1, -1,4,6,-1,-1,ACC,-1,5,7,

21、3,-1,-1,2,-1,-1,8,-1,-1, -1,104,104,-1,104,104,-1,104,104, 3,-1,-1,2,-1,-1,9,-1,-1, 3,-1,-1,2,-1,-1,10,-1,-1, 3,-1,-1,2,-1,-1,11,-1,-1, 3,-1,-1,2,-1,-1,12,-1,-1, -1,4,6,-1,13,-1,-1,5,7, -1,101,6,-1,101,101,-1,101,7, -1,105,6,-1,105,105,-1,105,7, -1,102,102,-1,102,102,-1,102,102, -1,106,106,-1,106,10

22、6,-1,106,106, -1,103,103,-1,103,103,-1,103,103;/*布尔表达式的LR分析表*/static int action21611= 1,-1,4,-1,5,-1,-1,-1,13,7,8, -1,2,-1,101,-1,101,101,101,-1,-1,-1, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,102,-1,102,102,102,-1,-1,-1, 1,-1,4,-1,5,-1,-1,-1,11,7,8, 1,-1,4,-1,5,-1,-1,-1,6,7,8, -1,-1,-1,104,-1,9,10

23、,104,-1,-1,-1, 1,-1,4,-1,5,-1,-1,-1,14,7,8, 1,-1,4,-1,5,-1,-1,-1,15,7,8, 105,-1,105,-1,105,-1,-1,-1,-1,-1,-1, 107,-1,107,-1,107,-1,-1,-1,-1,-1,-1, -1,-1,-1,12,-1,9,10,-1,-1,-1,-1, -1,-1,-1,103,-1,103,103,103,-1,-1,-1, -1,-1,-1,-1,-1,9,10,ACC,-1,-1,-1, -1,-1,-1,106,-1,9,10,106,-1,-1,-1, -1,-1,-1,108,

24、-1,9,10,108,-1,-1,-1;/*从文件读一行到缓冲区*/readline()/读一行 char ch1; pline=line; ch1=fgetc(cfile);/从文件中取一个 while(ch1!=n)&(ch1!=EOF)/把字符缓冲区填满 *pline=ch1; pline+; ch1=fgetc(cfile); *pline=0;/结尾终结符 pline=line;/字符缓冲区指针重新回到字符缓冲区的第一个字符位置 /*从缓冲区读取一个字符*/readch()/读一个 if(ch=0)/读到尾姐再来一行,行数加一 readline(); lnum+; ch=*plin

25、e;/从行缓冲区读取一个字符 pline+;/字符缓冲区指针后移 /*标识符和关键字的识别*/find(char spel)/在变量表中查询 int ss1=0;/ 是否查到的变量的标志(1为查到,0为没查到) int ii=0;/记录查到变量表第几条 while(ss1=0)&(ii=a)&(ch=0)&(ch=9);/数字或小写字母 pline-;/取字时多加的一个,-1可使 *pline指向字符缓冲区行尾 spellingk=0; while(ss=0)&(iii10) if(!strcmp(spelling,reswordsiii.sp)/在关键字表中查询 ss=1;/查到标志置1 i

26、ii+; /*关键字匹配*/ if(ss=1)/在关键字表中查到 bufcount.sy1=reswordsiii-1.sy;/关键字名字放入结果缓冲区 else/没查到 bufcount.sy1=ident;/将变量名置入结果缓冲区 j=find(spelling);/变量表查询 ,查到就把变量在变量表的地址赋给j if(j=-1)/没查到就新建一个变量 bufcount.pos=tt1;/将其在变量表中的地址放入结果缓冲区中的地址栏 strcpy(ntab1tt1,spelling);/将识别的变量名放入变量名表 tt1+; nlength+;/变量名表长加一 else bufcount.

27、pos=j;/查到后,将变量名表中变量的地址放入结果缓冲区该变量的地址栏中 count+;/指向结果缓冲区下一位置 for(k=0;k=0)&(ch=9); bufcount.sy1=intconst;/常量名存入结果缓冲区 bufcount.pos=ivalue;/该常量地址存入结果缓冲区 count+;/ 向结果缓冲区下一位置 pline-;/指向行缓冲区尾字符 /*扫描主程序*/scan() int i; while(ch!=)/为程序结束符 switch(ch) case :break; case a: case b: case c: case d: case e: case f: c

28、ase 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:identifier();break;/关键词或变量查询 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9:number();break;/数字查询 case :readch(

29、);/6种关系运算符bufcount.pos=(=为0,=为2,为3,为4,=为5) if(ch=) bufcount.pos=0; else if(ch=) bufcount.pos=4; else bufcount.pos=1; pline-; bufcount.sy1=rop;/关系运算符名存入结果 count+;/结果指针后移 break; case : readch(); if(ch=) bufcount.pos=2; else bufcount.pos=3; pline-; bufcount.sy1=rop; count+; break; case (: bufcount.sy1=

30、lparent; count+; break; case ): bufcount.sy1=rparent; count+; break; case #: bufcount.sy1=jinghao; count+; break; case +: bufcount.sy1=plus; count+; break; case -: bufcount.sy1=sub; count+; break; case *: bufcount.sy1=times; count+; break; case /: bufcount.sy1=div; count+; break; case : readch(); if(ch=) bufcount.sy1=becomes; count+; break; case =: bufcount.sy1=rop; bufcount.pos=5; count+; break; case ;: bufcount.sy1=semicolon;

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁