武汉大学编译原理第一次作业

/*
* 	计科3 halfopen
*	第一次作业,老师不要求做思考题
*	问题二:XL语言分析器的结合次序和优先级, 用retsuff.exe对输入表达式: "1 + 2 + 3;", 
   		先进行 1 + 2 的运算, 还是先进行 2 + 3 的运算. 
  	 	输入"1+2*3;",先算"2*3",还是先算"1+2".
	答:
		Please input an infix expression and ending with ";"
		1+2*3;
		    t0 = 1
		    t1 = 2
		    t2 = 3
		    t1 *= t2
		    t0 += t1
		the affix expression is + 1 * 2 3
	输出结果如上,所以是先算2*3

**/

/* retinf.c   	AXL分析器 */
#include 
#include 
#include 

#include "lex.h"

char err_id[] = "error";
char * midexp;
extern char * yytext;

struct YYLVAL {
  char * val;  /* 记录表达式中间临时变量 */
  char * expr; /* 记录表达式后缀式 */
  int last_op;  /* last operation of expression 
		   for elimination of redundant parentheses */
};

typedef struct YYLVAL Yylval;
Yylval    *factor     ( void );
Yylval    *term       ( void );
Yylval    *expression ( void );

char *newname( void ); /* 在name.c中定义 */
char *getVar(void);
extern void freename( char *name );

void statements ( void )
{
  /*  statements -> expression SEMI  |  expression SEMI statements  */
  
  Yylval *temp;
  printf("Please input an affix expression and ending with \";\"\n");
  while( !match(EOI) ){
    temp = expression();
    printf("the infix expression is %s\n", temp -> expr);
    freename(temp -> val);
    free(temp -> expr);
    free(temp);    
    if( match( SEMI ) ){
      advance();
      printf("Please input an affix expression and ending with \";\"\n");
    }
    else
      fprintf( stderr, "%d: Inserting missing semicolon\n", yylineno );
  }
}

/*
*test 
*/
void print_var(Yylval *t){
	char op = yytext[0];
	printf("expr:%s val:%s last_op:%c\n",t->expr,t->val, op);
}

Yylval *expression(void)
{ 
  /*
    expression -> PLUS expression expression
               |  MINUS expression expression
               |  TIMES expression expression
               |  DIVISION expression expression
	       |  NUM_OR_ID
  */
	Yylval* temp;
	temp=(Yylval *) malloc(sizeof(Yylval));
	if(match(PLUS)||match(MINUS) || match(TIMES)|| match(DIVISION) ){ //for the first 4 cases;
		temp = term();
 	}else if(match(NUM_OR_ID)){ //for the last case;
	    temp = factor();
	}
	else
		advance();
	return temp;
}

Yylval *term(void)
{
	Yylval* temp;
	temp=(Yylval *) malloc(sizeof(Yylval));
	int type=0;
	if(match(TIMES)||match(DIVISION)) type = 1;
	char op=yytext[0];
    advance();
    Yylval* temp1=expression();
    Yylval* temp2=expression();

    printf("%s %c = %s\n",temp1->val,op,temp2->val);
	freename(temp2->val); //release unused register
    temp->val=temp1->val;	//update the register's number
	if(type ==0){ 
		temp->last_op=1; 
     	temp->expr=(char *)malloc(strlen(temp1->expr)+1+strlen(temp2->expr));
     	sprintf( temp->expr, "%s %c %s",temp1->expr, op, temp2->expr);
	}else{
		temp->last_op=2;
	    if(temp1->last_op==1||temp2->last_op==1){ 
		    if(temp1->last_op!=1){ // a*(b+c)
			    temp->expr=(char *)malloc(strlen(temp1->expr)+3+strlen(temp2->expr));
			    sprintf(temp->expr,"%s %c %c %s %c",temp1->expr,op,'(',temp2->expr,')');
			}else if(temp2->last_op!=1){ // (a+c)*b
			    temp->expr=(char *)malloc(strlen(temp1->expr)+3+strlen(temp2->expr));
			    sprintf(temp->expr,"%c %s %c %c %s",'(',temp1->expr,')',op,temp2->expr);
			 }else{	//(a+b)*(c+d)
			    temp->expr=(char *)malloc(strlen(temp1->expr)+5+strlen(temp2->expr));
			    sprintf(temp->expr,"%c %s %c %c %c %s %c",'(',temp1->expr,')',op,'(',temp2->expr,')');
		   	 }
		}else{ //a+b+c
		    temp->expr=(char *)malloc(strlen(temp1->expr)+1+strlen(temp2->expr));
		    sprintf(temp->expr, "%s %c %s", temp1->expr, op, temp2->expr);
		  }
	}
	return temp;	     
}

Yylval* factor(void)
{
	char *name;
	char *name1 = newname(); 
	Yylval* temp;
	temp=(Yylval *) malloc(sizeof(Yylval));
	name = (char *) malloc(yyleng + 1);
	strncpy(name, yytext, yyleng);
	
	printf("%s = %s\n",name1,name);	
	temp->expr=(char *)malloc(strlen(name));
	sprintf(temp->expr,"%s",name);
	temp->last_op=2;
	temp->val=name1;	
	advance();
	return temp;
}

你可能感兴趣的:(compiler)