这是我编译原理课程的课程设计时写的,对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 #endif typedef 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; } else sym = colon; } else if(ch == '>') { getch(); if(ch == '=') { getch(); sym = geq; } else sym = gtr; } else if(ch == '<') { getch(); if(ch == '=') { getch(); sym = leq; } else if(ch == '>') { getch(); sym = neq; } else sym = lss; } else if(ch == '.') { getch(); if(ch == '.') { getch(); sym = colon; } else sym = 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++; } else strend = 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(); } else error(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; else j = 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; else itab[ix].link = namelist[lev]; itab[ix].tip = t; itab[ix].kind = k; if(lev == -1) nl = ix; else namelist[lev] = ix; } } } /*在符号表中查找符号,返回位置*/ int position() { int i , j; strcpy(itab[0].name, id); i = lev; do{ if(i == -1) j = nl; else j = 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); else error(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); } else error(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); else error(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); else funcall(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); } else error(117); } /*表达式的项*/ void term(int * x) { int y; factor(x); while(sym == andsym || sym == star || sym == divsym || sym == modsym) { if(sym == andsym) mustbe(booltip, *x); else mustbe(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); } else term(x); while(sym == orsym || sym == plus || sym == minus) { if(sym == orsym) mustbe(booltip, *x); else mustbe(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); else addressvar(i); if(ttab[i].kind == simple) gen0(stor); else gen1(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; } else s = 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; } else error(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; else namelist[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(); else check(endsym); }while(sym == ident); ttab[*t].size = sz; ttab[*t].kind = records; if(lev == -1) ttab[*t].fields = nl; else ttab[*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(); } 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"); } }