📄 compiler.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 + -