计算机语言常用符号含义,符号的含义 - 解析编译原理

本文详细介绍了C语言编译器的实现过程,包括if、while、for语句的解析和代码生成,以及表达式处理。通过对源代码的分析,展示了如何将高级语言转换为低级机器指令,涉及条件转移、无条件转移和变量操作等关键步骤。
摘要由CSDN通过智能技术生成

其中动作符号的含义如下

@BRF↑label1 :输出 BRF label1,

@BR↑label2:输出 BR label2,

@SETlabel↓label1:设置标号label1

@SETlabel↓label2:设置标号label2

*/

int if_stat(){

int es=0,label1,label2; //if

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

if (strcmp(token,“(”)) return(es=5); //少左括号

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=expression();

if (es》0) return(es);

if (strcmp(token,“)”)) return(es=6); //少右括号

label1=labelp++;//用label1记住条件为假时要转向的标号

fprintf(fout,“ BRF LABEL%d/n”,label1);//输出假转移指令

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=statement();

if (es》0) return(es);

label2=labelp++;//用label2记住要转向的标号

fprintf(fout,“ BR LABEL%d/n”,label2);//输出无条件转移指令

fprintf(fout,“LABEL%d:/n”,label1);//设置label1记住的标号

if (strcmp(token,“else”)==0)//else部分处理

{

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=statement();

if (es》0) return(es);

}

fprintf(fout,“LABEL%d:/n”,label2);//设置label2记住的标号

return(es);

}

//《while_stat》::= while (《expr 》) 《 statement 》

//《while_stat》::=while @SET↑labellabel1(《expression》) @BRF↑label2

// 《statement 》@BR↑label1 @SETlabel↓label2

//动作解释如下:

//@SETlabel↑label1:设置标号label1

//@BRF↑label2 :输出 BRF label2,

//@BR↑label1:输出 BR label1,

//@SETlabel↓label2:设置标号label2

int while_stat()

{

int es=0,label1,label2;

label1=labelp++;

fprintf(fout,“LABEL%d:/n”,label1);//设置label1标号

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

if (strcmp(token,“(”)) return(es=5); //少左括号

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=expression();

if (es》0) return(es);

if (strcmp(token,“)”)) return(es=6); //少右括号

label2=labelp++;

fprintf(fout,“ BRF LABEL%d/n”,label2);//输出假转移指令

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=statement();

if (es》0) return(es);

fprintf(fout,“ BR LABEL%d/n”,label1);//输出无条件转移指令

fprintf(fout,“LABEL%d:/n”,label2);//设置label2标号

return(es);

}

//《for_stat》::= for(《expr》,《expr》,《expr》)《statement》

/*

《for_stat》::=for (《expression》;

@SETlabel↓label1《 expression 》@BRF↑label2@BR↑label3;

@SETlabel↓label4 《 expression 》@BR↑label1)

@SETlabel↓label3 《语句 》@BR↑label4@SETlabel↓label2

动作解释:

1. @SETlabel↓label1:设置标号label1

2. @BRF↑label2 :输出 BRF label2,

3. @BR↑label3:输出 BR label3,

4. @SETlabel↓label4:设置标号label4

5. @BR↑label1:输出 BR label1,

6. @SETlabel↓label3:设置标号label3

7. @BR↑label4:输出 BR label4,

8. @SETlabel↓label2:设置标号label2

*/

int for_stat()

{

int es=0,label1,label2,label3,label4;

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

if (strcmp(token,“(”)) return(es=5); //少左括号

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=expression();

if (es》0) return(es);

if (strcmp(token,“;”)) return(es=4); //少分号

label1=labelp++;

fprintf(fout,“LABEL%d:/n”,label1);//设置label1标号

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=expression();

if (es》0) return(es);

label2=labelp++;

fprintf(fout,“ BRF LABEL%d/n”,label2);//输出假条件转移指令

label3=labelp++;

fprintf(fout,“ BR LABEL%d/n”,label3);//输出无条件转移指令

if (strcmp(token,“;”)) return(es=4); //少分号

label4=labelp++;

fprintf(fout,“LABEL%d:/n”,label4);//设置label4标号

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=expression();

if (es》0) return(es);

fprintf(fout,“ BR LABEL%d/n”,label1);//输出无条件转移指令

if (strcmp(token,“)”)) return(es=6); //少右括号

fprintf(fout,“LABEL%d:/n”,label3);//设置label3标号

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=statement();

if (es》0) return(es);

fprintf(fout,“ BR LABEL%d/n”,label4);//输出无条件转移指令

fprintf(fout,“LABEL%d:/n”,label2);//设置label2标号

return(es);

}

//《write_stat》::=write 《expression》;

//《write_stat》::=write 《expression》@OUT;

//动作解释:

//@ OUT:输出 OUT

int write_stat()

{

int es=0;

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=expression();

if (es》0)return(es);

if (strcmp(token,“;”)) return(es=4); //少分号

fprintf(fout,“ OUT/n”);//输出指令

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

return(es);

}

//《read_stat》::=read ID;

//《read_stat》::=read ID↑n LOOK↓n↑d @IN@STI↓d;

//动作解释:

//@LOOK↓n↑d:查符号表n,给出变量地址d; 没有,变量没定义

//@IN:输出IN

//@STI↓d:输出指令代码STI d

int read_stat()

{

int es=0,address;

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

if (strcmp(token,“ID”)) return(es=3); //少标识符

es=lookup(token1,&address);

if (es》0) return(es);

fprintf(fout,“ IN /n”);//输入指令

fprintf(fout,“ STI %d/n”,address);//指令

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

if (strcmp(token,“;”)) return(es=4); //少分号

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

return(es);

}

//《compound_stat》::={《statement_list》}

int compound_stat(){ //复合语句函数

int es=0;

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=statement_list();

return(es);

}

//《expression_stat》::=《expression》;|;

int expression_stat()

{

int es=0;

if (strcmp(token,“;”)==0)

{

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

return(es);

}

es=expression();

if (es》0) return(es);

if (strcmp(token,“;”)==0)

{

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

return(es);

} else

{

es=4;

return(es);//少分号

}

}

//《expression》::=ID↑n@LOOK↓n↑d@ASSIGN=《bool_expr》@STO↓d |《bool_expr》

int expression()

{

int es=0,fileadd;

char token2[20],token3[40];

if (strcmp(token,“ID”)==0)

{

fileadd=ftell(fp); //@ASSIGN记住当前文件位置

fscanf(fp,“%s %s/n”, &token2,&token3);

printf(“%s %s/n”,token2,token3);

if (strcmp(token2,“=”)==0) //‘=’

{

int address;

es=lookup(token1,&address);

if (es》0) return(es);

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=bool_expr();

if (es》0) return(es);

fprintf(fout,“ STO %d/n”,address);

} else

{

fseek(fp,fileadd,0); //若非‘=’则文件指针回到‘=’前的标识符

printf(“%s %s/n”,token,token1);

es=bool_expr();

if (es》0) return(es);

}

} else es=bool_expr();

return(es);

}

//《bool_expr》::=《additive_expr》

// |《 additive_expr 》(》|《|》=|《=|==|!=)《 additive_expr 》

/*

《bool_expr》::=《additive_expr》

|《 additive_expr 》》《additive_expr》@GT

|《 additive_expr 》《《additive_expr》@LES

|《 additive_expr 》》=《additive_expr 》@GE

|《 additive_expr 》《=《 additive_expr 》@LE

|《 additive_expr 》==《 additive_expr 》@EQ

|《 additive_expr 》!=《 additive_expr 》@NOTEQ

*/

int bool_expr()

{

int es=0;

es=additive_expr();

if(es》0) return(es);

if ( strcmp(token,“》”)==0 || strcmp(token,“》=”)==0

||strcmp(token,“《”)==0 || strcmp(token,“《=”)==0

||strcmp(token,“==”)==0|| strcmp(token,“!=”)==0)

{

char token2[20];

strcpy(token2,token);//保存运算符

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=additive_expr();

if(es》0) return(es);

if ( strcmp(token2,“》”)==0 ) fprintf(fout,“ GT/n”);

if ( strcmp(token2,“》=”)==0 ) fprintf(fout,“ GE/n”);

if ( strcmp(token2,“《”)==0 ) fprintf(fout,“ LES/n”);

if ( strcmp(token2,“《=”)==0 ) fprintf(fout,“ LE/n”);

if ( strcmp(token2,“==”)==0 ) fprintf(fout,“ EQ/n”);

if ( strcmp(token2,“!=”)==0 ) fprintf(fout,“ NOTEQ/n”);

}

return(es);

}

//《additive_expr》::=《term》{(+|-)《 term 》}

//《 additive_expr》::=《term》{(+《 term 》@ADD |-《项》@SUB)}

int additive_expr()

{

int es=0;

es=term();

if(es》0) return(es);

while (strcmp(token,“+”)==0 || strcmp(token,“-”)==0)

{

char token2[20];

strcpy(token2,token);

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=term();

if(es》0) return(es);

if ( strcmp(token2,“+”)==0 ) fprintf(fout,“ ADD/n”);

if ( strcmp(token2,“-”)==0 ) fprintf(fout,“ SUB/n”);

}

return(es);

}

//《 term 》::=《factor》{(*| /)《 factor 》}

//《 term 》::=《factor》{(*《 factor 》@MULT | /《 factor 》@DIV)}

int term()

{

int es=0;

es=factor();

if(es》0) return(es);

while (strcmp(token,“*”)==0 || strcmp(token,“/”)==0)

{

char token2[20];

strcpy(token2,token);

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=factor();

if(es》0) return(es);

if ( strcmp(token2,“*”)==0 ) fprintf(fout,“ MULT/n”);

if ( strcmp(token2,“/”)==0 ) fprintf(fout,“ DIV/n”);

}

return(es);

}

//《 factor 》::=(《additive_expr》)| ID|NUM

//《 factor 》::=(《 expression 》)| ID↑n@LOOK↓n↑d@LOAD↓d |NUM↑i@LOADI↓i

int factor()

{

int es=0;

if (strcmp(token,“(”)==0)

{

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

es=expression();

if (es》0) return(es);

if (strcmp(token,“)”)) return(es=6); //少右括号

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

} else

{

if (strcmp(token,“ID”)==0)

{

int address;

es=lookup(token1,&address);//查符号表,获取变量地址

if (es》0) return(es);//变量没声明

fprintf(fout,“ LOAD %d/n”,address);

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

return(es);

}

if (strcmp(token,“NUM”)==0)

{

fprintf(fout,“ LOADI %s/n”,token1);

fscanf(fp,“%s %s/n”,&token,&token1);

printf(“%s %s/n”,token,token1);

return(es);

}else

{

es=7;//缺少操作数

return(es);

}

}

return(es);

}

//主程序

void main(){

int es=0;

es=TESTscan();//调词法分析

if (es》0) printf(“词法分析有错,编译停止!”);

else printf(“词法分析成功!/n”);

if (es==0)

{

es=TESTparse(); //调语法、语义分析并生成代码

if (es==0) printf(“语法、语义分析并生成代码成功!/n”);

else printf(“语法、语义分析并生成代码错误!/n”);

}

}

下面我们可以进行测试:如下我挑了几个典型的。大家可以看看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值