#include"C0.h"
#define stacksize 500
void error(int n)
{
char space[81];
memset(space, 32, 81);
std::cout << "-------" << ch << std::endl;
space[cc - 1] = 0;//出错时当前符号已经读完,所以cc-1
std::cout << "****" << space << "!" << n << std::endl;
err++;
}
int getsym()
{
int i, j, k;
while (ch == 32 || ch == 10 || ch == 9)
{
getchdo;
}
if (ch >= 'a'&&ch <= 'z')
{
k = 0;
do {
if (k < al)
{
a[k] = ch;
k++;
}
getchdo;
} while (ch >= 'a'&&ch <= 'z' || ch >= '0'&&ch <= '9');
a[k] = 0;
strcpy(id, a);
i = 0;
j = norw;
do {
k = (i + j) / 2;
if (strcmp(id, word[k]) <= 0)
{
j = k - 1;
}
if (strcmp(id, word[k]) >= 0)
{
i = k + 1;
}
} while (i <= j);
if (i - 1 > j)
{
sym = wsym[k];
}
else
{
sym = ident;
}
}
else
{
if (ch >= '0'&&ch <= '9')
{
k = 0;
num = 0;
sym = number;
do {
num = 10 * num + ch - '0';
k++;
getchdo;
} while (ch >= '0'&&ch <= '9'); /*获取数字的值*/
k--;
if (k > nmax)
{
//error(30);
}
}
else
{
sym = ssym[ch];/* 当符号不满足上述条件时,全部按照单字符号处理*/
getchdo;
}
}
return 0;
}
int getch()
{
if (cc == ll)
{
if (fin.eof()) //如果文件结束,则返回非0值,否则返回0,文件结束符只能被clearerr()清除。
{
//std::cout << "程序未完成" << std::endl;
return -1;
}
ll = 0;
cc = 0;
std::cout << cx << " ";
fa1 << cx << " ";
ch = ' ';
std::getline(fin, line);
std::cout << line << std::endl;
fa1 << line << "\n";
ll = line.length();
}
ch = line[cc];
cc++;
return 0;
}
void init()
{
int i;
for (i = 0; i <= 255; i++)
{
ssym[i] = nul;
}
ssym['+'] = plus;
ssym['-'] = minus;
ssym['*'] = times;
ssym['/'] = slash;
ssym['='] = becomes;
ssym['('] = lparen;
ssym[')'] = rparen;
ssym['{'] = lbrace;
ssym['}'] = rbrace;
ssym[','] = comma;
ssym[';'] = semicolon;
/*设置保留字名字,按照字母顺序,便于折半查找*/
strcpy(word[0], "else");
strcpy(word[1], "if");
strcpy(word[2], "int");
strcpy(word[3], "printf");
strcpy(word[4], "return");
strcpy(word[5], "scanf");
strcpy(word[6], "void");
strcpy(word[7], "while");
/*设置保留字符号*/
wsym[0] = elsesym;
wsym[1] = ifsym;
wsym[2] = intsym;
wsym[3] = printfsym;
wsym[4] = returnsym;
wsym[5] = scanfsym;
wsym[6] = voidsym;
wsym[7] = whilesym;
///*设置指令名称*/
mnemonic[lit] = "lit";
mnemonic[lod] = "lod";
mnemonic[sto] = "sto";
mnemonic[cal] = "cal";
mnemonic[inte] = "int";
mnemonic[jmp] = "jmp";
mnemonic[jpc] = "jpc";
mnemonic[red] = "red";
mnemonic[add] = "add";
mnemonic[sub] = "sub";
mnemonic[mul] = "mul";
mnemonic[div1] = "div";
mnemonic[wrt] = "wrt";
mnemonic[ret] = "ret";
///*设置符号集*/
for (i = 0; i < symnum; i++)
{
declbegsys[i] = false;
statbegsys[i] = false;
facbegsys[i] = false;
}
/*设置声明开始符号集*/
declbegsys[voidsym] = true;
declbegsys[intsym] = true;
declbegsys[lbrace] = true;
/*设置语句开始符号集*/
statbegsys[ifsym] = true;
statbegsys[whilesym] = true;
statbegsys[voidsym] = true;
statbegsys[intsym] = true;
statbegsys[scanfsym] = true;
statbegsys[printfsym] = true;
/*设置因子开始符号集*/
facbegsys[ident] = true;
facbegsys[number] = true;
facbegsys[lparen] = true;
//brace处理辅助变量
braceflag = 0;
}
int gen(fct x, int y, int z)
{
if (cx >= cxmax)
{
printf("程序过长"); /*程序过长*/
return -1;
}
code[cx].f = x;
code[cx].l = y;
code[cx].a = z;
cx++;
return 0;
}
int test(bool * s1, bool * s2, int n)
{
if (!inset(sym, s1))
{
//error(n);
/*当检测不通过时,不停获取符号,直到它属于需要的集合或补救的集合*/
while ((!inset(sym, s1)) && (!inset(sym, s2)))
{
getsymdo;
}
}
return 0;
}
int inset(int e, bool * s)
{
return s[e];
}
int addset(bool* sr, bool* s1, bool* s2, int n)
{
int i;
for (i = 0; i < n; i++)
{
sr[i] = s1[i] || s2[i];
}
return 0;
}
int block2(int lev, int tx, bool * fsys)
{
int i;
int dx; /*名字分配到的相对地址*/
int tx0; /*保留初始tx*/
int cx0; /*保留初始cx*/
bool nxtlev[symnum]; /*在下级函数的参数中,符号集合均为值参,但由于使用数组
实现,传递进来的是指针,为防止下级函数改变上级函数的
集合,开辟新的空间传递给下级函数*/
dx = 3;
tx0 = tx; /*记录本层名字的初始位置*/
table[tx].adr = cx;
gendo(jmp, 0, 0);
if (lev > levmax)
{
error(32);
}
do {
if (sym == intsym)/*收到变量声名符号,开始处理变量声名*/
{
getsymdo;
intdeclarationdo(&tx, lev, &dx);
while (sym == comma)
{
getsymdo;
intdeclarationdo(&tx, lev, &dx);
}
if (sym == semicolon)
{
getsymdo;
}
else
{
error(5);
}
}
} while (inset(sym, declbegsys)); /*直到没有声明符号*/
code[table[tx0].adr].a = cx; /*开始生成当前过程代码*/
table[tx0].adr = cx; /*当前过程代码地址*/
table[tx0].size = dx; /*声明部分中每增加一条声明都会给dx增加1,声明部分已经结束,dx就是当前过程数据的size*/
cx0 = cx;
gendo(inte, 0, dx); /*生成分配内存代码*/
if (tableswitch) /*输出名字表*/
{
std::cout << "TABLE:\n";
if (tx0 + 1 > tx)
{
std::cout << "NULL\n";
}
for (i = tx0 + 1; i <= tx; i++)
{
switch (table[i].kind)
{
case integer:
std::cout << i << " int " << table[i].name << " ";
std::cout << "lev=" << table[i].level << " adr=" << table[i].adr << std::endl;
/*fprintf(fas, "%d var %s", i, table[i].name);
fprintf(fas, "lev=%d addr=%d\n", table[i].level, table[i].adr);*/
break;
case intfun:
std::cout << i << " intfun " << table[i].name << " ";
std::cout << "lev=" << table[i].level << " adr=" << table[i].adr << " size=" << table[i].size << std::endl;
/* fprintf(fas, "%d proc%s", i, table[i].name);
fprintf(fas, "lev=%d adr=%d size=%d \n", table[i].level, table[i].adr, table[i].size);*/
break;
case voidfun:
std::cout << i << " voidfun " << table[i].name << " ";
std::cout << "lev=" << table[i].level << " adr=" << table[i].adr << " size=" << table[i].size << std::endl;
/* fprintf(fas, "%d proc%s", i, table[i].name);
fprintf(fas, "lev=%d adr=%d size=%d \n", table[i].level, table[i].adr, table[i].size);*/
break;
}
}
std::cout << " ";
}
//memcpy(nxtlev, fsys, sizeof(bool)*symnum);/*每个后跟符号集和都包含上层后跟符号集和,以便补救*/
//nxtlev[semicolon] = true;
//nxtlev[endsym] = true;
do{
statementdo(nxtlev, &tx, lev);
if (sym == semicolon) getsymdo;
} while (sym == ident || sym == ifsym || sym == whilesym || sym == scanfsym || sym == printfsym||sym == returnsym);
gendo(ret, 0, 0); /*每个过程出口都要使用的释放数据段命令*/
//memset(nxtlev, 0, sizeof(bool)*symnum); /*分程序没有补救集合*/
//test(fsys, nxtlev, 8); /*检测后跟符号正确性*/
listcode(cx0); /*输出代码*/
return 0;
}
int block(int lev, int tx, bool * fsys)
{
int i;
int dx; /*名字分配到的相对地址*/
int tx0; /*保留初始tx*/
int cx0; /*保留初始cx*/
bool nxtlev[symnum]; /*在下级函数的参数中,符号集合均为值参,但由于使用数组
实现,传递进来的是指针,为防止下级函数改变上级函数的
集合,开辟新的空间传递给下级函数*/
dx = 4;
tx0 = tx; /*记录本层名字的初始位置*/
table[tx].adr = cx;
gendo(jmp, 0, 0);
if (lev > levmax)
{
error(32);
}
do
{
if (sym == intsym)
{
getsymdo;
if (sym == ident)
{
getsymdo;
}
else
{
error(1);//"缺ident");
}
if (sym == lparen
C0语言编译器
需积分: 9 103 浏览量
2018-05-19
15:44:37
上传
评论 1
收藏 2.79MB ZIP 举报
港胖子
- 粉丝: 5
- 资源: 5