IF-ELSE条件语句的翻译程序设计(LL(1)法、输出三地址表示) 2

武汉理工大学《编译原理》课程设计说明书

词法分析程序如下: void lexical()

{ //\是其一条特殊的例子 int i,j,d; char ch; j=d=0; for(i=0;var[i]!='#';i++) { ch=var[i]; if(ch=='i'&&var[i+1]=='f') { cout<<\关键字]\ queue[j++]='f';i+=1; }//{判断\关键字} else if(ch=='t') { ch=var[i+1]; if(ch=='h') { ch=var[i+2]; if(ch=='e') { ch=var[i+3]; if(ch=='n') { ch=var[i+4]; } } } cout<<\关键字]\ queue[j++]='t';i+=3; }//{判断\关键字} else if(ch=='e') { ch=var[i+5]; if(ch=='l') { ch=var[i+6]; if(ch=='s') { ch=var[i+7]; if(ch=='e')

6

武汉理工大学《编译原理》课程设计说明书

{ ch=var[i+8]; } } } cout<<\关键字]\ queue[j++]='e';i+=3; }//{判断\关键字} else if(index(ch,VT)<=0) { if(ch!='{'&&ch!='}'&&ch!='('&&ch!=')') { cout<0) { cout<

5 语法分析

主要的思想是设置一个分析栈和一个输入串队列,栈中最开始时存放的是文法开始

符和“#”。因为我这个程序本身已经确定是以if语句开头,所以,就不再把if放在 输入串中,而只是分析if以后的句子。在语法分析之前应该判定该文法是不是一个 LL(1)文法。判别的主要方法是做出文法中所有产生式的select集,对于同一个非终 结符的不同产生式,如果他们的select集合没有交集,则说明这个文法是LL(1)文法。 这个文法的预测分析表也设计的比较简单,如下表所示:

{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1},

{1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 2, -1},

7

武汉理工大学《编译原理》课程设计说明书

{4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {5, -1, -1, -1, -1, -1, -1, -1, 5, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, 6, 7, -1, -1, -1, -1, -1, 8, 8, 8}, {9, -1, -1, -1, -1, -1, -1, -1, 9, -1, -1, -1, -1, -1}, {-1, -1, -1, -1 , 12, 12, 10, 11, -1, -1, -1, 12, 12, 12}, {14, -1, -1, -1, -1, -1,- 1, -1, 13, -1, -1, -1, -1, -1}, {-1, 15, 16, 17, -1, -1, -1, -1, -1, -1, -1,- 1,- 1, -1},

//预测分析表

注:除了-1代表此处有产生式与之对应,具体的产生式在程序中给出。-1代表此处无

产生式与之对应。

void syntax() {

int n; count++; print(); X=stack[sp]; a=queue[front]; if(X=='#'&&a=='#')f=4;

if(X<'A'||X>'Z') //{判断字符集不是大写字母集合} { if(X==a) {

sp--; front++;

if(a!='i') //{\是特征字母} {

if(a!='f'&&a!='t'&&a!='e'&&a!=';'&&a!='#') {

opr=index(a,VT);

8

武汉理工大学《编译原理》课程设计说明书

}

semantic();

else if(a==';'||a=='e'||a=='t'||a=='#') {

opr=-2; }

else f=1; //字符不匹配,转去出错处理 } else {

int tx=index(X,VN);//{索引选择} int ta=index(a,VT);//{索引选择} n=M[tx][ta]; //{产生式选择} td[t++]=M[tx][ta]; //{产生式选择} if(ta==-1) {

f=2;cout<

opd=c;

//cout<

cout<<'\\t'<<'\\''<

cout<<'\\t'<<'\\''<

semantic();

} //字符没有出现在产生式终结符集VT中,转去出错处理 else if(n==-1)f=3; //没有找到合适的候选产生式来做进一步推导,转去出错处理

9

武汉理工大学《编译原理》课程设计说明书

}

else

{ //用产生式M[tx][ta]来做进一步推导 } }

if(f==0)syntax(); else {

td[t]='-1'; err(f); }

sp--;

cout<<'\\t'<

else cout<<\空串\

for(int i=len(p[n])-1;i>=0;i--) { }

cout<

stack[++sp]=p[n][i];

cout<

因为在推导过程中,会一并完成产生式后面附加的语义动作,所以这两部分是一起做的。 另外,在LL(1)分析过程中,会出现错误信息,如字符不匹配,或字符没有出现在产生式终结符集VT中,或没有找到合适的候选产生式来做进一步推导,会调用相应的出错处理函数err(f)。另外,此函数是递归实现,结束标志是f!=0,即成功或失败。

10

联系客服:779662525#qq.com(#替换为@) 苏ICP备20003344号-4