📄 plxcompiler.cpp
字号:
#include "stdafx.h"
#include "plxCompiler.h"
/* 初始化初始值 */
const plus = 0; /* + */
const minus = 1; /* - */
const times = 2; /* * */
const slash = 3; /* / */
const lparen = 4; /* ( */
const rparen = 5; /* ) */
const eql = 6; /* = */
const comma = 7; /* , */
const semicolon = 8; /* ; */
const period = 9; /* . */
const lss = 10; /* < */
const gtr = 11; /* > */
const ident = 12; /* */
const number = 14; /* */
const becomes = 15; /* := */
const geq = 16; /* >= */
const leq = 17; /* <= */
const neql = 18; /* /= */
const odd = 19; /* % */
const ledge = 101; /* [ */
const redge = 102; /* ] */
const progsym = 20;
const intesym = 21;
const logisym = 22;
const constsym = 23;
const ifsym = 24;
const thensym = 25;
const elsesym = 26;
const whilesym = 27;
const repeasym = 28;
const beginsym = 29;
const endsym = 30;
const orsym = 31;
const andsym = 32;
const notsym = 33;
const truesym = 34;
const falsesym = 35;
const dosym = 36;
const untilsym = 37;
const writesym = 38;
const procsym = 39;
const callsym = 40;
const term = 41; /* 结束 */
const commentsym= 100;
plxCompiler::plxCompiler()
{
cc = 0;
ll = 0;
tx = 0; /* 用0专门来做查询 */
cx = 0;
dx = 0;
lev= 0;
errornum = 0;
lineIndex = 0;
codeIndex = 0;
breakpoint = 0;
strcpy(word[0] ,"program");
strcpy(word[1] ,"integer");
strcpy(word[2] ,"logical");
strcpy(word[3] ,"const");
strcpy(word[4] ,"if");
strcpy(word[5] ,"then");
strcpy(word[6] ,"else");
strcpy(word[7] ,"while");
strcpy(word[8] ,"repeat");
strcpy(word[9] ,"begin");
strcpy(word[10] ,"end");
strcpy(word[11] ,"or");
strcpy(word[12] ,"and");
strcpy(word[13] ,"not");
strcpy(word[14] ,"true");
strcpy(word[15] ,"false");
strcpy(word[16] ,"do");
strcpy(word[17] ,"until");
strcpy(word[18] ,"write");
strcpy(word[19] ,"procedure");
strcpy(word[20] ,"call");
wsym[0] = progsym;
wsym[1] = intesym;
wsym[2] = logisym;
wsym[3] = constsym;
wsym[4] = ifsym;
wsym[5] = thensym;
wsym[6] = elsesym;
wsym[7] = whilesym;
wsym[8] = repeasym;
wsym[9] = beginsym;
wsym[10] = endsym;
wsym[11] = orsym;
wsym[12] = andsym;
wsym[13] = notsym;
wsym[14] = truesym;
wsym[15] = falsesym;
wsym[16] = dosym;
wsym[17] = untilsym;
wsym[18] = writesym;
wsym[19] = procsym;
wsym[20] = callsym;
for(int i=0;i<MAX_ANSICNUMBER;i++)
ssym[i] = -1;
ssym['+'] = plus;
ssym['-'] = minus;
ssym['%'] = odd;
ssym['*'] = times;
ssym['/'] = slash;
ssym['('] = lparen;
ssym[')'] = rparen;
ssym['='] = eql;
ssym[','] = comma;
ssym[';'] = semicolon;
ssym['.'] = period;
ssym['<'] = lss;
ssym['>'] = gtr;
ssym['$'] = term;
ssym['['] = ledge;
ssym[']'] = redge;
pOutputView = NULL;
pDebugView = NULL;
pCodeView = NULL;
/********* 每一种可能出错的地方的follow ******************/
/* program的follow */
non_finis[0].num = 7;
non_finis[0].followSym[0] = intesym;
non_finis[0].followSym[1] = logisym;
non_finis[0].followSym[2] = semicolon;
non_finis[0].followSym[3] = constsym;
non_finis[0].followSym[4] = procsym;
non_finis[0].followSym[5] = term;
non_finis[0].followSym[6] = beginsym;
/* ds的follow */
non_finis[1].num = 4;
non_finis[1].followSym[0] = procsym;
non_finis[1].followSym[1] = term;
non_finis[1].followSym[2] = beginsym;
non_finis[1].followSym[3] = semicolon;
/* begin 和 ss 的follow */
non_finis[2].num = 8;
non_finis[2].followSym[0] = ident;
non_finis[2].followSym[1] = term;
non_finis[2].followSym[2] = ifsym;
non_finis[2].followSym[3] = whilesym;
non_finis[2].followSym[4] = repeasym;
non_finis[2].followSym[5] = writesym;
non_finis[2].followSym[6] = endsym;
non_finis[2].followSym[7] = semicolon;
/* ss的first */
non_finis[3].num = 5;
non_finis[3].followSym[0] = ident;
non_finis[3].followSym[1] = ifsym;
non_finis[3].followSym[2] = whilesym;
non_finis[3].followSym[3] = repeasym;
non_finis[3].followSym[4] = writesym;
/* af 的first */
non_finis[4].num = 4;
non_finis[4].followSym[0] = ident;
non_finis[4].followSym[1] = lparen;
non_finis[4].followSym[2] = constsym;
non_finis[4].followSym[3] = number;
}
plxCompiler::~plxCompiler()
{
}
/* 字符获取函数 */
void plxCompiler::getch()
{
if( cc != ll)
{
ch = line[cc++];
return;
}else
{
if(InFile.eof())
{
ch = '$';
return;
}
}
cc = ll =0;
lineIndex++;
InFile.getline(line,MAX_LINECHAR);
ll = strlen(line);
line[ll++] = ' ';
ch = line[cc++];
}
/* 词法获取函数 */
void plxCompiler::getsym()
{
while(ch == ' ') getch();
/* 字符串识别 */
if(ch<='z'&&ch>='a')
{
int i=0;
do{
if(i < MAX_INDENTFIERLEN-1)
{
a[i++] = ch;
}else
{
break;
}
getch();
}
while((ch<='z'&&ch>='a')||(ch<='9'&&ch>='0'));
a[i] = '\0';
strcpy(id,a);
sym = ident;
for(i=0;i<MAX_KEYWORD;i++)
{
if(strcmp(id,word[i]) == 0)
{
sym = wsym[i];
}
}
}else
{
/* 数字识别 */
if(ch <= '9' && ch >= '0')
{
int i=0;
num = 0;
do{
i++;
num = 10*num + ((int)ch - '0');
getch();
}
while(ch <= '9' && ch >= '0');
if(i>MAX_NUMBERSIZE)
{
error("数字位数过长!");
}
sym = number;
}else
{
/* 赋值号识别 */
if(ch == ':')
{
getch();
if(ch == '=')
{
getch();
sym = becomes;
}
else
{
error("赋值符号缺少 '=' 符号!");
}
}
else{
/* 小于号识别 */
if(ch == '<')
{
getch();
if(ch == '=')
{
sym = leq;
getch();
}
else
{
sym = lss;
}
}else
{
/* 大于号识别 */
if(ch == '>')
{
getch();
if(ch == '=')
{
getch();
sym = geq;
}else
{
sym = gtr;
}
}else
{
if(ch == '/')
{
getch();
/* C++注释处理 */
if(ch == '/')
{
getch();
cc = ll;
sym = commentsym;
getch();
getsym();
return;
}else
{
/* C注释处理 */
if(ch == '*')
{
getch();
while(true)
{
while(ch != '*')
{
getch();
if(ch == '$')
{
sym = term;
error("缺少注释边界!");
return;
}
}
getch();
if(ch == '/')
{
getch();
sym = commentsym;
getsym();
break;
}
}
}
/* 不等于处理 */
else
{
if(ch == '=')
{
getch();
sym = neql;
}else
{
sym = slash;
}
}
}
}else
{
if(ch > 0)
{
sym = ssym[ch];
//去除中文码问题
if(sym == -1)
{
error("%s 使用不合法标识符",ch);
}
getch();
}else
{
error("unknown character '%x'",ch);
getch();
}
}
}
}
}
}
}
}
/* 语法分析 */
void plxCompiler::enter(_kind indent, int value)
{
ASSERT_VALID(pVariableView);
if(position(id) != 0 )
{
error("%s redefine.",id);
}else
{
tx++;
strcpy(table[tx].name , id);
table[tx].kind = indent;
switch(indent)
{
case varConst : table[tx].val = num;
table[tx].ldex = pVariableView->AddText(table[tx].name,num);
break;
case varInteger: table[tx].adr = dx;
table[tx].level = lev;
table[tx].ldex = pVariableView->AddText(table[tx].name,0);
dx++;
break;
case varLogical: table[tx].adr = dx;
table[tx].level = lev;
table[tx].ldex = pVariableView->AddText(table[tx].name,0);
dx++;
break;
case varProc : table[tx].level = lev; break;
}
}
}
/* 寻找标识符-为0表示失败 */
int plxCompiler::position(char *ident)
{
strcpy(table[0].name,ident);
int i = tx;
while(strcmp(table[i].name,ident) != 0) i--;
return i;
}
/* 存储变量或者过程 */
void plxCompiler::vardeclaration(_kind varkind)
{
if(sym == ident)
{
enter(varkind);
getsym();
if(sym == ledge)
{
getsym();
if(sym == number)
{
expandArray(num);
getsym();
if(sym == redge)
{
getsym();
}else
{
error("缺少]");
}
}else
{
error("缺少数字");
}
}
}else
{
error("unidentifiable definition.");
}
}
/* 开辟数组当然是比实际的要小一个,因为变量本身也是一个 */
void plxCompiler::expandArray(int len)
{
dx += len - 1;
}
/* 常量定义函数 */
void plxCompiler::constdeclaration()
{
if(sym == ident)
{
getsym();
if(sym == eql )
{
getsym();
if(sym == number)
{
enter(varConst,num);
getsym();
}
}else
{
if(sym == becomes)
{
getsym();
error("常量定义使用赋值号!");
}else
{
error("常量定义错误!");
}
}
}else
{
error("常量定义错误!");
}
}
/* 主程序入口 */
void plxCompiler::Prog()
{
if(sym == progsym)
{
getsym();
}else
{
error("源文件缺少'program'入口.");
text(0);
}
block();
if(sym == period)
{
getsym();
}else
{
error("程序缺少结束符号!");
}
}
/* block 非终结函数 */
void plxCompiler::block()
{
dx = 3;
int tx0 = tx;
/* 让每个table的入口 */
table[tx0].adr = cx;
gen(JMP,0,0);
ds();
while(sym == procsym)
{
getsym();
if(sym == ident)
{
enter(varProc);
getsym();
if(sym == semicolon)
{
getsym();
/* 保存当前层次和dx针 */
int oldlev = lev;
int olddx = dx;
lev ++;
block();
/* 恢复层次和数据针 */
lev = oldlev;
dx = olddx;
if(sym == semicolon)
{
getsym();
}else
{
error("过程定义缺少结束分号!");
}
}else
{
error("过程定义缺少开始分号!");
}
}else
{
error("不可识别的过程定义标识符!");
}
}
code[table[tx0].adr].a = cx; /* 回填,确定函数起始位置 */
table[tx0].adr = cx;
gen(INT,0,dx);
if(sym == beginsym)
{
getsym();
}else
{
error("程序语句缺少'begin'关键字.");
text(2);
}
Satement();
if(sym == endsym)
{
getsym();
gen(OPR,0,0);
}else
{
error("程序缺少'end'关键字.");
}
}
/* 主体语句 */
void plxCompiler::Satement()
{
ss();
while(sym == semicolon || textIn(3))
{
if(sym == semicolon)
{
getsym();
}else
{
error("语句缺少';'号.");
}
ss();
}
}
/* 定义变量的过程 */
void plxCompiler::ds()
{
d();
while(sym == semicolon)
{
getsym();
d();
}
}
/* 定义变量过程 */
void plxCompiler::d()
{
if(sym == intesym)
{
getsym();
ddInt();
}else
{
if(sym == logisym)
{
getsym();
ddBool();
}else
{
if(sym == constsym)
{
getsym();
ddConst();
}else
{
}
}
}
}
/* did not finish the code which will realise the array. */
void plxCompiler::ddInt()
{
vardeclaration(varInteger);
while(sym == comma)
{
getsym();
ddInt();
}
}
void plxCompiler::ddBool()
{
vardeclaration(varLogical);
while(sym == comma)
{
getsym();
ddBool();
}
}
void plxCompiler::ddConst()
{
constdeclaration();
while(sym == comma)
{
getsym();
constdeclaration();
}
}
void plxCompiler::offset()
{
if(sym == ledge)
{
getsym();
ae();
if(sym == redge)
{
getsym();
}else
{
error("缺少右边界]!");
}
}else
{
gen(LIT,1,0);
}
}
/* 语句过程 */
void plxCompiler::ss()
{
if(sym == ident)
{
int index = position(id);
if(index == 0)
{
error("'%s' 不可识别的标识符!",id);
getsym();
text(2);
}else
{
int kind = table[index].kind;
if(kind == varInteger)
{
getsym();
offset();
if(sym == becomes || sym == eql)
{
if(sym == eql)
{
error("赋值语句不能使用 '=' 标识符!");
}
getsym();
ae();
gen(STO,lev-table[index].level,table[index].adr);
}else
{
error("左值使用出错!");
}
}else if(kind == varLogical)
{
getsym();
offset();
if(sym == becomes || sym == eql)
{
if(sym == eql)
{
error("赋值语句不能使用 '=' 标识符!");
}
getsym();
be();
gen(STO,lev-table[index].level,table[index].adr);
}else
{
error("左值使用出错!");
}
}else
{
error("'%s' 为过程变量!");
}
}
}else if(sym == ifsym)
{
getsym();
be();
if(sym == thensym || textIn(3))
{
if(sym == thensym)
{
getsym();
}else
{
error("'if' 语句缺少 'then'标识符!");
}
int cx1 = cx;
gen(JPC,0,0);
Satement();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -