PL0文法编译器C语言源代码

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。












这是我编译原理课程的课程设计时写的,对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;
&


nbsp;
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;
ca

se 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)
{
&nb


sp; 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:
&n


bsp; 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);
s

kip(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;
&nb


sp;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");
}

}





相关文档
最新文档