FirstVT集和LastVT集生成算法模拟(编译原理课设)
编译原理语法分析(3)_ 习题

来消除左递归。由此,将产生式B→Bb|d改造为 B→dB′ B′→bB′| ε
其次,应通过提取公共左因子的方法来消除G[A]中的回 溯,即将产生式A→aABl|a改造为 A→aA′ A′→ABl | ε
最后得到改造后的文法为 G[A′]:A→aA′ A′→ABl | ε B→dB′ B′→bB′| ε
S ( L) L, S S ( L)
S a
图4-5 句型(S,(a))的语法树
(2) 由图4-5可知: 短语:S、a、(a)、S,(a)、(S,(a)); 直接短语:a、S; 句柄:S; 素短语:素短语可由图4-5中相邻终结符之间的优 先关系求得,即:
#⋖ (⋖,⋖ (⋖a⋗)⋗)⋗# 因此,素短语为a。
D
D
TL
TL
int a L′
int L , c
, b L′
L, b
, c L′
a (a)
(b)
图4-6 两种文法为int a,b,c构造的分析树 (a) 文法G(D); (b) 文法G′(D)
3.9 考虑文法G[S]: S→(T) | a+S | a T→T,S | S
消除文法的左递归及提取公共左因子,然后对每 个非终结符写出不带回溯的递归子程序。
优先关系表构造方法: ① 对P→…ab…或P→…aQb…,有ab; ② 对P→…aR…而b∈FIRSTVT(R),有a⋖b; ③ 对P→…Rb…而a∈LASTVT(R),有a⋗b。 解之无①。 由②得:E→…+T,即+⋖FIRSTVT(T),有+⋖*,+⋖i;
T→…*P,即*⋖FIRSTVT(P),有*i。 由③得:E→E+…,即LASTVT(E)⋗+,有+⋗+,*⋗+, i⋗+;
编译原理模拟试题六

《编译原理》模拟试题六一、是非题(请在括号内,正确的划√,错误的划×)(每个2分,共20分)1.设r和s分别是正规式,则有L(r|s)=L(r)L(s)。
(×)2.确定的自动机以及不确定的自动机都能正确地识别正规集。
(√)3.词法分析作为单独的一遍来处理较好。
(× )4.构造LR分析器的任务就是产生LR分析表。
(√)5.规范归约和规范推导是互逆的两个过程。
(× )6.同心集的合并有可能产生新的“移进”/“归约”冲突。
(× )7.LR分析技术无法适用二义文法。
(× )8.树形表示和四元式不便于优化,而三元式和间接三元式则便于优化。
(×)9.程序中的表达式语句在语义翻译时不需要回填技术。
(√)10.对中间代码的优化依赖于具体的计算机。
(× )二、选择题(请在前括号内选择最确切的一项作为答案划一个勾,多划按错论)(每个4分,共40分)1.编译程序绝大多数时间花在_____ 上。
A.( ) 出错处理 B.( ) 词法分析C.( ) 目标代码生成D.( ) 表格管理2.编译程序是对_____。
A.( ) 汇编程序的翻译 B.( ) 高级语言程序的解释执行C.( ) 机器语言的执行D.( ) 高级语言的翻译3.采用自上而下分析,必须_____。
A.( ) 消除左递归 B.( ) 消除右递归C.( ) 消除回溯 D.( ) 提取公共左因子4.在规范归约中,用_____来刻画可归约串。
A.( )直接短语B.( )句柄C.( )最左素短语D.( )素短语5.若a为终结符,则A->α ·aβ为_____项目。
A.( )归约B.( ) 移进C.( ) 接受D.( ) 待约6.间接三元式表示法的优点为_____。
A.( ) 采用间接码表,便于优化处理B.( ) 节省存储空间,不便于表的修改C.( ) 便于优化处理,节省存储空间 D.( ) 节省存储空间,不便于优化处理7.基本块内的优化为_____。
设计一个给定文法和对应的FIRSTVT和LASTVT集,能依据依据文法和FIRSTVT和LASTVT

实验二算符优先分析器#include "stdio.h"#include "stdlib.h"#include "iostream.h"char data[20][20]; //算符优先关系char s[100]; //模拟符号栈schar lable[20]; //文法终极符集char input[100]; //文法输入符号串char string[20][10]; //用于输入串的分析int k;char a;int j;char q;int r; //文法规则个数int r1; //转化后文法规则个数char st[10][30]; //用来存储文法规则char first[10][10]; //文法非终结符FIRSTVT集char last[10][10]; //文法非终结符LASTVT集int fflag[10]={0}; //标志第i个非终结符的FIRSTVT集是否已求出int lflag[10]={0}; //标志第i个非终结符的LASTVT集是否已求出int deal(); //对输入串的分析int zhongjie(char c); //判断字符c是否是终极符int xiabiao(char c); //求字符c在算符优先关系表中的下标void out(int j,int k,char *s); //打印s栈void firstvt(char c); //求非终结符c的FIRSTVT集void lastvt(char c); //求非终结符c的LASTVT集void table(); //创建文法优先关系表void main(){int i,j,k=0;printf("请输入文法规则数:");scanf("%d",&r);printf("请输入文法规则:\n");for(i=0;i<r;i++){scanf("%s",st[i]); //存储文法规则,初始化FIRSTVT集和LASTVT集*/first[i][0]=0; /*first[i][0]和last[i][0]分别表示st[i][0]非终极符的FIRSTVT集和LASTVT集中元素的个数*/ last[i][0]=0;}for(i=0;i<r;i++) //判断文法是否合法{for(j=0;st[i][j]!='\0';j++){if(st[i][0]<'A'||st[i][0]>'Z'){printf("不是算符文法!\n");exit(-1);}if(st[i][j]>='A'&&st[i][j]<='Z'){if(st[i][j+1]>='A'&&st[i][j+1]<='Z'){printf("不是算符文法!\n");exit(-1);}}}}for(i=0;i<r;i++){for(j=0;st[i][j]!='\0';j++){if((st[i][j]<'A'||st[i][j]>'Z')&&st[i][j]!='-'&&st[i][j]!='>'&&st[i][j]!='|') lable[k++]=st[i][j];}}lable[k]='#';lable[k+1]='\0';table();printf("每个非终结符的FIRSTVT集为:\n"); //输出每个非终结符的FIRSTVT集for(i=0;i<r;i++){printf("%c: ",st[i][0]);for(j=0;j<first[i][0];j++){printf("%c ",first[i][j+1]);}printf("\n");}printf("每个非终结符的LASTVT集为:\n"); //输出每个非终结符的LASTVT集for(i=0;i<r;i++){printf("%c: ",st[i][0]);for(j=0;j<last[i][0];j++){printf("%c ",last[i][j+1]);}printf("\n");}printf("算符优先分析表如下:\n");for(i=0;lable[i]!='\0';i++)printf("\t%c",lable[i]);printf("\n");for(i=0;i<k+1;i++){printf("%c\t",lable[i]);for(j=0;j<k+1;j++){printf("%c\t",data[i][j]);}printf("\n");}printf("请输入文法输入符号串以#结束:");scanf("%s",input);deal();}void table(){char text[20][10];int i,j,k,t,l,x=0,y=0;int m,n;x=0;for(i=0;i<r;i++){firstvt(st[i][0]);lastvt(st[i][0]);}for(i=0;i<r;i++){text[x][y]=st[i][0];y++;for(j=1;st[i][j]!='\0';j++){if(st[i][j]=='|'){text[x][y]='\0';x++;y=0;text[x][y]=st[i][0];y++;text[x][y++]='-';text[x][y++]='>';}else{text[x][y]=st[i][j];y++;}}text[x][y]='\0';x++;y=0;}r1=x;printf("转化后的文法为:\n");for(i=0;i<x;i++) //输出转化后的文法规则串{printf("%s\n",text[i]);}for(i=0;i<x;i++) /*求每个终结符的推导结果(去掉"->"后的转化文法,用于最后的规约)*/ {string[i][0]=text[i][0];for(j=3,l=1;text[i][j]!='\0';j++,l++)string[i][l]=text[i][j];string[i][l]='\0';}for(i=0;i<x;i++){for(j=1;text[i][j+1]!='\0';j++){if(zhongjie(text[i][j])&&zhongjie(text[i][j+1])){m=xiabiao(text[i][j]);n=xiabiao(text[i][j+1]);data[m][n]='=';}if(text[i][j+2]!='\0'&&zhongjie(text[i][j])&&zhongjie(text[i][j+2])&&!zhongjie(text[i][j +1])){m=xiabiao(text[i][j]);n=xiabiao(text[i][j+2]);data[m][n]='=';}if(zhongjie(text[i][j])&&!zhongjie(text[i][j+1])){for(k=0;k<r;k++){if(st[k][0]==text[i][j+1])break;}m=xiabiao(text[i][j]);for(t=0;t<first[k][0];t++){n=xiabiao(first[k][t+1]);data[m][n]='<';}}if(!zhongjie(text[i][j])&&zhongjie(text[i][j+1])){for(k=0;k<r;k++){if(st[k][0]==text[i][j])break;}n=xiabiao(text[i][j+1]);for(t=0;t<last[k][0];t++){m=xiabiao(last[k][t+1]);data[m][n]='>';}}}}m=xiabiao('#');for(t=0;t<first[0][0];t++){n=xiabiao(first[0][t+1]);data[m][n]='<';}n=xiabiao('#');for(t=0;t<last[0][0];t++){m=xiabiao(last[0][t+1]);data[m][n]='>';}data[n][n]='=';}void firstvt(char c) //求FIRSTVT集{int i,j,k,m,n;for(i=0;i<r;i++){if(st[i][0]==c)break;}if(fflag[i]==0){n=first[i][0]+1;m=0;do{if(m==2||st[i][m]=='|'){if(zhongjie(st[i][m+1])){first[i][n]=st[i][m+1];n++;}else{if(zhongjie(st[i][m+2])){first[i][n]=st[i][m+2];n++;}if(st[i][m+1]!=c){firstvt(st[i][m+1]);for(j=0;j<r;j++){if(st[j][0]==st[i][m+1])break;}for(k=0;k<first[j][0];k++){int t;for(t=0;t<n;t++){if(first[i][t]==first[j][k+1])break;}if(t==n){first[i][n]=first[j][k+1];n++;}}}}}m++;}while(st[i][m]!='\0');first[i][n]='\0';first[i][0]=--n;fflag[i]=1;}}void lastvt(char c) //求LASTVT集{int i,j,k,m,n;for(i=0;i<r;i++){if(st[i][0]==c)break;}if(lflag[i]==0){n=last[i][0]+1;m=0;do{if(st[i][m+1]=='\0'||st[i][m+1]=='|'){if(zhongjie(st[i][m])){last[i][n]=st[i][m];n++;}else{if(zhongjie(st[i][m-1])){last[i][n]=st[i][m-1];n++;}if(st[i][m]!=c){lastvt(st[i][m]);for(j=0;j<r;j++){if(st[j][0]==st[i][m])break;}for(k=0;k<last[j][0];k++){int t;for(t=0;t<n;t++){if(last[i][t]==last[j][k+1])break;}if(t==n){last[i][n]=last[j][k+1];n++;}}}}}m++;}while(st[i][m]!='\0');last[i][n]='\0';last[i][0]=--n;lflag[i]=1;}}int deal(){int i,j;int x,y;int z; //输入串的长度k=1;s[k]='#'; //栈置初值for(i=0;input[i]!='\0';i++); //计算输入串的长度z=i--;i=0;while((a=input[i])!='\0'){if(zhongjie(s[k]))j=k;elsej=k-1;x=xiabiao(s[j]);y=xiabiao(a);if(data[x][y]=='>'){out(1,k,s);printf("%c",a);out(i+1,z,input);printf("规约\n");do{q=s[j];if(zhongjie(s[j-1]))j=j-1;else j=j-2;x=xiabiao(s[j]);y=xiabiao(q);}while(data[x][y]!='<');int m,n,N;for(m=j+1;m<=k;m++){for(N=0;N<r1;N++)for(n=1;string[N][n]!='\0';n++){if(!zhongjie(s[m])&&!zhongjie(string[N][n])){if(zhongjie(s[m+1])&&zhongjie(string[N][n+1])&&s[m+1]==string[N][n+1]){s[j+1]=string[N][0];break;}}elseif(zhongjie(s[m]))if(s[m]==string[N][n]){s[j+1]=string[N][0];break;}}}k=j+1;if(k==2&&a=='#'){out(1,k,s);printf("%c",a);out(i+1,z,input);printf("结束\n");printf("输入串符合文法的定义!\n");return 1; //输入串符合文法的定义}}elseif(data[x][y]=='<'||data[x][y]=='='){ //移进out(1,k,s);printf("%c",a);out(i+1,z,input);printf("移进\n");k++;s[k]=a;i++;}else{printf("\nflase");return 0;}}printf("\nflase");return 0;}void out(int j,int k,char *s){int n=0;int i;for(i=j;i<=k;i++){printf("%c",s[i]);n++;}for(;n<15;n++){printf(" ");}}int xiabiao(char c) //求字符c在算符优先关系表中的下标{int i;for(i=0;lable[i]!='\0';i++){if(c==lable[i])return i;}return -1;}int zhongjie(char c) //判断字符c是否是终极符{int i;for(i=0;lable[i]!='\0';i++){if(c==lable[i])return 1;}return 0;}。
编译原理课后题

第二章6、令文法G6为:N →D|NDD → 0|1|2|3|4|5|6|7|8|9(1)G6 的语言L(G6)是什么?(2)给出句子0127、34和568的最左推导和最右推导。
解答:思路:由N → D|ND可得出如下推导N=>ND=>NDD=>…=>D n(n>=1)可以看出,N最终可以推导出1个或多个(也可以是无穷)D,而D → 0|1|2|3|4|5|6|7|8|9可知,每个D为0~9中的任一个数字,所以,N 最终推导出的就是由0~9这10个数字组成的字符串。
(1)G6 的语言L(G6)是由0~9这10个数字组成的字符串,或{0,1,…,9}+。
(2)句子0127、34和568的最左推导分别为:N=>ND=>NDD=>NDDD=>DDDD=>0DDD=>01DD=>012D=>0127N=>ND=>DD=>3D=>34N=>ND=>NDD=>DDD=>5DD=>56D=>568句子0127、34和568的最右推导分别为:N=>ND=>N7=>ND7=>N27=>ND27=>N127=>D127=>0127N=>ND=>N4=>D4=>34N=>ND=>N8=>ND8=>N68=>D68=>5687、写一个文法,使其语言是奇数集,且每个基数不以0开头。
解答:G(S):S → CD|D D→1|3|5|7|9C → CB|A A→2|4|6|8|DB → A|0或:G(S):S →MWN|N N →1|3|5|7|9 M →1|2|3|4|5|6|7|8|9W → WV|ε V → M|08、令文法为:E→T|E+T|E-TT→F|T*F|T/FF→(E)|i(1)i+i*i、i*(i+i)的最左推导和最右推导;(2)给出i+i+i、i+i*i和i-i-i的语法树。
解答:(1)i+i*i、i*(i+i)的最左推导分别为:E=>T=>E+T=>F+T=>i+T=>i+T*F=>i+F*F=>i+i*F=>i+i*iE=>T=>T*F=>F*F=>i*F=>i*(E)=>i*(E+T)=>i*(T+T)=>i*(F+T)=>i*(i+T)=>i*(i+F)=>i*(i+i)i+i*i、i*(i+i)的最右推导分别为:E=>T=>E+T=>E+T*F=>E+T*i=>E+F*i=>E+i*i=>T+i*i=>F+i*i=>i+i*iE=>T=>T*F=>T*(E+T)=>T*(E+F)=>T*(E+i)=>T*(T+i)=>T*(F+i)=>T*(i+i)=>F*(i+i)=>i*(i+i)(2) E E EE + T E + T E - TT T * F T T * F E - T FF F i F F i T F ii i i i F ii+i+I i+i*ii i-i-i9、证明下面的文法是二义的: S→iSeS|iS|i证明:思路:要证明该文法是二义的,必须找到一个句子,使得该句子具有两个不同的最右推导或两个不同的语法树。
编译原理课后习题答案

编译原理课后习题答案编译原理习题答案习题11.1翻译程序:把⽤某种程序设计语⾔(源语⾔)编写的程序(源程序)翻译成与之等价的另⼀种语⾔(⽬标语⾔)的程序(⽬标程序)。
编译程序:⼀种翻译程序,将⾼级语⾔编写的源程序翻译成等价的机器语⾔或汇编语⾔的⽬标程序。
1.2词法分析、语法分析、语义分析和中间代码⽣成、代码优化、⽬标代码⽣成1.3词法分析:根据语⾔的词法规则对构成源程序的符号进⾏扫描和分解,识别出⼀个个的单词。
语法分析:根据语⾔的语法规则,把单词符号串分解成各类语法单位。
语义分析及中间代码⽣成:对语法分析识别出的语法单位分析其含义,并进⾏初步翻译。
代码优化:对中间代码进⾏加⼯变换,以产⽣更⾼效的⽬标代码。
⽬标代码⽣成:将中间代码变换成特定机器上的绝对指令代码、可重定位的指令代码或会变指令代码。
以上5个阶段依次执⾏。
习题22.1 (1)有穷⾮空的符号集合(2)利⽤产⽣是规则A->v将A替换为v时与A的上下⽂⽆关。
(3)略(4)推导是把句型中的⾮终结符⽤⼀个产⽣是规则的右部开替代的过程;直接推导是将⾮终结符的替代结果只⽤了⼀次产⽣式规则。
(5)略(6)⼀个句型的最左直接短语(7)如果⼀个⽂法存在某个句⼦对应两棵不同的语法树或有两个不同的最左(右)推导,则称这个⽂法是⼆义的。
2.2(1)VN ={Z,A,B} VT ={a,b,c,d,e}(2)abbcde,abbbcde是,acde不是。
2.3 (1)L[G]={d|n≥1,m≥0}(2)2.4 (1) A=>B=>c=>fAg=>fBg=>fCg=>feg(2)A=>AaB=>AaC=>Aae=>Bae=>BcCae=>Bceae=>Cceae=>eceae(3)A=>B=>BcC=>BcfAg=>BcfAaBg=>BcfAaCg=>BcfAaeg=>BcfBaeg =>BcfCaeg=>Bcfeaeg=>Ccfeaeg=>ecfeaeg(3)中题⽬有错应为C fCg|e2.5L[G]={a?b?c?|aab,n≥2}2.6 (1)Z→AB A→Aa|ε B→Bb|ε(2)Z→aZb|ab(3)Z→aAb A→aAb|b(4)Z→AB A→aAb|ab B→cB|ε(5)Z→aaAb|ab Z→aaBb|bb A→aaAb|ab B→aaBb|bb2.7 ⼀位数:Z→2|4|6|8两位数:Z→AB A→1|2|3|4|5|6|7|8|9 B→0|2|4|6|8三位以上:Z→ACB A→1|2|3|4|5|6|7|8|9 B→0|2|4|6|8 C→CDD→0|1|2|3|4|5|6|7|8|92.8证明:E=>E+T=>E+T*F短语:T*F E+T*F 直接短语:T*F 句柄:T*F2.9 语法树: E 短语:E*T , (E*T) , F↑(E*T) ,F ,E* F↑(E*T)E *F 直接短语:E*T , FT ↑ F 句柄:FF ( E )E * T2.10(1)语法树(2)直接短语:a , ZZ 句柄:Z( L )L , ZZ ( L )Za2.11最左推导:Z=>ZaB=>BaB=>B+AaB=>A+AaB=>(+)Z*aB=>(+)ZaB*aB =>(+)+aB*aB=>(+)+aA*aB=>(+)+a(*aB=>(+)+a(*aA=>(+)+a(*a(直接短语:(,+句柄:(2.12(1) S=>iSeS=>iiSeS=>iiIeS=>iiIeIS=>iS=>iiSeS=>iiIeS=>iiIeI(2) S=>SaS=>cSaS=>cfaS=>cfafS=>cS=>cSaS=>cfaS=>cfaf(3) E=>EOE=>EOEOE=>iOEOE=>i+EOE=>i+iOE=>i+i-E=>i+i-iE=>EOE=>iOE=>i+E=>i+EOE=>i+iOE=>i+i-E=>i+i-i2.13 Z→aABZ|cCACdA→bAB|aZA|cCCB→bAB|CzbC→cZ|c习题33.1(1)确定的有限⾃动机(2)不确定的有限⾃动机(3)正规集是⼀类特殊的单词集合,正规式是正规集的描述⼯具 3.2 (1) (1|2|3|4|5|6|7|8|9|0)*(1|3|5|7|9) (2) 11(0|1)*00 3.3 证明:b *(a|b)+={a,b,ab,ba,aa,bb …} (a|b)+={a,b,ab,ba,aa,bb …} 3.4 (1)(2)DDDD3.5(1) (2)(3)3.6(1) (01|10) *(01|10)(2) (0(1|00)*)|003.7(1) Z →1AB (2)Z →ABA →(0|1)A A →0A|εA →0|1B →(0|1)B|ε B →0B B →ε3.8 r=a(a|b )*bb3.9 Z →1BB →0Z|0 Z →0Z|ε3.10 3.11DDD习题44.1 (1)若⽂法G[Z]满⾜①⽂法不含左递归②③(2)4.2(1) First(S)={a,d} First(B)={a,d,c,ε}First(A)={a,d,e,c} First(D)={a,d,ε}Follow(S)={#,a,b,d,e} Follow(B)={a,d}Follow(A)={b} Follow(D)={e,a,d,b}(2) 不是4.3 (1) 证明: First(Z)={a,b,c} Follow(S)={#,a,b,c,d} First(A)={a,b,c,d} Follow(A)={ #,a,b,c,d }First(B)={a,d,c} Follow(B)={ a,b,c,d } 是LL(1)⽂法。
firstvt集和lastvt集例题

1. 什么是firstvt集?firstvt集是文法分析中的一个重要概念,指的是文法中每个非终结符号的推导出的符号串中的第一个终结符号的集合。
在LL(1)文法的分析中,计算出每个非终结符号的firstvt集是非常关键的步骤。
2. 如何计算一个非终结符号的firstvt集?我们需要明确文法中终结符号和非终结符号的定义。
根据文法的推导规则和终结符号的定义,逐步推导出每个非终结符号的firstvt集。
具体的计算方法包括:- 对于每个终结符号,其firstvt集就是它本身。
- 对于每个非终结符号A,如果存在产生式A->α,其中α可以为空串或者以终结符号开始,那么将α的第一个终结符号加入A的firstvt 集。
- 重复以上步骤,直到所有的非终结符号的firstvt集都得到计算。
3. firstvt集的作用firstvt集的计算是文法分析中自顶向下分析方法的关键步骤之一。
它能够帮助我们判断一个文法是否是LL(1)文法,从而确定是否可以使用LL(1)分析方法对该文法进行分析。
在语法分析中,firstvt集还可以辅助我们进行推导和归约的过程。
1. 什么是lastvt集?lastvt集与firstvt集类似,也是文法中每个非终结符号的推导出的符号串中的最后一个终结符号的集合。
在LR分析中,计算出每个非终结符号的lastvt集同样是非常关键的步骤。
2. 如何计算一个非终结符号的lastvt集?同样地,我们需要明确文法中终结符号和非终结符号的定义。
根据LR分析的推导规则和终结符号的定义,逐步推导出每个非终结符号的lastvt集。
具体的计算方法与计算firstvt集类似:- 对于每个终结符号,其lastvt集就是它本身。
- 对于每个非终结符号A,如果存在产生式A->α,其中α可以为空串或者以终结符号结尾,那么将α的最后一个终结符号加入A的lastvt集。
- 重复以上步骤,直到所有的非终结符号的lastvt集都得到计算。
FirstVT集和LastVT集生成算法模拟(编译原理课设)

课程设计(论文)任务书软件学院学院软件测试专业 4 班一、课程设计(论文)题目 FIRSTVT集和LASTVT集生成算法模拟二、课程设计(论文)工作自2014 年 6 月16 日起至2014 年6 月 21 日止。
三、课程设计(论文) 地点: 软件学院实训中心四、课程设计(论文)内容要求:1.本课程设计的目的进一步培养学生编译器设计的思想,加深对编译原理和应用程序的理解,针对编译过程的重点和难点内容进行编程,独立完成有一定工作量的程序设计任务,同时,强调好的程序设计风格,并综合使用程序设计语言、数据结构和编译原理的知识, 熟悉使用开发工具VC /JA V A/C#/.NET 。
2.课程设计的任务及要求1)课程设计任务:设计一个由正规文法生成FIRSTVT集和LASTVT集的算法动态模拟。
(算法参见教材)动态模拟算法的基本功能是:(1)输入一个文法G;(2) 输出由文法G构造FIRSTVT集的算法;(3) 输出FIRSTVT集;(4) 输出由文法G构造LASTVT集的算法;(5) 输出LASTVT集。
2)创新要求:用界面的形式来展现这个结果集,这样显得更加的美观。
3)课程设计论文编写要求(1)课程设计任务及要求(2)设计思路--工作原理、功能规划(3)详细设计---数据分析、算法思路、功能实现(含程序流程图、主要代码及注释)、界面等。
(4)运行调试与分析讨论---给出运行屏幕截图,分析运行结果,有何改进想法等。
(5)设计体会与小结---设计遇到的问题及解决办法,通过设计学到了哪些新知识,巩固了哪些知识,有哪些提高。
(6)报告按规定排版打印,要求装订平整,否则要求返工;(7)课设报告的装订顺序如下:封面---任务书---中文摘要---目录----正文---附录(代码及相关图片)(8)严禁抄袭,如有发现,按不及格处理。
4)课程设计评分标准:(1)学习态度:20分;(2)系统设计:20分;(3)编程调试:20分;(4)回答问题:20分;(5)论文撰写:20分。
编译原理模拟试题和答案[编译原理模拟试题和答案.d

【题型】简答题1题干】现有文法G[S]:B→idt|ε请问aidtccb是句型还是句子,为什么?S→aAbA→BcA|B【答案】S ⇒aAb ⇒aBcAb ⇒aidtcAb ⇒aidtcBcAb ⇒aidtc εcAb ⇒ aidtccAb⇒aidtccBb ⇒aidtcc εb ⇒ aidtccb是句型,也是句子。
【题型】简答题2题干】设有文法G1[S]:<S>→<N><N>→<D>|<N><D><D→0|1|2|…|9试写出028的最左推导过程。
【答案】028的最左推导:<S>=><N>=><N><D>=><N><D><D>=><D><D><D>=>0<D><D>=>02<D>=>028。
3题型】填空题【题干】递归下降法不允许任一非终结符是直接_______________递归的。
【答案】左;4题型】填空题【题干】在使用高级语言编程时,首先可通过编译程序发现源程序的全部_______________错误和部分语义错误。
【答案】语法;5题型】填空题【题干】把汇编语言程序翻译成机器可执行的目标程序的工作是由_______________完成的。
【答案】汇编器;6题型】填空题【题干】语法分析器的输出是_______________。
【答案】语法单位;循环优化的三种重要技术包括删除归纳变量、代码外提和_______________。
【答案】强度消弱;8题干】写出表达式(a+b)/(a-b)-a(a+b*c)的三元式序列及四元式序列。
【答案】三元式:⑴.(+,a,b) ⑵.(-,a,b) ⑶.(/,⑴,⑵) ⑷.(*,b,c) ⑸.(+,a,⑷) ⑹.(-,⑶,⑸)四元式:⑴.(+,a,b,T1) ⑵.(-,a,b,T2) ⑶.(/,T1,T2,T3) ⑷.(*,b,c,T4) ⑸.(+,a,T4,T5) ⑹.(-,T3,T5,T6)9题干】什么是句子?什么是语言?【答案】(1)设G是一个给定的文法,S是文法的开始符号,如果S→x(其中x∈VT*),则称x是文法的一个句子。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程设计(论文)任务书软件学院学院软件测试专业 4 班一、课程设计(论文)题目 FIRSTVT集和LASTVT集生成算法模拟二、课程设计(论文)工作自2014 年 6 月16 日起至2014 年6 月 21 日止。
三、课程设计(论文) 地点: 软件学院实训中心四、课程设计(论文)内容要求:1.本课程设计的目的进一步培养学生编译器设计的思想,加深对编译原理和应用程序的理解,针对编译过程的重点和难点内容进行编程,独立完成有一定工作量的程序设计任务,同时,强调好的程序设计风格,并综合使用程序设计语言、数据结构和编译原理的知识, 熟悉使用开发工具VC /JA V A/C#/.NET 。
2.课程设计的任务及要求1)课程设计任务:设计一个由正规文法生成FIRSTVT集和LASTVT集的算法动态模拟。
(算法参见教材)动态模拟算法的基本功能是:(1)输入一个文法G;(2) 输出由文法G构造FIRSTVT集的算法;(3) 输出FIRSTVT集;(4) 输出由文法G构造LASTVT集的算法;(5) 输出LASTVT集。
2)创新要求:用界面的形式来展现这个结果集,这样显得更加的美观。
3)课程设计论文编写要求(1)课程设计任务及要求(2)设计思路--工作原理、功能规划(3)详细设计---数据分析、算法思路、功能实现(含程序流程图、主要代码及注释)、界面等。
(4)运行调试与分析讨论---给出运行屏幕截图,分析运行结果,有何改进想法等。
(5)设计体会与小结---设计遇到的问题及解决办法,通过设计学到了哪些新知识,巩固了哪些知识,有哪些提高。
(6)报告按规定排版打印,要求装订平整,否则要求返工;(7)课设报告的装订顺序如下:封面---任务书---中文摘要---目录----正文---附录(代码及相关图片)(8)严禁抄袭,如有发现,按不及格处理。
4)课程设计评分标准:(1)学习态度:20分;(2)系统设计:20分;(3)编程调试:20分;(4)回答问题:20分;(5)论文撰写:20分。
5)参考文献:(1)张素琴,吕映芝. 编译原理[M]., 清华大学出版社(2)蒋立源、康慕宁等,编译原理(第2版)[M],西安:西北工业大学出版社6)课程设计进度安排1.准备阶段(4学时):选择设计题目、了解设计目的要求、查阅相关资料2.程序模块设计分析阶段(4学时):程序总体设计、详细设计3.代码编写调试阶段(8学时):程序模块代码编写、调试、测试4.撰写论文阶段(4学时):总结课程设计任务和设计内容,撰写课程设计论文学生签名:2014 年 6 月21 日课程设计(论文)评审意见(1)学习态度(20分):优()、良()、中()、一般()、差();(2)系统设计(20分):优()、良()、中()、一般()、差();(3)编程调试(20分):优()、良()、中()、一般()、差();(4)回答问题(20分):优()、良()、中()、一般()、差();(5)论文撰写(20分):优()、良()、中()、一般()、差();评阅人:职称:副教授2014 年 6 月26 日目录绪论 (5)正文 (5)设计实现 (11)测试数据运行结果分析 (13)课程设计总结 (14)参考文献 (15)绪论随着计算机科学的飞速发展,形式语言与自动机理论和方法的研究也越来越受到人们的重视,但前者已经成为计算机科学的理论基础。
本课程设计主要研究自动机在编译方面的应用,并将讨论重点放在算符优先分析法上,并用此理论完成算数表达式的正确与否的判断。
根据算符优先分析算法,编写一个语法程序,程序具有通用性,即编制的语法缝隙程序能够适用于不同文法以及各种输入的单词串。
基本思想描述,语法分析前首先要对输入的文法和句子进行词法分析,去除多余的自负,并将产生式和终结符、非终结符填入有关数组,为语法分析做前期准备。
算符优先分析算法的核心算法教材上已给出,因此所要做的事只是将其变成实现。
正文设计目的本课程设计的题目为“FirstVT集和LastVT集生成算法模拟”,它是算符优先分析算法中判断三种优先关系的关键。
算符优先分析算法是自底向上分析方法的一种。
所谓自底向上分析,也称移近——规约分析,粗略地说它的实现思想是对输入符号串自左向右进行扫描,并将输入符逐个移入一个后进先出的栈中,边移进边分析,一旦栈顶符号串形成某个句型的句柄或可规约串,就用该产生式的左部非终结符代替相应右部的文法符号串,这称为一部规约。
重复这一过程直到规约到栈中只剩文法的开始符号则为分析成功,也就确认输入串是该文法的句子。
而算符优先分析算法的基本思想只是规定算符之间的优先关系,也就是只考虑终结符之间的优先关系。
本课程设计的要求只是构造FirstVT集和LastVT集,在此基础上扩充建造算符优先关系表。
问题描述设计一个给定文法和对应的FIRSTVT和LASTVT集,能依据依据文法和FIRSTVT和LASTVT生成算符优先分析表。
可以动态模拟算法的基本功能,通过输入一个给定文法,及FIRSTVT和LASTVT集,本题目以文法G[E]为测试数据: 文法G[E]:E->TE’E’->+TE’|εT->FT’T’->*FT’|εF->(E)|i该文法有对应的FIRSTVT(E)={ +, * ,( ,i } LASTVT(E)={ +,*,),i }FIRSTVT(E')={ +} LASTVT(E')={ +,*,),i }FIRSTVT(T)={ * ,( ,i } LASTVT(T)={ *,),i }FIRSTVT(T')={ * } LASTVT(T')={ *,),i }FIRSTVT(F)={ ( ,i } LASTVT(F)={ ),i }通过算符优先关系表构造算法:给定文法中任何二个终结符对(a,b)之间的优先关系有三种优先关系计算为:①=关系:可以直接查看产生式的右部,对如下形式的产生式:A→...ab...或A→...aBb...则有a=b成立。
②<关系:求出每个非终结符B的FIRSTVT(B),观察如下形式的产生式:A→...aB...对每一b∈FIRSTVT(B),有a<b成立。
③>关系:计算每个非终结符B的LASTVT(B),观察如下形式的产生式:A→...Bb...对每一a∈LASTVT(B),有a>b成立。
这样,对于给定的文法和对应的FIRSTVT和LASTVT集,通过二个终结符之间的优先关系表构造算法,可以得到算法优先分析表构造过程的过程和算符优先分析表生成算法。
所以,我们的重点应该放在算符优先分析表的生成算法上,解决了这一问题,也就可以得到我们想要的结果,算法优先分析表以及分析过程。
其中,对于FIRSTVT集和LASTVT集的表示可以采取集合的方式,同样也可以采用关系图法进行表示。
总体设计算符优先分析表的构造原理:通过检查文法G的每个产生式的每个候选式,可以首先找出满足a=b的终结符对;为了找出所有满足关系<和>的终结符对,我们首先需要对文法G的每个非终结符P构造二个集合FIRSTVT(P)和LASTVT(P)。
1.FirstVT集的构造FIRSTVT(P)={a|P=>+a...或P=>+Qa...,a∈VT而Q∈VN }若有产生式:P→a...或P→Qa...,则a∈FIRSTVT(P);若a∈FIRSTVT(Q),且有产生式P→Q...,则a∈FIRSTVT(P)。
stVT集的构造LASTVT(P)={ a|P=>+...a或P=>+...aQ,a∈VT而Q∈VN }若有产生式:U→...a或U→...aV, 则a∈LASTVT(U);若a∈LASTVT(V),且有产生式U→...V,则a∈LASTVT(U)。
当我们有了这二个集合之后,就可以通过检查每个产生式的候选式确定满足关系的“<”和“>”的所有终结符对。
我们假定有产生式的一个侯选式形为...aP...,那么,对任何b∈FIRSTVT(P),a<b;假定有产生式的一个候选形为...Pb...,那么,对任何a∈LASTVT(P),有a>b。
3.构造算符优先关系表在我们有了每个非终结符P的FIRSTVT(P)和LASTVT(P)集合之后,就能够构造文法G的优先表。
详细设计首先介绍算符优先文法的几个重要性质:性质1:在算符文法中任何句型都不包含两个相邻的非终结符。
性质2:如果Aa(或者bA)出现在算符文法的句型S中,其中A是非终结符,b是终结符,则S中任何含此b的短语必含有A。
1.FirstVT集的构造,算法描述①:若有产生式A->a…或A->Ba…,则a属于FirstVT(A),其中A、B为非终结符,a为终结符。
②:若a属于FirstVT(B)且有产生式A->B…则有a属于FirstVT(A)。
为了计算方便,建立一个布尔数组F[m,n](m为非终结字符的个数,n为终结字符的个数)和一个后进先出栈STACK。
将所有的非终结符排序,用iA表示非终结符A的序号,再将所有的终结符排序,用ia表示终结符a的序号。
算法的目的是要使数组的一个元素最终取值满足:F[iA,ja]的值为真,当且仅当a属于FirstVT(A)。
至此,显然所有的非终结符的FirstVT集已完全确定。
步骤如下:首先按规则①对每个数组元素附初值。
观察这些初值,若F[iA,ia]的值是真,则将(A,a)推入栈中,直至对所有数组的初值都按此处理完。
然后对栈做如下运算。
将栈顶项弹出,则令其变为真,且将(A,a)推进栈,如此重复直到栈弹空为止。
若表达式文法为:(0) E'→# E #(1) E→E + T(2) E→T(3) T→T*F(4) T→F(5) F→P↑F | P(6) P→(E)(7) P→i计算每个非终结符的FirstVT集和LastVT集得到如下结果:FIRSTVT(E') = { # }FIRSTVT(E) = {+,*,↑,(,i}FIRSTVT(T) = {*,↑,(,i}FIRSTVT(F) = {↑,(,i}FIRSTVT(P)={(,i}stVT集的构造,算法描述:用于构建输入文法的LastVT集①若有规则U::=…a或U::==…aV,则a属于LastVT(U)②若有规则U::=…V,且a属于LastVT(V)则a属于LastVT(U)设一个栈STACK,和一个布尔数组BProcedureInsert(U,a)IF NOT B[U,a] THENBEGINB[U,a]::=TRUE;把(U,a)推进STACK栈;END;BEGINFOR 每个非终结符号U和终结符号a DOB[U,a]:=FALSE;FOR 每个形如U::=…a或U::=…aV的规则DOINSERT(U,a);WHILE STACK栈非空DOBEGIN把STACK栈的栈顶弹出,记为(V,a);FOR 没条形如U::=…V的规则DOINSERT(U,a);END OF WHILE;END;具体算法如下:BeginFor每个终结符P和终结符a Do F[P,a]=FALSE;For 每个形如P->…a或P->…aQ的产生式,Do insert (P,a)While Stack 非空DoBegin把Stack 的顶端,记为(Q,a),上托出去;For每条形如P->…Q的产生式Insert(P,a)End of while;END针对上述算法可得到每个非终结符的LastVT集如下:LASTVT(E') = { # }LASTVT(E) = {+,*,↑,),i}LASTVT(T) = {*,↑,),i}LASTVT(F) ={↑,),i}LAVSTVT(P)={),i}①算符优先分析流程图图1算符优先分析流程图设计实现Ⅰ.主要数据存储结构描述:本课程设计主要采用栈的数据结构,定义一个栈的类,类中主要成员函数实现栈的一些基本操作,如:push()为入栈操作,pop()为出栈操作,empty()判断栈中是否为空,clear()用于对栈进行清空处理,核心代码为:①建立FirstVT函数集和SetFirstVT(),用来得到相应文法中所对应的非终结符的FirstVT集void CMyDlg::SetFirstVt(int Ptnum) //建立FRISTVT集{int i,j;char Q;char a;for(i=0;i<100;i++)for(j=0;j<100;j++)F[i][j]=false;for(i=0;i<=Ptnum;i++){if(Vt.Find(Pt[i].pright[0])!=-1)InsertFirstOrLast(Pt[i].pleft,Pt[i].pright[0],"First");if(Pt[i].pright.GetLength()>=2)if(Vn.Find(Pt[i].pright[0])!=-1 && Vt.Find(Pt[i].pright[1])!=-1) InsertFirstOrLast(Pt[i].pleft,Pt[i].pright[1],"First");}while(!stack.empty()){stack.pop(Q,a);for(i=0;i<Ptnum;i++)if(Pt[i].pright[0]==Q)InsertFirstOrLast(Pt[i].pleft,a,"First");}}②建立LastVT集函数和SetLastVT函数,用来得到相应文法中所有非终结符的LastVT集void CMyDlg::SetLastVt(int Ptnum) //建立LASTVT集{int i,j;char Q;char a;for(i=0;i<100;i++)for(j=0;j<100;j++)L[i][j]=false;for(i=0;i<Ptnum;i++){if(Vt.Find(Pt[i].pright.Right(1)[0]))InsertFirstOrLast(Pt[i].pleft,Pt[i].pright.Right(1)[0],"Last");if(Pt[i].pright.GetLength()>=2)if(Vt.Find(Pt[i].pright.Right(2)[0])!=-1&&Vn.Find(Pt[i].pright.Right(2)[1])!=-1) InsertFirstOrLast(Pt[i].pleft,Pt[i].pright.Right(2)[0],"Last");}while(!stack.empty()){stack.pop(Q,a);for(i=0;i<Ptnum;i++)if(Pt[i].pright[0]==Q)InsertFirstOrLast(Pt[i].pleft,a,"Last");}}测试数据运行结果分析1、测试数据如下,文法G[S]①S→# E #②E→E + T③E→T④T→T*F⑤T→F⑥F→P-F | P⑦P→(E)|i它对性的FirstVT集和LastVT集为:FIRSTVT(S) = { # }FIRSTVT(E) = {+,*,-,(,i}FIRSTVT(T) = {*,-,(,i}FIRSTVT(F) = {-,(,i}FIRSTVT(P)={(,i}LASTVT(S) = { # }LASTVT(E) ={+,*,-,),i}LASTVT(T) ={*,-,),i}LASTVT(F) ={-,),i}LA VSTVT(P)={),i}2、运行结果截图为:课程设计总结经过一个星期的编译原理课程设计的实践,我重新复习了自底向上的分析方法,其中重点复习了算符优先分析算法,对词法、文法的判断有了较深刻的认识,对算符优先分析算法的FirstVT集和LastVT集的构造有了更加感性的认识,对其中数据的流向和数据的输出操作有了很清晰的认识,对数据在该课程设计中的存储和运算有了深刻的理解。