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

📄 pl0.txt

📁 PL/0的C语言版本
💻 TXT
📖 第 1 页 / 共 3 页
字号:
 enter(id, varbl, 0);
 p = ix;
 getsym();
 while(sym == comma)
 {
  getsym();
  check(ident);
  enter(id, varbl, 0);
  getsym();
 }
 q = ix;
 skip(colon);
 typ(&t);
 skip(semicolon);
 do{
  itab[p].vlevel = lev;
  dx = dx - ttab[t].size;
  itab[p].tip = t;
  itab[p].vadr = dx;
  itab[p].refpar = FALSE;
  p = p + 1;
 }while(p <= q); 
}

/*参数列表*/
void paramlist(int *p, int * ps)
{
 BOOL r;
 int t;
 if(sym == varsym)
 {
  r = TRUE;
  getsym();
 }
 else
  r = FALSE;
 check(ident);
 *p = ix;
 enter(id, varbl, 0);
 getsym();
 while(sym == comma)
 {
  getsym();
  check(ident);
  enter(id, varbl, 0);
  getsym();
 }
 skip(colon);
 check(ident);
 typ(&t);
 while(*p < ix)
 {
  *p = *p + 1;
  itab[*p].tip = t;
  itab[*p].refpar = r;
  if(r)
   *ps = *ps + 1; /*传地址*/
  else
   *ps = *ps + ttab[t].size; /*传值*/
 }
}

void funcdeclaration(BOOL isf)
{
 int f, p, ps, odx;
 getsym();
 check(ident);
 enter(id, funkt, 0);
 getsym();
 f = ix;
 itab[f].flevel = lev;
 itab[f].fadr = codelabel();
 gen1(jump, 0);
 if(lev == lmax)
 {
  error(127); /*深度超过限度,应退出*/
 }
 lev = lev + 1;
 if(lev == -1)
  nl = 0;
 else
  namelist[lev] = 0;
 ps = 1;
 odx = dx;
 if(sym == lparen)
 {
  do{
   getsym();
   paramlist(&p, &ps);
  }while(sym == semicolon);
  skip(rparen);
 }
 if(lev > 1)
  dx = -1;
 else
  dx = 0;
 itab[f].resultadr = ps;
 p = f;
 while(p < ix)
 {
  p = p + 1;
  if(itab[p].refpar)
   ps = ps - 1;
  else
   ps = ps - ttab[itab[p].tip].size;
  itab[p].vlevel = lev;
  itab[p].vadr = ps;
 }
 if(isf == TRUE)
 {
  skip(colon);
  check(ident);
  typ(&(itab[f].tip));
  if(ttab[itab[f].tip].kind != simple)
   error(128); /*只能返回简单类型*/
 }
 skip(semicolon);
 itab[f].lastpar = ix;
 itab[f].inside = TRUE;
 block(itab[f].fadr);
 itab[f].inside = FALSE;
 gen1(pexit, itab[f].resultadr - dx);
 lev = lev - 1;
 dx = odx;
 skip(semicolon);
}

void block(int l)
{
 int d, odx, oix;
 odx = dx;
 oix = ix;
 if(sym == constsym)
 {
  getsym();
  check(ident);
  do{
   constdeclaration();
  }while(sym == ident);
 }
 if(sym == typesym)
 {
  getsym();
  check(ident);
  do{
   typedeclaration();
  }while(sym == ident);
 }
 if(sym == varsym)
 {
  getsym();
  check(ident);
  do{
   vardeclaration();
  }while(sym == ident);
 }
 while(sym == funcsym || sym == procsym)
 {
  if(sym == funcsym)
   funcdeclaration(TRUE);
  else
   funcdeclaration(FALSE);
 }
 if(l + 1 == codelabel())
  cx = cx -1;
 else
  code[l].a = codelabel();
 if(lev == 0)
  gen1(sets, dx);
 else
 {
  d = dx - odx;
  dx = odx;
  gen1(adjs, d);
 }
 statement();
 if(lev != 0)
  gen1(adjs, odx - dx);
 ix = oix;
}

void listcode(FILE * fi)
{
 int i;
 for(i = 0; i < cx; i++)
 {
  fprintf(fi, "%-4d :   ", i);
  switch(code[i].op)
  {
  case add:
   fprintf(fi, "add\n");
   break;
        case neg:
   fprintf(fi, "neg\n");
   break;
        case mul:
   fprintf(fi, "mul\n");
   break;
        case divd:
   fprintf(fi, "divd\n");
   break;
        case remd:
   fprintf(fi, "remd\n");
   break;
        case div2:
   fprintf(fi, "div2\n");
   break;
        case rem2:
   fprintf(fi, "rem2\n");
   break;
        case eqli:
   fprintf(fi, "eqli\n");
   break;
        case neqi:
   fprintf(fi, "neqi\n");
   break;
        case lssi:
   fprintf(fi, "lssi\n");
   break;
        case leqi:
   fprintf(fi, "leqi\n");
   break;
        case gtri:
   fprintf(fi, "gtri\n");
   break;
        case geqi:
   fprintf(fi, "geqi\n");
   break;
        case dupl:
   fprintf(fi, "dupl\n");
   break;
        case swap:
   fprintf(fi, "swap\n");
   break;
        case andb:
   fprintf(fi, "andb\n");
   break;
        case orb:
   fprintf(fi, "orb\n");
   break;
        case load:
   fprintf(fi, "load\n");
   break;
        case stor:
   fprintf(fi, "stor\n");
   break;
        case hhalt:
   fprintf(fi, "hhalt\n");
   break;
        case wri:
   fprintf(fi, "wri\n");
   break;
        case wrc:
   fprintf(fi, "wrc\n");
   break;
        case wrl:
   fprintf(fi, "wrl\n");
   break;
        case rdi:
   fprintf(fi, "rdi\n");
   break;
        case rdc:
   fprintf(fi, "rdc\n");
   break;
        case rdl:
   fprintf(fi, "rdl\n");
   break;
        case eol:
   fprintf(fi, "eol\n");
   break;
        case ldc:
   fprintf(fi, "ldc   %d\n", code[i].a);
   break;
        case ldla:
   fprintf(fi, "ldla  %d\n", code[i].a);
   break;
        case ldl:
   fprintf(fi,"ldl   %d\n", code[i].a);
   break;
        case ldg:
   fprintf(fi, "ldg   %d\n", code[i].a);
   break;
        case stl:
   fprintf(fi, "stl   %d\n", code[i].a);
   break;
        case stg:
   fprintf(fi, "stg   %d\n", code[i].a);
   break;
        case move:
   fprintf(fi, "move  %d\n", code[i].a);
   break;
        case copy:
   fprintf(fi, "copy  %d\n", code[i].a);
   break;
        case addc:
   fprintf(fi, "addc  %d\n", code[i].a);
   break;
        case mulc:
   fprintf(fi, "mulc  %d\n", code[i].a);
   break;
        case jump:
   fprintf(fi, "jump  %d\n", code[i].a);
   break;
        case jumpz:
   fprintf(fi, "jumpz %d\n", code[i].a);
   break;
        case call:
   fprintf(fi, "call  %d\n", code[i].a);
   break;
        case adjs:
   fprintf(fi, "adjs  %d\n", code[i].a);
   break;
        case sets:
   fprintf(fi, "sets  %d\n", code[i].a);
   break;
        case pexit:
   fprintf(fi, "exit  %d\n", code[i].a);
   break;
  }
 }
}

void compile()
{
 ttab[intip].size = 1;
 ttab[intip].kind = simple;
 ttab[chartip].size = 1;
 ttab[chartip].kind = simple;
 ttab[booltip].size = 1;
 ttab[booltip].kind = simple;
 tx = 3;
 nl = 0; /* namelist[-1] = 0; */
 lev = -1;
 ix = 0;
 enter("false", konst, booltip);
 itab[ix].val = FALSE;
 enter("true", konst, booltip);
 itab[ix].val = TRUE;
 enter("maxint", konst, intip);
 itab[ix].val = 32767;
 enter("integer", tipe, intip);
 enter("char", tipe, chartip);
 enter("boolean", tipe, booltip);

 enter("abs", funkt, intip);
 itab[ix].flevel = -1;
 itab[ix].fadr = fabs;
 itab[ix].inside = FALSE;

 enter("sqr", funkt, intip);
 itab[ix].flevel = -1;
 itab[ix].fadr = fsqr;
 itab[ix].inside = FALSE;

 enter("odd", funkt, booltip);
 itab[ix].flevel = -1;
 itab[ix].fadr = fodd;
 itab[ix].inside = FALSE;

 enter("chr", funkt, chartip);
 itab[ix].flevel = -1;
 itab[ix].fadr = fchr;
 itab[ix].inside = FALSE;

 enter("ord", funkt, intip);
 itab[ix].flevel = -1;
 itab[ix].fadr = ford;
 itab[ix].inside = FALSE;

 enter("write", funkt, 0);
 itab[ix].flevel = -1;
 itab[ix].fadr = fwrite;

 enter("writeln", funkt, 0);
 itab[ix].flevel = -1;
 itab[ix].fadr = fwriteln;

 enter("read", funkt, 0);
 itab[ix].flevel = -1;
 itab[ix].fadr = fread;

 enter("readln", funkt, 0);
 itab[ix].flevel = -1;
 itab[ix].fadr = freadln;

 enter("eoln", funkt, booltip);
 itab[ix].flevel = -1;
 itab[ix].fadr = feoln;
 itab[ix].inside = FALSE;

 namelist[0] = 0;
 lev = 0;
 cc = 0;
 ll = 0;

 getch();
 getsym();

 labeled = FALSE;
 cx = 0;
 dx = amax + 1;

 skip(progsym);
 skip(ident);
 check(lparen);
 do{
  getsym();
  check(ident);
  if(strcmp(id, "input") != 0 && strcmp(id, "output") != 0)
   error(129);
  getsym();
 }while(sym == comma);
 skip(rparen);
 skip(semicolon);
 gen1(jump, 0);
 block(0);
 gen0(hhalt);
 check(period);
}

/*解释执行*/
void interpret()
{
 int pc, sp, j, k, n;
 instr i;
 char c;
 BOOL h;

 pc = 0;
 h = FALSE;
 do{
  i = code[pc];
  pc = pc + 1;
  switch(i.op)
  {
  case add:
   m[sp + 1] = m[sp + 1] + m[sp];
   sp = sp + 1;
   break;
  case neg:
   m[sp] = -m[sp];
   break;
  case mul:
   m[sp + 1] = m[sp + 1] * m[sp];
   sp = sp + 1;
   break;
  case divd:
   m[sp + 1] = m[sp + 1] / m[sp];
   sp = sp + 1;
   break;
  case remd:
   m[sp + 1] = m[sp + 1] % m[sp];
   sp = sp + 1;
   break;
  case div2:
   m[sp] = m[sp] / 2;
   break;
  case rem2:
   m[sp] = m[sp] % 2;
   break;
  case eqli:
   m[sp + 1] = (m[sp + 1] == m[sp]);
   sp = sp + 1;
   break;
  case neqi:
   m[sp + 1] = (m[sp + 1] != m[sp]);
   sp = sp + 1;
   break;
  case lssi:
   m[sp + 1] = (m[sp + 1] < m[sp]);
   sp = sp + 1;
   break;
  case leqi:
   m[sp + 1] = (m[sp + 1] <= m[sp]);
   sp = sp + 1;
   break;
  case gtri:
   m[sp + 1] = (m[sp + 1] > m[sp]);
   sp = sp + 1;
   break;
  case geqi:
   m[sp + 1] = (m[sp + 1] >= m[sp]);
   sp = sp + 1;
   break;
  case dupl:
   sp = sp - 1;
   m[sp] = m[sp + 1];
   break;
  case swap:
   k = m[sp];
   m[sp] = m[sp + 1];
   m[sp + 1] = k;
   break;
  case andb:
   if(m[sp] == 0)
    m[sp + 1] = 0;
   sp = sp + 1;
   break;
  case orb:
   if(m[sp] == 1)
    m[sp + 1] = 1;
   sp = sp + 1;
   break;
  case load:
   m[sp] = m[m[sp]];
   break;
  case stor:
   m[m[sp]] = m[sp + 1];
   sp = sp + 2;
   break;
  case hhalt:
   h = TRUE;
   break;
  case wri:
   /*待定*/
   fprintf(stdout, "%d", m[sp + 1]);
   sp = sp + 2;
   break;
  case wrc:
   fprintf(stdout, "%c", m[sp]);
   sp = sp + 1;
   break;
  case wrl:
   fprintf(stdout, "\n");
   break;
  case rdi:
   fprintf(stdout, "input integer: ");
   fscanf(stdin, "%d", &(m[m[sp]]));
   sp = sp + 1;
   break;
  case rdc:
   fprintf(stdout, "input character: ");
   fscanf(stdin, "%c", &c);
   m[m[sp]] = c;
   sp = sp + 1;
   break;
  case rdl:
   /*待定*/
   break;
  case eol:
   sp = sp - 1;
   m[sp] = feof(stdin);
   break;
  case ldc:
   sp = sp - 1;
   m[sp] = i.a;
   break;
  case ldla:
   sp = sp - 1;
   m[sp] = sp + 1 + i.a;
   break;
  case ldl:
   sp = sp - 1;
   m[sp] = m[sp + 1 + i.a];
   break;
  case ldg:
   sp = sp - 1;
   m[sp] = m[i.a];
   break;
  case stl:
   m[sp + i.a] = m[sp];
   sp = sp + 1;
   break;
  case stg:
   m[i.a] = m[sp];
   sp = sp + 1;
   break;
  case move:
   k = m[sp];
   j = m[sp + 1];
   sp = sp + 2;
   n = i.a;
   do{
    n = n - 1;
    m[k + n] = m[j + n];
   }while(n > 0);
   break;
  case copy:
   j = m[sp];
   n = i.a;
   sp = sp - n + 1;
   do{
    n = n - 1;
    m[sp + n] = m[j + n];
   }while(n > 0);
   break;
  case addc:
   m[sp] = m[sp] + i.a;
   break;
  case mulc:
   m[sp] = m[sp] * i.a;
   break;
  case jump:
   pc = i.a;
   break;
  case jumpz:
   if(m[sp] == 0)
    pc = i.a;
   sp = sp + 1;
   break;
  case call:
   sp = sp - 1;
   m[sp] = pc;
   pc = i.a;
   break;
  case adjs:
   sp = sp + i.a;
   break;
  case sets:
   sp = i.a;
   break;
  case pexit:
   pc = m[sp];
   sp = sp + i.a;
   break;
  }
 }while(h == FALSE);
}


void main(int argc, char **argv)
{
 char filename[81], save;
 FILE * sf;
 memset(filename, 0, 81);
 if(argc == 1)
 {
  fprintf(stdout, "please enter source file name: ");
  fscanf(stdin, "%s", filename);
 }
 else
  strcpy(filename, argv[1]);
 source = fopen(filename, "r");
 if(source == NULL)
 {
  fprintf(stderr, "cann't open file: %s\n", filename);
  return;
 }
 fprintf(stdout, "compiling...\n");
 compile();
 fclose(source);
 fprintf(stdout, "no errors, compile succeed.\n");
 fprintf(stdout, "--------------------------------\n");
 listcode(stdout);
 fprintf(stdout, "--------------------------------\n");
 fprintf(stdout, "Run>\n");
 interpret();
 fprintf(stdout, "program exit.\n");
 fprintf(stdout, "do you want to save the code(y or n): ");
 do{
  scanf("%c", &save);
 }while(save != 'y' && save != 'Y' && save != 'n' && save != 'N');
 if(save == 'y' || save == 'Y')
 {
  fprintf(stdout, "enter file name: ");
  scanf("%s", filename);
  sf = fopen(filename, "w");
  if(sf)
  {
   listcode(sf);
   fclose(sf);
  }
  else
   fprintf(stdout, "open file error, code not saved.\n");
 }
 
}

 

⌨️ 快捷键说明

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