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

📄 compiler.c

📁 该程序可以将简单中缀算术表达式变换成: (1)后缀形式 (2)生成书上描述的抽象堆栈机的代码 (3)对常量算术表达式
💻 C
字号:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>

void (*emit)(int,int);
int lexan(void);
void match(int);
void factor(void);
int expr(void);
int term(void);
void parser(void);
void init(void);
int lookup(char*);
int insert(char*,int);
void error(char *);

#define BSIZE 128
#define NONE -1
#define EOS '\0'
#define NUM 256
#define DIV 257
#define MOD 258
#define ID 259
#define DONE 260

static int RESULT;
static int lineno;
static int colno;
static int tokenval;

static int stack[100];
static int stacktop;

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

FILE *fp,*fpout;

//符号表的定义:
#define STRMAX 999
#define SYMMAX 100

char lexemes[STRMAX];
int lastchar =-1;
struct entry symtable[SYMMAX];
int lastentry =0;
//*********************
//*****************************************************lexer.c
char lexbuf[BSIZE];
lineno=1;
colno=1;
tokenval=NONE;
int lexan()  
{
	int t;

	while(1){
		t=fgetc(fp);
		if(t==' '||t=='\t');
		else if(t=='\n'){
			lineno=lineno+1;
		}else if(isdigit(t)){    
			ungetc(t,fp);
			fscanf(fp,"%d",&tokenval);
			return NUM;
		}else if(isalpha(t)){  
			int p,b=0;
			while(isalnum(t)){  
				lexbuf[b]=t;
				t=fgetc(fp);
				b++;
				if(b>=BSIZE){
					error("compiler error");
					return 0;
				}
			}
			lexbuf[b]=EOS;
			if(t!=EOF)
				ungetc(t,fp);
			p=lookup(lexbuf);
			if(p==0)
				p=insert(lexbuf,ID);
			tokenval=p;
			return symtable[p].token;
		}
		else if(t==EOF)
			return DONE;
		else {
			tokenval=NONE;
			return t;
		}
	}
}
//*************************************************parser.c
static int lookahead;
void parser()
{
	lookahead=lexan();
	while(lookahead!=DONE){
		expr();
		match(';');
	}
}
void match(int t)
{
	if(t==';'){
		if(RESULT==1)fprintf(fpout,"%d\n",stack[0]);
		fprintf(fpout,"%c",'\n');
	}
	if(lookahead==t)
		lookahead=lexan();
	else error("syntax error");
}
void factor()
{
	switch(lookahead){
	case'(':
		match('(');
		expr();
		match(')');
		break;
	case NUM:
		emit(NUM,tokenval);
		match(NUM);
		break;
	case ID:
		emit(ID,tokenval);
		match(ID);
		break;
	default:
		error("syntax error");
	}
}
int expr()
{
	int t;
	term();
	while(1){
		switch (lookahead){
			case '+':
			case '-': 
				t=lookahead;
				match(lookahead);
				term();
				emit(t,NONE);
				continue;
			default:
				return 1;
		}
	}
}
int 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 1;
		}
	}
}
//*************************************************emitter.c
void diremit(int t,int tval)
{
	switch(t){
	case '+': case '-': case '*': case '/':
		fprintf(fpout,"%c\n",t);
		break;
	case DIV:
		fprintf(fpout,"DIV\n");
		break;
	case MOD:
		fprintf(fpout,"MOD\n");
		break;
	case NUM:
		fprintf(fpout,"%d\n",tval);
		break;
	case ID:
		fprintf(fpout,"%s\n",symtable[tval].lexptr);
		break;
	default :
		fprintf(fpout,"token %d,tokenval %d\n",t,tval);
	}
}
//*********************************************************abstackemit.c
void abstackemit(int t,int tval)
{
	switch(t){
	case '+': case '-': case '*': case '/':
		fprintf(fpout,"%c\n",t);
		break;
	case DIV:
		fprintf(fpout,"DIV\n");
		break;
	case MOD:
		fprintf(fpout,"MOD\n");
		break;
	case NUM:
		fprintf(fpout,"push %d\n",tval);
		break;
	case ID:
		fprintf(fpout,"rvalue %s\n",symtable[tval].lexptr);
		break;
	default :
		fprintf(fpout,"token %d,tokenval %d\n",t,tval);
	}
}
//************************************************************getresult.c
int pop()
{
	return stack[--stacktop];
}
void push(int t)
{	
	stack[stacktop++]=t;
}
int calculate(int i,int j,int t)
{
	switch(t){
	case '+':
		return i+j;break;
	case '-':
		return i-j;break;
	case '*':
		return i*j;break;
	case '/':case DIV:
		return i/j;
		break;
	case MOD:
		return i%j;
		break;
	}
	return 0;
}
void getresult(int t,int tval)
{
	char errstr[100];
	switch(t){
	case '+': case '-': case '*': case '/':case DIV:case MOD:
		push(calculate(pop(),pop(),t));
		break;
	case NUM:
		push(tval);
		break;
	case ID:
		strcpy(errstr,symtable[tval].lexptr);
		strcat(errstr,":symbol can'not be calculated");
		error(errstr);
		break;
	default :
		fprintf(fpout,"token %d,tokenval %d\n",t,tval);
	}
}
//****************************************************symbol.c


int lookup(char s[])
{
	int p;
	for(p=lastentry;p>0;p--)
		if(strcmp(symtable[p].lexptr,s)==0)
			return p;
	return 0;
}
int insert(char s[],int tok)
{
	int len;
	len=strlen(s);
	if(lastentry+1>=SYMMAX)
		error("symbol table full");
	if(lastchar +len+1>=STRMAX)
		error("lexemes array 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

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

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

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

int main(int argc, char* argv[])
{
	init();
	if(argc!=4||(strcmp(argv[1],"-s")&&strcmp(argv[1],"-r")&&strcmp(argv[1],"-d"))){
        printf("CopyRight cs040032 2007.04.04\n");                                                                                                                                                                            
		printf("choose mode\n-s for abstract stack\n-d for direct translate\n-r for output result\n");
		printf("execute as :[finename][option...-r.-s.-d][file in][file out]\n");
		return 0;
	}
	if((fp=fopen(argv[2],"r"))==NULL){
 	    printf("cannot open the file\n");
 	    exit(0);
	}
	if((fpout=fopen(argv[3],"w"))==NULL){
   	    printf("open error\n");
   	    exit(0);
	}
	if(!strcmp(argv[1],"-s"))
		emit=abstackemit;
	if(!strcmp(argv[1],"-d"))
		emit=diremit;
	if(!strcmp(argv[1],"-r")){
		emit=getresult;
		RESULT=1;
	}
	parser(); 
    fclose(fp);
    fclose(fpout);
	return 0;
}

⌨️ 快捷键说明

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