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

📄 steve.c

📁 简单的编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define norw 13
#define txmax 100
#define nmax 14
#define al 10
#define amax 2047
#define levmax 3
#define cxmax 200
#define stacksize 500

char *symbol[32]={"nul","ident","number","plus","minus","times","slash","oddsym","eql","neq","lss","leq","gtr","geq","lparen","rparen","comma","semicolon","period","becomes","beginsym","endsym","ifsym","thensym","whilesym","writesym","readsym",
"dosym","callsym","constsym","varsym","procsym"};

char *word[norw]={"begin","call","const","do","end","if","odd","procedure","read","then","var","while","write"};

char *wsym[norw]={"beginsym","callsym","constsym","dosym","endsym","ifsym","oddsym","procsym","readsym","thensym","varsym","whilesym","writesym"};

char *mnemonic[8]={"lit","opr","lod","sto","cal","ini","jmp","jpc"};

char ch;                        /*last char read*/
char id[al];                    /*last identifier read*/
char sym[10];                /*last symbol read*/
char line[81];
char a[al],fname[al];

enum object{constant,variable,procedur};
enum object kind;
enum fct{lit,opr,lod,sto,cal,ini,jmp,jpc};
enum listswitcher{false,true};
enum listswitcher listswitch;

FILE *fa;
FILE *fa1,*fa2;
FILE *fin,*fout;

int num;                        /*last number read*/
int cc;                           /*character count*/
int ll;
int kk;
int cx;                  /*code allocation index*/
int err;
int lev=0,tx,dx=0;
int linecnt=0;

struct instruction
{ enum fct f;                          /*function code*/
   int l;                          /*level*/
   int a;                  /*displacement addr*/
};

struct instruction code[cxmax+1];
struct table1
{ char name[al];
   enum object kind;
   int val,level,adr,size;
};

struct table1 table[txmax+1];

struct node{
char *pa[32];}*declbegsys,*statbegsys,*facbegsys,*tempsetsys;

int in(str,set)
char *str;
struct node *set;
{ int i=0;
  while(set->pa[i]!=NULL)
      {  if(strcmp(str,set->pa[i])==0)
               return (1);
          else    i++;
       }
   return (0);}


struct node *add(set1,set2)
struct node *set1,*set2;
{ int i=0,j=0,k=0,cnt;
  struct node *pt;
  pt=(struct node *)malloc(sizeof(struct node));
  for (cnt=0;cnt<32;cnt++)
           pt->pa[cnt]=(char*)malloc(10*sizeof(char));

 while(set1->pa[i]!=NULL)
           strcpy(pt->pa[j++],set1->pa[i++]);

 while(set2->pa[k]!=NULL)
         {  if (in(set2->pa[k],set1)==0)
                    strcpy(pt->pa[j++],set2->pa[k++]);
             else  k++;
          }
 pt->pa[j]=NULL;
 return(pt);}



error(int n)
{ int i;
  printf("***");
  fputs("***",fa1);
  for(i=0;i<cc;i++)
        {printf("  ");}
  for(i=0;i<cc;i++)
	fputs(" ",fa1);
  printf("error%d\n",n);
  fprintf(fa1,"error%d\n",n);
  err++;
 }


void get_ch()
{ if(cc==ll+1)
       {  if (feof(fin))
                 printf("program incomplete");
           ll=0;
           cc=0;
           while((ch=fgetc(fin))!='\n')
                 { putchar(ch);
		   fputc(ch,fa1);
                   line[ll++]=ch;}
           printf("\n");
           line[ll]=ch;
	   fprintf(fa1,"\n");
       }
   ch=line[cc++];
 }

void getsym()
{ int i,j,k;
  while(ch==' '||ch=='\t'||ch=='\n')
       get_ch();
  if(ch>='a'&&ch<='z')
       { k=0;
          do  {  if(k<al) {a[k]=ch;k++;}
                    get_ch();
          } while((ch>='a'&&ch<='z')||(ch>='0'&&ch<='9'));
         if(k>=kk)   kk=k;
         else while (k<kk-1) a[k++]=' ';
         strcpy(id,a);
         i=0;
         j=norw-1;
        do{
           k=(i+j)/2;
           if (strcmp(id,word[k])<=0)j=k-1;
           if (strcmp(id,word[k])>=0)i=k+1;
          }while(i<=j);
       if(i-1>j)strcpy(sym,wsym[k]);
       else strcpy(sym,"ident");
     }
else if (ch>='0'&&ch<='9')
      {    k=0;num=0;
           strcpy(sym,"number");
           do{ num=10*num+(int)ch-'0';
                  k++;
                 get_ch();
                }while(ch>='0'&&ch<='9');
            if(k>nmax)error(30);
       }
else if (ch==':')
     {    get_ch();
           if(ch=='=')   {strcpy(sym,"becomes");
                                get_ch();}
           else strcpy(sym,"nul");
      }
else if (ch=='<')
      {    get_ch();
            if (ch=='='){strcpy(sym,"leq");
                               get_ch();}
            else strcpy(sym,"lss");
        }
else if(ch=='>')
      {     get_ch();
             if(ch=='=') { strcpy(sym,"geq");
                                get_ch();}
              else strcpy(sym,"gtr");
       }
 else {
switch(ch){
case '+':strcpy(sym,"plus");break;
case '-':strcpy(sym,"minus");break;
case '*':strcpy(sym,"times");break;
case '/':strcpy(sym,"slash");break;
case '(':strcpy(sym,"lparen");break;
case ')':strcpy(sym,"rparen");break;
case '=':strcpy(sym,"eql");break;
case ',':strcpy(sym,"comma");break;
case '.':strcpy(sym,"period");break;
case '#':strcpy(sym,"neq");break;
case ';':strcpy(sym,"semicolon");break;
}
get_ch();
}
}

void gen (x,y,z)
enum fct x;
int y,z;
{ if (cx>cxmax)   printf("program too long");
  code[cx].f=x;
  code[cx].l=y;
  code[cx].a=z;
  cx++;
}

void test(s1,s2,n)
struct node *s1,*s2;
int n;
{ if(in(sym,s1)==0)
     { error(n);
       s1=add(s1,s2);
       while(in(sym,s1)==0)  getsym();
}
}

void enter(k)
enum object k;
{ tx=tx+1;
  strcpy(table[tx].name,id);
  table[tx].kind=k;
  switch(k)
     {  case constant:  if (num>nmax)
                          {  error(31); num=0;}
                        table[tx].val=num;break;
        case variable:  table[tx].level=lev;
                        table[tx].adr=dx;dx++;break;
        case procedur:table[tx].level=lev;break;
}
}

int position(id)
char id[10];
{int i;
strcpy(table[0].name,id);
i=tx;
while (strcmp(table[i].name,id)!=0)
       i--;
return i;}



void constdeclaration()
{ if (strcmp(sym,"ident")==0)
     { getsym();
       if(strcmp(sym,"eql")==0||strcmp(sym,"becomes")==0)
           { if(strcmp(sym,"becomes")==0) error(1);
             getsym();
	     if (strcmp(sym,"number")==0)
                 { enter(constant);
                   getsym();}
             else error(2);
           }
       else error(3);
     }
  else error(4);}


void vardeclaration()
{ if (strcmp(sym,"ident")==0){
   enter(variable);
   getsym();
   }
 else error(4);
}



void listcode(int *cx0)
{ int i;
  if(listswitch==true)
      {   for(i=*cx0;i<=cx-1;i++)
		 {  printf("%2d    %5s   %3d    %5d\n",i,mnemonic[(int)code[i].f],code[i].l,code[i].a);
		    fprintf(fa,"%2d    %5s   %3d   %5d\n",i,mnemonic[(int)code[i].f],code[i].l,code[i].a);}
       }
}

/*      293      */


void factor(fsys)
struct node *fsys;
{ void expression();
  int m=0,n=0,i;
  char *tempset[]={"rparen",NULL};
  struct node *temp;
  temp=(struct node * )malloc(sizeof(struct node));
  while(tempset[m]!=NULL)
       temp->pa[n++]=tempset[m++];
  temp->pa[n]=NULL;
  test(facbegsys,fsys,24);
  while(in(sym,facbegsys)==1)
       { if(strcmp(sym,"ident")==0) 
             { i=position(id);
               if(i==0) error(11);
               else switch(table[i].kind)
		  { case constant:gen(lit,0,table[i].val);break;
                    case variable:gen(lod,lev-table[i].level,table[i].adr+2);break;
                    case procedur:error(21);break;
                  }
               getsym();
             }
         else if(strcmp(sym,"number")==0)
             { if(num>amax) {error(31);num=0;} 
               gen(lit,0,num);
               getsym();
              }
         else if(strcmp(sym,"lparen")==0)
              { getsym();
                expression(add(temp,fsys));
                if (strcmp(sym,"rparen")==0)
		       getsym();
                else error(22);
               }
         test(fsys,facbegsys,23);
      }
}



void term(fsys)
struct node *fsys;
{ int i=0,j=0;
  char mulop[10];
  char *tempset[]={"times","slash",NULL};
  struct node *temp;
  temp=(struct node *)malloc(sizeof(struct node));
  while(tempset[i]!=NULL)
       temp->pa[i++]=tempset[j++];
  temp->pa[i]=NULL;
  factor(add(temp,fsys));
  while(in(sym,tempset)==1)
      { strcpy(mulop,sym);
        getsym();
        factor(add(tempset,fsys));
        if (strcmp(mulop,"times")==0)gen(opr,0,4);
        else gen(opr,0,5);
       }
}

void expression(fsys)
struct node *fsys;
{ int m=0,n=0;
  char addop[10];
  char *tempset[]={"plus","minus",NULL};
  struct node *temp;
  temp=(struct node *)malloc(sizeof(struct node));
  while(tempset[m]!=NULL)
      temp->pa[n++]=tempset[m++];
  temp->pa[n]=NULL;
  if(in(sym,temp)==1)
     { strcpy(addop,sym);
       getsym();
       term(add(fsys,temp));
       if(strcmp(addop,"minus")==0)gen(opr,0,1);
     }
  else term(add(fsys,temp));
  while(in(sym,temp)==1)
     { strcpy(addop,sym);
       getsym();
       term(add(fsys,temp));
       if(strcmp(addop,"plus")==0)gen(opr,0,2);
       else gen(opr,0,3);
     }
}

void condition(fsys)
struct node *fsys;
{ int i=0,j=0;
  char relop[10];
  char *tempset[]={"eql","neq","lss","leq","gtr","geq"};
  struct node *temp;
  temp=(struct node *)malloc(sizeof(struct node));
  while(tempset[i]!=NULL)
       temp->pa[j++]=tempset[i++];
  temp->pa[j]=NULL;
  if(strcmp(sym,"oddsym")==0)
       { getsym();
         expression(fsys);
         gen(opr,0,6);
        }
  else 
      { expression(add(temp,fsys));
        if(in(sym,temp)==0)  error(20);
        else
           { strcpy(relop,sym);
             getsym();
             expression(fsys);
             if(strcmp(relop,"eql")==0)gen(opr,0,8);
             if(strcmp(relop,"neq")==0)gen(opr,0,9);
             if(strcmp(relop,"lss")==0)gen(opr,0,10);
             if(strcmp(relop,"geq")==0)gen(opr,0,11);
             if(strcmp(relop,"gtr")==0)gen(opr,0,12);
             if(strcmp(relop,"leq")==0)gen(opr,0,13);
           } 
        }
}

/*         295                       */

⌨️ 快捷键说明

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