⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 translater.c

📁 将简单中缀算术表达式变换成: (1)后缀形式 (2)对常量算术表达式
💻 C
字号:
/**** global.h************************/
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>

#define BSIZE 128
#define NONE  -1
#define EOS  '\0'
#define N     20

#define NUM 256
#define DIV 257
#define MOD 258 
#define ID  259
#define DONE 260

#define STRMAX 999
#define SYMMAX 100

char lexemes[STRMAX];
int lastchar=-1;
//struct entry symtable[SYMMAX];
int lastentry=0;

int  tokenval=NONE;
int  lineno=1;
int  number[N];
FILE *fp,*fp1;
char lexbuf[BSIZE];
int lookahead;
int flag=1,flag1=0;
int i=0;

struct entry{
	char *lexptr;
	int  token;
};

struct entry keywords[]={
	"div",DIV,
	"mod",MOD,
	"DIV",DIV,
	"MOD",MOD,
      0,  0
};

struct entry symtable[SYMMAX];
//函数声明
int lexan();
void  parse(char *filename);
void expr();
void term();
void factor();
void match(int t);
void emit(int t,int tval);
int lookup(char s[]);
int insert(char s[],int tok);
void init();
void error(char *m);
FILE *clearline(char *filename);




/****lexer.c*****************************/

int lexan()
{//词法分析器
	int t;
	while(1){
		t=getc(fp);
		if(t==' '||t=='\t')
			;
		else if(t=='\n')
			lineno=lineno+1;   //记录当前所在行
		else if(isdigit(t)) {      //判断t是数字
			fseek(fp,-1,1);
			fscanf(fp,"%d",&tokenval);
			return NUM;
		}
		else if (isalpha(t)){   //t是字母
			int p,b=0;
			while(isalnum(t)){   //t是字母或数字
				lexbuf[b]=t;
				t=getc(fp);
				b=b+1;
				if(b>=BSIZE)
					error("compiler error");
			}
			lexbuf[b]=EOS;
			if(t!=EOF)
				fseek(fp,-1,1);
			p=lookup(lexbuf);   //看t是否在lexbuf中出现过
			if (p==0)
				p=insert(lexbuf,ID);//没有出现则将其插入到lexbuf中
			tokenval=p;
			return symtable[p].token;
		}
		else if (t==EOF)
			return DONE;
		else {
			tokenval=NONE;
			return t;
		}
	}
}

/*********parser.c**************************/

void parse(char *filename)
{
	lookahead=lexan();
	while(lookahead!=DONE){
		expr();match(';');
		       if(flag==0){  /*表达式中只有数字*/
                    if(flag1){  /*对常量表达式不输出后缀,而直接输入结果*/
                          fclose(fp1);
                          fp1=clearline(filename); //清除该行产生的后缀表达式
                          fprintf(fp1,"\n%d",number[0]);//在该行输出运算结果
                         }
                  }
                 i=0;flag=0;
                 fprintf(fp1,"\n");
                 if(flag1==1)fprintf(fp1,"\n");
	}
}

void expr()
{
	int t;
	term();
	while(1)
		switch(lookahead){
        case'+': case'-':
			t=lookahead;
			match(lookahead);
			term();
			emit(t,NONE);
			continue;
		default:
			return;
	}
}

void term()
{
	int t;
	factor();
	while(1)
		switch(lookahead){
        case'*': case'/': case DIV: case MOD:
             t=lookahead;
			 match(lookahead);
			 factor();
			 emit(t,NONE);
			 continue;
		default:
			return;
	}
}

void factor()
{
	switch(lookahead){
	case '(':
		match('(');expr();match(')');break;
	case NUM:
		emit(NUM,tokenval);
		if(flag==0)number[i++]=tokenval;
		match(NUM);break;
	case ID:
		emit(ID,tokenval);
		if(flag==0)flag=1;
		match(ID);break;
	default:
		error("syntax error");
	}
}

void match(t)
    int t;
{
	if(lookahead==t)
		lookahead=lexan();
	else error ("syntax error");
}

/****emitter.c*************************/
void emit(t,tval)
     int t,tval;
{
  	switch(t){
		case'+':
			if(flag1)fprintf(fp1,"%c",t);
			else fprintf(fp1,"%c\n",t);
			if(flag==0){
            number[i-2]+=number[i-1];
			i=i-1;
			}
			break;
		case'-':
			if(flag1)fprintf(fp1,"%c",t);
			else fprintf(fp1,"%c\n",t);
			if(flag==0){
			number[i-2]-=number[i-1];
			i=i-1;
			}
			break;
		case'*':
			if(flag1)fprintf(fp1,"%c",t);
			else fprintf(fp1,"%c\n",t);
			if(flag==0){
			number[i-2]*=number[i-1];
			i=i-1;}
			break;
		case'/':
			if(flag1)fprintf(fp1,"%c",t);
			else fprintf(fp1,"%c\n",t);
			if(flag==0){
			number[i-2]/=number[i-1];
			i=i-1;
			}
			break;
		case DIV:
			if(flag1)fprintf(fp1,"DIV",t);
			else fprintf(fp1,"DIV\n",t);
			if(flag==0){
			number[i-2]/=number[i-1];
			i=i-1;
			}
			break;
		case MOD:
			if(flag1)fprintf(fp1,"MOD",t);
			else fprintf(fp1,"MOD\n",t);
			if(flag==0){
			number[i-2]=(number[i-2])%(number[i-1]);
			i=i-1;
			}
			break;
		case NUM:
			if(flag1)fprintf(fp1,"%d",tval);
			else fprintf(fp1,"PUSH %d\n",tval);
            break;
	    case ID:
			if(flag1)fprintf(fp1,"%s",symtable[tval].lexptr);
			else fprintf(fp1,"RVALUE %s\n",symtable[tval].lexptr);
		    break;
	    default:
			if(flag1)fprintf(fp1,"\n");
	        fprintf(fp1,"token %d,tokenval %d\n",t,tval);
	}	
}

/****symbol.c*******************************/

int lookup(s)
    char s[];
{
	int p;
	for(p=lastentry;p>0;p=p-1)
		if(strcmp(symtable[p].lexptr,s)==0)
			return p;
		return 0;
}
int insert(s,tok)
    char s[];
    int tok;
{
	int len;
	len=strlen(s);
	if(lastentry+1>=SYMMAX)
		error("symbol table full");
    lastentry=lastentry+1;
	symtable[lastentry].token=tok;
    symtable[lastentry].lexptr=&lexemes[lastchar+1];
	lastchar=lastchar+len+1;
	strcpy(symtable[lastentry].lexptr,s);
	return lastentry;
}

/*********init.c****************************/


void init()
{
	struct entry *p;
	for (p=keywords;p->token;p++)
		insert(p->lexptr,p->token);
}

/****error.c*************************/
void error(m)
    char *m;
{
	fprintf(fp1,"line %d:%s\n",lineno,m);
	exit(1);
}

/************clearline*********************/
FILE *clearline(char *filename)
{
   char t;
   FILE *fp2;
   fp2=fopen(filename,"r+");
   fseek(fp2,-1,2);
   t=getc(fp2);
   fseek(fp2,-1,1);
	while(t!='\n'){
		fputc('\0',fp2);
		fseek(fp2,-2,1);
		t=fgetc(fp2);
		fseek(fp2,-1,1);
	}
	return fp2;
}


/*********main.c***************************/
int main(int argc,char *argv[])
{
	printf("--------------copyright-------------\n");
	printf("   lijunrong   04120043    2007/4/4\n");
       if(argc!=4){
           printf("input error!\n");
           exit(1);
         }
       if((argv[1][1]!='c')&&(argv[1][1]!='s')){
           printf("input no avail!\n");
           exit(1);
          }
	init();
        if(strcmp(argv[1],"-c")) flag1=1;  
        if((fp=fopen(argv[2],"r"))==NULL)
                printf("can not open the file %s\n",argv[2]);
        fp1=fopen(argv[3],"w");
	parse(argv[3]);
	fclose(fp);
        fclose(fp1);
	return(0);
}









⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -