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