?? compile.cpp
字號:
#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
#define realtip 4
/*指令碼*/
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, inc, dec
}opcode;
/*指令結構體*/
typedef struct instr{
opcode op;
int a;
}instr;
/*詞法類別*/
typedef enum symbol{pl0=-1,
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, funcsym,procsym,cstring
}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;
char string[imax];
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[] = {
{" ", pl0},
{"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 },
{ "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(ch=='\"')
{
k=0;
do{
getch();
string[k]=ch;
k++;
}while(ch!='\"');
sym=cstring;
}
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);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -