📄 plxcompiler.cpp
字号:
gen(JMP,0,0);
int cx2 = cx -1;
code[cx1].a = cx;
if(sym == elsesym)
{
getsym();
Satement();
code[cx2].a = cx;
}
if(sym == endsym)
{
getsym();
code[cx2].a = cx;
}else
{
error("if 语句缺乏 end标记符!");
text(2);
}
}else
{
error("不可识别的'if'语句内容!");
text(2);
}
}else if(sym == whilesym)
{
int cx1 = cx;
getsym();
be();
int cx2 = cx;
gen(JPC,0,0);
if(sym == dosym || textIn(3))
{
if(sym == dosym)
{
getsym();
}else
{
error("'while' 语句缺少 'do'标识符!");
}
Satement();
gen(JMP,0,cx1);
code[cx2].a = cx;
if(sym == endsym)
{
getsym();
}else
{
error("在 while 循环里需要一个 end 标识符!");
}
}else
{
error("不可识别的'while'语句内容!");
text(2);
}
}else if(sym == repeasym)
{
int cx1 = cx;
getsym();
Satement();
if(sym == untilsym || textIn(3))
{
if(sym == untilsym)
{
getsym();
}else
{
error("repeat 缺乏'until'标识符!");
}
be();
gen(JPC,0,cx1);
}else
{
error("repeat 缺乏'until'标识符!");
text(2);
}
}else if(sym == writesym)
{
getsym();
ae();
gen(SHO,0,0);
}else if(sym == callsym)
{
getsym();
if(sym == ident)
{
int index = position(id);
if(index == 0)
{
error("%s 没有定义!",id);
getsym();
text(2);
}else
{
if(table[index].kind != varProc)
{
error("被调用的不是过程!");
}else
{
gen(CAL,lev-table[index].level,table[index].adr);
getsym();
}
}
}else
{
error("call 语句无法识别!");
text(2);
}
}else
{
/* 空语句 */
}
}
/* bool 表达式语句 */
void plxCompiler::be()
{
bt();
while(sym == orsym)
{
getsym();
bt();
gen(OPR,0,14);
}
}
/* 数学整形表达式 */
void plxCompiler::ae()
{
int addop = -1;
if(sym == minus)
{
addop = sym;
getsym();
at();
gen(OPR,0,1);
}else
{
at();
}
while(sym == minus || sym == plus)
{
addop = sym;
getsym();
at();
if(addop == plus)
{
gen(OPR,0,2);
}else
{
gen(OPR,0,3);
}
}
}
/* 数学乘除表达式 */
void plxCompiler::at()
{
af();
int mulop = -1;
while(sym == times || sym == slash || sym == odd)
{
mulop = sym;
getsym();
af();
if(mulop == times)
{
gen(OPR,0,4);
}else if(mulop == slash)
{
gen(OPR,0,5);
}else
{
gen(OPR,0,6);
}
}
}
/* and 布尔表达式 */
void plxCompiler::bt()
{
bf();
while(sym == andsym )
{
getsym();
bf();
gen(OPR,0,15);
}
}
/* 表达式因子 */
void plxCompiler::af()
{
if(sym == ident)
{
int index = position(id);
if(index == 0)
{
error("'%s' 没有定义!",id);
getsym();
}else
{
int kind = table[index].kind;
if(kind == varInteger)
{
getsym();
offset();
gen(LOD,lev-table[index].level,table[index].adr);
}else if(kind == varConst)
{
gen(LIT,0,table[index].val);
getsym();
}else
{
error("'%s' 运算式中不可使用!",id);
}
}
}else
{
if(sym == lparen)
{
getsym();
ae();
if(sym == rparen)
{
getsym();
}else
{
error("缺乏')'标识符!");
}
}else if(sym == number)
{
gen(LIT,0,num);
getsym();
}else
{
error("不可识别的运算因子!");
text(2);
}
}
}
/* 布尔表达式 */
void plxCompiler::bf()
{
if(sym == ident)
{
int index = position(id);
if(index == 0)
{
error("'%s' 标识符未定义!",id);
getsym();
}else
{
if(table[index].kind == varLogical)
{
getsym();
offset();
gen(LOD,lev-table[index].level,table[index].adr);
}else
{
re();
}
}
}else if(sym == truesym)
{
getsym();
gen(LIT,0,1);
}else if(sym == falsesym)
{
getsym();
gen(LIT,0,0);
}else if(sym == notsym)
{
getsym();
bf();
gen(OPR,0,16);
}else if(sym == lparen)
{
getsym();
be();
if(sym == rparen)
{
getsym();
}else
{
error("运算式缺少 ')' 标识符!");
}
}else
{
re();
}
}
void plxCompiler::re()
{
ae();
switch(sym)
{
case eql : getsym();
ae();
gen(OPR,0,8);
break;
case gtr : getsym();
ae();
gen(OPR,0,12);
break;
case lss : getsym();
ae();
gen(OPR,0,10);
break;
case geq : getsym();
ae();
gen(OPR,0,11);
break;
case leq : getsym();
ae();
gen(OPR,0,13);
break;
case neql: getsym();
ae();
gen(OPR,0,9);
break;
default : error("错误的运算符号!");
}
}
/* 生成中间码 */
void plxCompiler::gen(fct _f,int _l,int _a)
{
if(cx < MAX_CODENUMBER)
{
code[cx].f = _f;
code[cx].l = _l;
code[cx].a = _a;
code[cx].line = codeIndex++;
if(_f == STO || _f == LOD || _f == LIT )
{
code[cx].lev = lev;
}else
{
code[cx].lev = -1;
}
cx++;
}else
{
error("程序长度溢出!");
}
}
/* 跳出错误代码区间 */
void plxCompiler::text(int index)
{
while(!textIn(index))
{
getsym();
}
}
/* 测试当前sym是否属于跟随集 */
bool plxCompiler::textIn(int index)
{
FOLLOW temp = non_finis[index];
for(int i = 0;i<temp.num ;i++)
{
if(sym == temp.followSym[i])
return TRUE;
}
return FALSE;
}
/* 清除虚拟机中的代码 */
void plxCompiler::clearStack()
{
t = 0;
b = 1;
p = 0;
s[1] = 0;
s[2] = 0;
s[3] = 0;
}
/* 虚拟机 */
int plxCompiler::interpret(int debugStyle)
{
CODE i; /* 指令寄存器 */
if(debugStyle == RUNBREAKPOINT) clearStack();
do{
i = code[p];
p++;
if(debugStyle == RUNBREAKPOINT)// && i.line > breakpoint && breakpoint != 0)
{
return i.line;
}
switch(i.f)
{
case LIT : t++;
s[t] = i.a;
break;
case OPR : switch(i.a)
{
case 0: t = b-1;
p = s[t+3];
b = s[t+2];
break;
case 1: s[t] = -s[t];
break;
case 2: t--;
s[t] = s[t] + s[t+1];
break;
case 3: t--;
s[t] = s[t] - s[t+1];
break;
case 4: t--;
s[t] = s[t] * s[t+1];
break;
case 5: t--;
s[t] = s[t] / s[t+1];
break;
case 6: t--;
s[t] = s[t] % s[t+1];
break;
case 7: break;
case 8: t--;
s[t] = (int)(s[t] == s[t+1]);
break;
case 9: t--;
s[t] = (int)(s[t] != s[t+1]);
break;
case 10:t--;
s[t] = (int)(s[t] < s[t+1]);
break;
case 11:t--;
s[t] = (int)(s[t] >= s[t+1]);
break;
case 12:t--;
s[t] = (int)(s[t] > s[t+1]);
break;
case 13:t--;
s[t] = (int)(s[t] <= s[t+1]);
break;
case 14:t--;
s[t] = (int)(s[t] | s[t+1]);
break;
case 15:t--;
s[t] = (int)(s[t] & s[t+1]);
break;
case 16:s[t] = (int)(!s[t]);
break;
}
break;
case LOD : s[t] = s[base(i.l)+i.a + s[t]];
break;
case STO : t--;
s[base(i.l)+i.a + s[t]] = s[t+1];
ListVariable(i,s[t+1]);
t--;
break;
case CAL : s[t+1] = base(i.l);
s[t+2] = b;
s[t+3] = p;
b = t + 1;
p = i.a;
break;
case INT : t = t + i.a;
break;
case JMP : p = i.a;
break;
case JPC : {CString str;
str.Format(_T("%d"),s[t]);
pOutputView->AddText(str);
}
if(s[t] == 0)
{
p = i.a;
}
t--;
break;
case SHO : {
ASSERT_VALID(pOutputView);
CString str;
str.Format(_T("%d"),s[t]);
pOutputView->AddText(str);
}
t--;
break;
default :;
}
if(debugStyle == RUNINTO)
{
showCode(i.line);
return i.line;
}
}while( p != 0 );
return -1;
}
/* 计算静态链地址 */
int plxCompiler::base(int l)
{
int b1 = b;
int l1 = l;
while(l1 > 0)
{
b1 = s[b1];
l1 = l1 - 1;
}
return b1;
}
/* 错误输出函数*/
void plxCompiler::error(const char *format,...)
{
char buffer[1024];
va_list valist;
va_start (valist, format);
if(_vsnprintf ((char *)buffer,1024,format,valist) == -1)
return;
va_end (valist);
textOut(buffer);
}
/* 错误代码输出 */
void plxCompiler::textOut(char *text)
{
CString str;
str.Format(_T("%04d error : %s"),lineIndex,text);
if(pDebugView->m_hWnd != NULL)
{
pDebugView->AddText(str,lineIndex);
}
errornum++;
}
/* 显示列表变量 */
void plxCompiler::ListVariable(CODE i,int value)
{
ASSERT_VALID(pVariableView);
int ix = getTableIndex(i.lev-i.l,i.a);
if(ix == -1)
return;
pVariableView->ChangeValue(table[ix].ldex,value);
}
/* 判断那个table变量是当前改变的变量 */
int plxCompiler::getTableIndex(int lev,int adx)
{
/* 用1开头是因为table本身是1开始的 */
for(int i=1;i<=tx;i++)
{
/* 加速的方法但是效果不明显,因为速度慢在于设置list */
if(table[i].adr != adx || table[i].level != lev)
{
continue;
}
return i;
}
return -1;
}
/************************************** 接口 ***********************************************/
/* 打开plx文件 */
bool plxCompiler::OpenFile(const char *fileName)
{
InFile.open(fileName);
if(InFile.fail())
return false;
sourceFilepath = CString(fileName);
return true;
}
/* 开始编译 */
void plxCompiler::Compiler()
{
clear();
getch();
getsym();
pDebugView->AddText("Compiling......");
pDebugView->AddText(sourceFilepath);
Prog();
closeResource();
}
/* build */
bool plxCompiler::Build(LPCTSTR outputfile)
{
Compiler();
if(this->GetErrorNumber() != 0)
return FALSE;
return outputCode(outputfile);
}
/* 虚拟机调试 */
void plxCompiler::Debug()
{
clearStack();
interpret(RUNBREAKPOINT);
}
/* 获取错误数目 */
int plxCompiler::GetErrorNumber()
{
return errornum;
}
/* 屏幕上显示中间码 */
void plxCompiler::showCode(int index)
{
if(pCodeView->m_hWnd == NULL)
return;
char word[9][4] = {"OPR",
"LIT",
"LOD",
"STO",
"INT",
"JMP",
"JPC",
"SHO",
"CAL"};
CString codetext;
pCodeView->SetRedraw(FALSE);
pCodeView->Clean();
for(int i=0;i<cx;i++)
{
if(index != i)
codetext.Format(_T(" %04d: %s %2d %4d"),i,word[code[i].f],code[i].l,code[i].a);
else
codetext.Format(_T("->%04d: %s %2d %4d"),i,word[code[i].f],code[i].l,code[i].a);
pCodeView->AddText(codetext,index);
}
pCodeView->SetRedraw(TRUE);
}
/* 输出中间码到文件 */
bool plxCompiler::outputCode(LPCTSTR outputfile)
{
ofstream objectOut(outputfile,ios::out);
if(objectOut.fail())
{
return FALSE;
}
for(int i=0;i<cx;i++)
{
objectOut<<code[i].f<<' '<<code[i].l<<' '<<code[i].a<<'\n';
}
return TRUE;
}
/* 设置断点函数 */
bool plxCompiler::SetBreakpointLine(int line)
{
if(breakpoint == line)
{
breakpoint = 0;
return FALSE;
}else
{
breakpoint = line;
}
return TRUE;
}
/* 设置Debug信息显示对象 */
void plxCompiler::SetDebugView(COutputView *pDebug)
{
ASSERT_VALID(pDebug);
pDebugView = pDebug;
}
/* 设置输出信息显示对象 */
void plxCompiler::SetOutputView(COutputView *pOutView)
{
ASSERT_VALID(pOutView);
pOutputView = pOutView;
}
/* 设置中间码显示对象 */
void plxCompiler::SetCodeOutView(COutputView *pCode)
{
ASSERT_VALID(pCode);
pCodeView = pCode;
}
/* 设置变量列表 */
void plxCompiler::SetVariableList(CVariableList *pList)
{
ASSERT_VALID(pList);
pVariableView = pList;
}
/* 清空重新初始化 */
void plxCompiler::clear()
{
cc = 0;
ll = 0;
lineIndex = 0;
tx = 0;
cx = 0;
dx = 0;
lev = 0;
codeIndex = 0;
errornum = 0;
nDebugStyle = 0;
}
/* 关闭文件流 */
void plxCompiler::closeResource()
{
InFile.close();
}
/* 获取中间码长度 */
int plxCompiler::GetCodeSize()
{
return cx;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -