[置顶] PL0文法编译器C语言源代码时间:2022-06-01 20:05:39这是我编译原理课程的课程设计时写的,对PL0文法进行了扩充,主要增加了数组及结构体的功能,并用C语言实现了之。可能有人需要,就在这贴出来了。 #include "stdio.h"#include "string.h"#include "stdlib.h"#include "ctype.h"#ifndef TRUE#define TRUE 1#endif#ifndef FALSE#define FALSE 0#endiftypedef int BOOL;#define cxmax 2000#define amax 16383#define imax 100 /* length of identifier table */#define tmax 100 /* length of type table */#define lmax 10 /* maximum level */#define al 10 /* length of identifiers */#define norw 27 /* number of reserverd words *//* standard function */#define fabs 0#define fsqr 1#define fodd 2#define fchr 3#define ford 4#define fwrite 5#define fwriteln 6#define fread 7#define freadln 8#define feoln 9/* standard types */#define intip 1#define booltip 2#define chartip 3/*指令码*/typedef enum opcode{add, neg, mul, divd, remd, div2, rem2, eqli, neqi, lssi,leqi, gtri, geqi, dupl, swap, andb, orb,load, stor, hhalt, wri, wrc, wrl, rdi, rdc, rdl, eol,ldc, ldla, ldl, ldg, stl, stg, move, copy, addc, mulc,jump, jumpz, call, adjs, sets, pexit}opcode;/*指令结构体*/typedef struct instr{opcode op;int a;}instr;/*词法类别*/typedef enum symbol{ident, number, sstring, plus, minus, star, lbrack, rbrack,colon, eql, neq, lss, leq, gtr, geq, lparen, rparen, comma, semicolon, period, becomes,beginsym, endsym, ifsym, thensym, elsesym, whilesym, dosym,casesym, repeatsym, untilsym, forsym, tosym, downtosym,notsym, divsym, modsym, andsym, orsym, constsym, varsym,typesym, arraysym, ofsym, recordsym, progsym, funcsym,procsym}symbol;/*变量类型*/typedef enum idkind{konst, varbl, field, tipe, funkt}idkind;/*类型的种类,简单的,数组,记录类型*/typedef enum tpkind{simple, arrays, records}tpkind;typedef char alfa[al+1];instr code[cxmax + 1];int m[amax + 1];/*词法分析相关全局变量*/char ch;int cc = 0, ll = 0;char line[129];symbol sym;alfa id;int num;char str[81];int slen;/*alfa word[norw + 1];*/int cx;int lev;int dx;BOOL labeled;int nl; /* as namelist[-1] */int namelist[lmax];int ix, tx; /* indices in tables *//* identifier table */typedef struct ITAB{alfa name;int link;int tip;idkind kind;union{int val; /*常量类型的值*/struct{int vlevel;int vadr;BOOL refpar;}; /*变量类型的属性*/int offset; /*域类型的偏移地址*/struct{int flevel;int fadr;int lastpar;int resultadr;BOOL inside;}; /*函数类型的属性*/};}ITAB;ITAB itab[imax + 1];/* type table */typedef struct TTAB{int size;tpkind kind;union{struct{int low;int high;int elemtip;}; /*数组类型的属性*/int fields; /*记录类型最后一个域的地址*/};}TTAB;TTAB ttab[tmax + 1];/*保留字*/static struct{alfa name;symbol lex;}word[] = {{ "", -1 },{ "begin", beginsym },{ "end", endsym },{ "if", ifsym },{ "then", thensym },{ "else", elsesym },{ "while", whilesym },{ "do", dosym },{ "case", casesym },{ "repeat", repeatsym },{ "until", untilsym },{ "for", forsym },{ "to", tosym },{ "downto", downtosym },{ "not", notsym },{ "div", divsym },{ "mod", modsym },{ "and", andsym },{ "or", orsym },{ "const", constsym },{ "var", varsym },{ "type", typesym },{ "array", arraysym },{ "of", ofsym },{ "record", recordsym },{ "program", progsym },{ "function", funcsym },{ "procedure", procsym }};FILE * source;BOOL eof_flag = FALSE;symbol search(){int i;for(i = norw; i >= 1; i--){if(strcmp(id, word[i].name) == 0)return word[i].lex;}return ident;}void error(int n){int i;for(i = 0; i < ll; i++)putchar(line[i]);for(i = 0; i <= cc - 1; i++)putchar(' ');printf("^/n");printf("error %d detected/n", n);exit(1);}void getch(){if (cc == ll){memset(line, 0, 129);if(feof(source)){fprintf(stderr, "program incomplete/n");exit(0);}ll = 0;cc = 0;while(!feof(source) && (ch = getc(source)) != '/n'){line[ll] = ch;ll++;}if(ch == '/n'){line[ll] = ch;ll++;}}ch = line[cc];cc++;}void getsym(){int k;int strend;while(ch == ' ' || ch == '/t' || ch == '/n')getch();if(isalpha(ch)){memset(id, 0, al+1);k = 0;do{if(k != al){id[k] = ch;k++;}getch();}while(isalnum(ch));sym = search();}else if(isdigit(ch)){num = 0;sym = number;do{num = 10 * num + (ch - '0');getch();}while(isdigit(ch));}else if(ch == ':'){getch();if(ch == '='){getch();sym = becomes;}elsesym = colon;}else if(ch == '>'){getch();if(ch == '='){getch();sym = geq;}elsesym = gtr;}else if(ch == '<'){getch();if(ch == '='){getch();sym = leq;}else if(ch == '>'){getch();sym = neq;}elsesym = lss;}else if(ch == '.'){getch();if(ch == '.'){getch();sym = colon;}elsesym = period;}else if(ch == '/''){slen = 0;strend = FALSE;sym = sstring;do{if(cc == ll)error(101);getch();if(ch == '/''){getch();if(ch == '/''){str[slen] = ch;slen++;}elsestrend = TRUE;}else{str[slen] = ch;slen++;}}while(strend == FALSE);if(slen == 0)error(102); /*不允许空字符串*/str[slen++] = '/0';}else if(ch == '+'){getch();sym = plus;}else if(ch == '-'){getch();sym = minus;}else if(ch == '*'){getch();sym = star;}else if(ch == '('){getch();sym = lparen;}else if(ch == ')'){getch();sym = rparen;}else if(ch == '['){getch();sym = lbrack;}else if(ch == ']'){getch();sym = rbrack;}else if(ch == '='){getch();sym = eql;}else if(ch == ','){getch();sym = comma;}else if(ch == ';'){getch();sym = semicolon;}else if(ch == '{'){do{getch();}while(ch != '}');getch();getsym();}elseerror(104);}void check(symbol s){if(sym != s)error(s);}void skip(symbol s){check(s);getsym();}/*将符号串登记入符号表*/void enter(alfa id, idkind k, int t){int j;if(ix == imax)error(104);else{ix++;strcpy(itab[0].name, id);if(lev == -1)j = nl;elsej = namelist[lev];while(strcmp(itab[j].name, id) != 0)j = itab[j].link;if(j != 0)error(105);else{strcpy(itab[ix].name, id);if(lev == -1)itab[ix].link = nl;elseitab[ix].link = namelist[lev];itab[ix].tip = t;itab[ix].kind = k;if(lev == -1)nl = ix;elsenamelist[lev] = ix;}}}/*在符号表中查找符号,返回位置*/int position(){int i , j;strcpy(itab[0].name, id);i = lev;do{if(i == -1)j = nl;elsej = namelist[i];while(strcmp(itab[j].name, id) != 0)j = itab[j].link;i = i - 1;}while(i >= -1 && j == 0);if(j == 0)error(106);return j;}void gen(instr i){switch(i.op){case dupl:case eol:case ldc:case ldla:case ldl:case ldg:dx = dx - 1;break;case add:case mul:case divd:case remd:case eqli:case neqi:case lssi:case leqi:case gtri:case geqi:case andb:case orb:case wrc:case rdi:case rdc:case stl:case stg:case jumpz:dx = dx + 1;break;case stor:case wri:case move:dx = dx + 2;break;case copy:dx = dx - i.a + 1;break;case adjs:dx = dx + i.a;break;}if(!(((i.op == addc || i.op == adjs) && (i.a == 0)) || ((i.op == mulc) && (i.a == 1)))){if(labeled){code[cx] = i;cx = cx +1;labeled = FALSE;}else if(code[cx - 1].op == ldc && i.op == add){code[cx - 1].op = addc;}else if(code[cx - 1].op == ldc && i.op == mul){code[cx - 1].op = mulc;}else if(code[cx - 1].op == ldc && i.op == neg){code[cx - 1].a = -code[cx - 1].a;}else if(code[cx - 1].op == ldc && code[cx - 1].a == 2 && i.op == divd){code[cx - 1].op = div2;}else if(code[cx - 1].op == ldc && code[cx - 1].a == 2 && i.op == remd){code[cx - 1].op = rem2;}else if(code[cx - 1].op == ldc && i.op == stor){code[cx - 1].op = stg;}else if(code[cx - 1].op == ldc && i.op == load){code[cx - 1].op = ldg;}else if(code[cx - 1].op == ldla && i.op == stor){code[cx - 1].op = stl;}else if(code[cx - 1].op == ldla && i.op == load){code[cx - 1].op = ldl;}else{code[cx] = i;cx = cx + 1;}}}void gen0(opcode op){instr i;i.op = op;gen(i);}void gen1(opcode op, int a){instr i;i.op = op;i.a = a;gen(i);}int codelabel(){labeled = TRUE;return cx;}void address(int lv, int ad){if(lv == 0)gen1(ldc, ad);else if(lv == lev)gen1(ldla, ad - dx);else{gen1(ldl, -dx);while(lv + 1 != lev){gen0(load);lv = lv + 1;}gen1(addc, ad);}}void addressvar(int ref){address(itab[ref].vlevel, itab[ref].vadr);if(itab[ref].refpar)gen0(load);}void mustbe(int x, int y){if(x != y){if((ttab[x].kind == arrays) && (ttab[y].kind == arrays) && (ttab[x].low == ttab[y].low) && (ttab[x].high == ttab[y].high))mustbe(ttab[x].elemtip, ttab[y].elemtip);elseerror(107);/*类型不匹配*/}}void expression(int * x);void selector(int * t, int * ref){int j, x;*t = itab[*ref].tip;getsym();if(sym == period ||sym == lbrack){addressvar(*ref);*ref = 0;while(sym == period || sym == lbrack){switch(sym){case period:if(ttab[*t].kind != records)error(108);else{getsym();check(ident);j = ttab[*t].fields;strcpy(itab[0].name, id);while(strcmp(itab[0].name, id) != 0)j = itab[j].link;if(j == 0)error(109);else{gen1(addc, itab[j].offset);*t = itab[j].tip;getsym();}}break;case lbrack:do{if(ttab[*t].kind != arrays)error(110);else{getsym();expression(&x);mustbe(intip, x);gen1(addc, -(ttab[*t].low));*t = ttab[*t].elemtip;gen1(mulc, ttab[*t].size);gen0(add);}}while(sym == comma);skip(rbrack);break;}}}}void varpar(int * t){int j;check(ident);j = position();selector(t, &j);if(j != 0)addressvar(j);}/*标准函数*/void standfct(int n){int x, l;switch(n){case fabs:skip(lparen);expression(&x);mustbe(intip, x);gen0(dupl);gen1(ldc, 0);gen0(lssi);l = codelabel();gen1(jumpz, 0);gen0(neg);code[l].a = codelabel();skip(rparen);break;case fsqr:skip(lparen);expression(&x);mustbe(intip, x);gen0(dupl);gen0(mul);skip(rparen);break;case fodd:skip(lparen);expression(&x);mustbe(intip, x);gen0(rem2);skip(rparen);break;case fchr:skip(lparen);expression(&x);mustbe(intip, x);skip(rparen);break;case ford:skip(lparen);expression(&x);mustbe(chartip, x);skip(rparen);break;case fwrite:case fwriteln:if(n == fwrite)check(lparen);if(sym == lparen){do{getsym();if(sym == sstring){for(x = 0; x < slen; x++){gen1(ldc, str[x]);gen0(wrc);}getsym();}else{expression(&x);if(sym == colon){mustbe(intip, x);getsym();expression(&x);mustbe(intip, x);gen0(wri);}else if(x == intip){gen1(ldc, 8);gen0(wri);}else if(x == chartip){gen0(wrc);}elseerror(111);}}while(sym == comma);skip(rparen);}if(n == fwriteln)gen0(wrl);break;case fread:case freadln:if(n == fread)check(lparen);if(sym == lparen){do{getsym();varpar(&x);if(x == intip)gen0(rdi);else if(x == chartip)gen0(rdc);elseerror(112);}while(sym == comma);skip(rparen);}if(n == freadln)gen0(rdl);break;case feoln:gen0(eol);break;}}/*函数,过程调用*/void funcall(int i){int d, p, x;getsym();if(itab[i].flevel < 0)standfct(itab[i].fadr);else{if(itab[i].tip != 0)gen1(ldc, 0);p = i;d = dx;if(sym == lparen){do{getsym();if(p == itab[i].lastpar)error(113);else{p = p + 1;if(itab[p].refpar == TRUE)varpar(&x);else{expression(&x);if(ttab[x].kind != simple)gen1(copy, ttab[x].size);}}mustbe(itab[p].tip, x);}while(sym == comma);skip(rparen);}if(p != itab[i].lastpar)error(114);if(itab[i].flevel != 0)address(itab[i].flevel, 0);gen1(call, itab[i].fadr);dx = d;}}/*因子*/void factor(int * t){int i;if(sym == ident){i = position();*t = itab[i].tip;switch(itab[i].kind){case konst:getsym();gen1(ldc, itab[i].val);break;case varbl:selector(t, &i);if(i != 0)addressvar(i);if(ttab[i].kind == simple)gen0(load);break;case funkt:if(*t == 0)error(115);elsefuncall(i);break;case tipe:error(116); /*类型名不能作为因子*/break;}}else if(sym == number){gen1(ldc, num);*t = intip;getsym();}else if(sym == sstring && slen == 2){gen1(ldc, str[0]);*t = chartip;getsym();}else if(sym == lparen){getsym();expression(t);skip(rparen);}else if(sym == notsym){getsym();factor(t);mustbe(booltip, *t);gen0(neg);gen1(addc, 1);}elseerror(117);}/*表达式的项*/void term(int * x){int y;factor(x);while(sym == andsym || sym == star || sym == divsym || sym == modsym){if(sym == andsym)mustbe(booltip, *x);elsemustbe(intip, *x);switch(sym){case star:getsym();factor(&y);gen0(mul);break;case divsym:getsym();factor(&y);gen0(divd);break;case modsym:getsym();factor(&y);gen0(remd);break;case andsym:getsym();factor(&y);gen0(andb);break;}mustbe(*x, y);}}/*简单表达式*/void simpleexpression(int * x){int y;if(sym == plus){getsym();term(x);mustbe(intip, *x);}else if(sym == minus){getsym();term(x);mustbe(intip, *x);gen0(neg);}elseterm(x);while(sym == orsym || sym == plus || sym == minus){if(sym == orsym)mustbe(booltip, *x);elsemustbe(intip, *x);switch(sym){case plus:getsym();term(&y);gen0(add);break;case minus:getsym();term(&y);gen0(neg);gen0(add);break;case orsym:getsym();term(&y);gen0(orb);break;}mustbe(*x, y);}}/*表达式*/void expression(int * x){symbol op;int y;simpleexpression(x);if(sym == eql ||sym == neq || sym == lss || sym == leq || sym == gtr ||sym == geq){if(ttab[*x].kind != simple)error(118);else{op = sym;getsym();simpleexpression(&y);mustbe(*x, y);switch(op){case eql:gen0(eqli);break;case neq:gen0(neqi);break;case lss:gen0(lssi);break;case leq:gen0(leqi);break;case gtr:gen0(gtri);break;case geq:gen0(geqi);break;}*x = booltip;}}}/*语句*/void statement(){int i, j, t, x;if(sym == ident){i = position();switch(itab[i].kind){case varbl:selector(&t, &i);skip(becomes);expression(&x);mustbe(t, x);if(i == 0)gen0(swap);elseaddressvar(i);if(ttab[i].kind == simple)gen0(stor);elsegen1(move, ttab[i].size);break;case funkt:if(itab[i].tip == 0)funcall(i);else{if(itab[i].inside == FALSE)error(119);/*此处不能对函数赋值*/else{getsym();skip(becomes);expression(&x);mustbe(itab[i].tip, x);address(itab[i].flevel + 1, itab[i].resultadr);gen0(stor);}}break;case konst:case field:case tipe:error(120); /*变量不能用在此处*/break;}}else if(sym == ifsym){getsym();expression(&t);mustbe(booltip, t);skip(thensym);i = codelabel();gen1(jumpz, 0);statement();if(sym == elsesym){getsym();j = codelabel();gen1(jump, 0);code[i].a = codelabel();i = j;statement();}code[i].a = codelabel();}else if(sym == whilesym){getsym();i = codelabel();expression(&t);mustbe(booltip, t);skip(dosym);j = codelabel();gen1(jumpz, 0);statement();gen1(jump, i);/*这里表写错了*/code[j].a = codelabel();}else if(sym == repeatsym){i = codelabel();do{getsym();statement();}while(sym == semicolon);skip(untilsym);expression(&t);mustbe(booltip, t);gen1(jumpz, i);}else if(sym == beginsym){do{getsym();statement();}while(sym == semicolon);skip(endsym);}}void block(int l);/*常量*/void constant(int * c, int * t){int i, s;if(sym == sstring && slen == 2){*c = str[0];*t = chartip;}else{if(sym == plus){getsym();s = +1;}else if(sym == minus){getsym();s = -1;}elses = 0;if(sym == ident){i = position();if(itab[i].kind != konst)error(121);else{*c = itab[i].val;*t = itab[i].tip;}}else if(sym == number){*c = num;*t = intip;}elseerror(122);if(s != 0){mustbe(*t, intip);(*c) = (*c) * (s);}}getsym();}/*常量声明*/void constdeclaration(){alfa a;int t, c;strcpy(a, id);getsym();skip(eql);constant(&c, &t);skip(semicolon);enter(a, konst, t);itab[ix].val = c;}void typ(int * t);/*数组类型*/void arraytyp(int * t){int x;ttab[*t].kind = arrays;getsym();constant(&(ttab[*t].low), &x);mustbe(intip, x);skip(colon);constant(&(ttab[*t].high), &x);mustbe(intip, x);if(ttab[*t].low > ttab[*t].high)error(123); /*数组边界问题*/if(sym == comma)arraytyp(&(ttab[*t].elemtip));else{skip(rbrack);skip(ofsym);typ(&(ttab[*t].elemtip));}ttab[*t].size = (ttab[*t].high - ttab[*t].low + 1) * ttab[ttab[*t].elemtip].size;}/*类型定义*/void typ(int * t){int i, j, sz, ft;if(sym == ident){i = position();if(itab[i].kind != tipe)error(124); /*这个标识符不是类型能够*/else{*t = itab[i].tip;getsym();}}else{if(tx == tmax){error(125); /*溢出,应退出*/}else{tx = tx + 1;*t = tx;}if(sym == arraysym){getsym();check(lbrack);arraytyp(t);}else{skip(recordsym);if(lev == lmax){error(126); /*深度超过限度,应退出*/}else{lev = lev + 1;if(lev == -1)nl = 0;elsenamelist[lev] = 0;check(ident);sz = 0;do{enter(id, field, 0);i = ix;getsym();while(sym == comma){getsym();check(ident);enter(id, field, 0);getsym();}j = ix;skip(colon);typ(&ft);do{itab[i].tip = ft;itab[i].offset = sz;sz = sz + ttab[ft].size;i = i + 1;}while(i <= j);if(sym == semicolon)getsym();elsecheck(endsym);}while(sym == ident);ttab[*t].size = sz;ttab[*t].kind = records;if(lev == -1)ttab[*t].fields = nl;elsettab[*t].fields = namelist[lev];lev = lev - 1;skip(endsym);}}}}/*类型声明,type保留字处*/void typedeclaration(){alfa a;int t;strcpy(a, id);getsym();skip(eql);typ(&t);skip(semicolon);enter(a, tipe, t);}/*变量声明*/void vardeclaration(){int p, q, t;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();}elser = 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;elsenamelist[lev] = 0;ps = 1;odx = dx;if(sym == lparen){do{getsym();paramlist(&p, &ps);}while(sym == semicolon);skip(rparen);}if(lev > 1)dx = -1;elsedx = 0;itab[f].resultadr = ps;p = f;while(p < ix){p = p + 1;if(itab[p].refpar)ps = ps - 1;elseps = 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);elsefuncdeclaration(FALSE);}if(l + 1 == codelabel())cx = cx -1;elsecode[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);}elsestrcpy(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);}elsefprintf(stdout, "open file error, code not saved./n");}}