📄 pl0doc.cpp
字号:
{
Advanced();
Expression(lev,tx);//完成
Advanced();
}
}
//项分析
void CPL0Doc::Term(int lev,int tx,int i)
{
int mulop;
if(i==1)
Advanced();
Factor(lev,tx);//第一个因子,得到结果
while(Sym == 15||Sym == 16)// * is 15 while / is 16
{
mulop = Sym;
Advanced();
Factor(lev,tx);//第二个因子,得到结果
if(mulop == 15)
Generate((Functions)2,0,4);//栈顶两个元素相乘,结果放在次栈顶
else
Generate((Functions)2,0,5);//栈顶两个元素相除,结果放在次栈顶
}
}
//表达式
void CPL0Doc::Expression(int lev,int tx)
{
int addop;
addop = Sym;
if(Sym == 13||Sym == 14)//定符号数 + is 13 - is 14
{
//Advanced();
Term(lev,tx);
if(addop == 14)
Generate((Functions)2,0,1);//是负数opr = 2
}
else//不是 + 或 -
Term(lev,tx,0);
while(Sym == 13||Sym == 14)
{
addop = Sym;
//Advanced();
Term(lev,tx);
if(addop == 13)
Generate((Functions)2,0,2);// +
else
Generate((Functions)2,0,3);// -
}
}
//条件判断中的条件真假判断
void CPL0Doc::Condition(int lev,int tx)
{
int relop ;//关系运算符
if(Sym == 29)//oddsym = 29
{
Advanced();
Expression(lev,tx);
Generate((Functions)2,0,6);//取反opr = 2
}
else
{
Expression(lev,tx);//离开时,顺带一个 标识符 表达式 1
relop = Sym;
Advanced();
Expression(lev,tx); //表达式 2
switch(relop) //两个表达式进行运算 opr =2
{
case 20:Generate((Functions)2,0,8);break;//eql = 20
case 28:Generate((Functions)2,0,9);break;//neq = 28
case 18:Generate((Functions)2,0,10);break;//lss = 18
case 22:Generate((Functions)2,0,11);break;//geq = 22
case 21:Generate((Functions)2,0,12);break;//gtr = 21
case 19:Generate((Functions)2,0,13);break;//leq = 19
}
}
}
//语句处理部分
void CPL0Doc::Statement(int lev,int tx)
{
int cx1,cx2;
int i = -1;
//分支 identifier
if(Sym == 888)//"ident"
{
i = Position(temp);
Advanced();
Advanced();
Expression(lev,tx);
Generate((Functions)4,lev-table[i].level,table[i].address);//sto =4
}
//分支 read
else if(Sym == 10)//readsym
{
Advanced();
do
{
Advanced();
i = Position(temp);
Generate((Functions)2,0,16);//opr =2
Generate((Functions)4,lev-table[i].level,table[i].address);//sto =4
Advanced();
}while(Sym == 27 );//comma
Advanced();
}
//分支write
else if(Sym == 9)//writesym = 9
{
Advanced();
do
{
Advanced();
Expression(lev,tx);
Generate((Functions)2,0,14); //opr =2
}while(Sym == 27); //comma = 27
Advanced();
Generate((Functions)2,0,15);//opr
}
//分支 call
else if(Sym == 8)//callsym
{
i = -1;
Advanced();
i = Position(temp);
Generate((Functions)5,lev-table[i].level,table[i].address);// cal = 5
Advanced();
}
//分支 if
else if(Sym == 3)//ifsym = 3
{
Advanced();
Condition(lev,tx);
Advanced();
cx1 = CIndex;
Generate((Functions)8,0,0);//待返填,当条件为假时,跳转jpc
Statement(lev,tx);
Codes[cx1].Addr = CIndex;//跳到语句结束处
}
//分支 begin
else if(Sym == 1)//beginsym = 1
{
do
{
Advanced();
Statement(lev,tx);
}while(Sym == 26 );//分号semicolon = 26
Advanced();
}
//分支 while
else if(Sym == 11)//whilesym = 11
{
cx1 = CIndex;
Advanced();
Condition(lev,tx);
cx2 = CIndex;
Generate((Functions)8,0,0);//jpc = 8
Advanced();
Statement(lev,tx);
Generate((Functions)7,0,cx1);//jmp = 7
Codes[cx2].Addr = CIndex;
}
else error(33);
}
//程序块分析
void CPL0Doc::Block(int lev,int tx)
{
int RelDepth=3;//开头留出三个空间,用来存放一些链接参数用
int TX0;
int CIndex0;
TX0 = TXCode;//保存前一个过程在符号表中的位置,以便在下面反填
CIndex0=CIndex;//保存跳转的地址,以便在下面反填要转移到的地方
Generate((Functions)7,0,0);//"jmp"
do
{
if(Sym == 6)//constsym
{
Advanced();
Constdeclaration(RelDepth);
Advanced();
}
if(Sym == 5)//"varsym"
{
Vardeclaration(RelDepth);
Advanced();
}
if(Sym == 7)//"procsym"
{
TXCode++;
Advanced();
Advanced();
Advanced();
Block(lev + 1,tx);
Advanced();
}
}while((Sym ==5|| Sym==6||Sym ==7));// var const procedure;
//下面开始语句部分的处理
Codes[CIndex0].Addr=CIndex;
table[TX0].address = CIndex;
table[TX0].size = RelDepth;//为变量分配
TX0 = TXCode;
Generate((Functions)6,0,RelDepth);//init =1
Statement(lev,tx);
Generate((Functions)2,0,0);//opr =2 ,退出该层
}
int CPL0Doc::Base(int lev)
{
int base0;
base0 = CurBase;
while(lev > 0)
{
base0 = Stack[base0];
lev --;
}
return base0;
}
bool CPL0Doc::OnCodesAnalyze()
{
bool flag=false;
if(OnSyntaxAnalyze()==true)
{
if(twoelement.head!=NULL)
{
Advanced(0);
TXCode = 0;
CIndex = 0;
Block(0,0);
flag=true;
CString result;
result.Empty();
result+="中间代码已经生成!";
CView* cv;
POSITION p=GetFirstViewPosition();
cv=GetNextView(p);
cv->SetWindowText(result);
}
}
return flag;
}
void CPL0Doc::Interpret(bool & interrupt,int count)
{
Top = 0;
CurBase = 1;
Ip = 0;
Stack[1] = 0;
Stack[2] = 0;
Stack[3] = 0;
do
{
Instructor = Codes[Ip];
Ip ++;
switch(Instructor.function)
{
case 1:Stack[++Top] = Instructor.Addr;break;//lit
case 2://opr
switch(Instructor.Addr)
{
case 0:{//subproc finished
Top = CurBase - 1;
Ip = Stack[Top+3];
CurBase = Stack[Top+2];
}
break;
case 1:Stack[Top] = -Stack[Top];break;//reverse
case 2:{//add
Top --;
Stack[Top] += Stack[Top+1];
}
break;
case 3:{//minus
Top --;
Stack[Top] -= Stack[Top+1];
}
break;
case 4:{//mul
Top --;
Stack[Top] *= Stack[Top+1];
}
break;
case 5:{//div
Top --;
Stack[Top] /= Stack[Top+1];
}
break;
case 6:Stack[Top] = (int)!Stack[Top];//odd
break;
case 8:{//=
Top --;
Stack[Top] = (int)(Stack[Top]==Stack[Top+1]);
}
break;
case 9:{//!=
Top --;
Stack[Top] = (int)(Stack[Top] != Stack[Top+1]);
}
break;
case 10:{//<
Top --;
Stack[Top] = (int)(Stack[Top] < Stack[Top+1]);
}
break;
case 11:{//>=
Top --;
Stack[Top] = (int)(Stack[Top] >=Stack[Top+1]);
}
break;
case 12:{//>
Top --;
Stack[Top] = (int)(Stack[Top] > Stack[Top+1]);
}
break;
case 13:{//<=
Top --;
Stack[Top] = (int)(Stack[Top] <= Stack[Top+1]);
}
break;
case 14:{//write
CString str;
CString result;
result.Empty();
str.Empty();
CView* cv;
POSITION p=GetFirstViewPosition();
cv=GetNextView(p);
cv->GetWindowText(result);
str.Format("%d",count++);
result+="输出["+str+"]"+":";
str.Empty();
str.Format(" %d",Stack[Top]);
result+=str+(char)13+(char)10;
cv->SetWindowText(result);
//将栈顶元素写出来
//同时 写进文件
Top--;
}
break;
case 15:{
//换行分支,写在case 14: 中
}
break;
case 16:{//read
Top ++;
CAnotherShow Input;
Input.DoModal();
Stack[Top]=Input.m_Variable;
if(Input.flag)
{
Ip=0;
interrupt=true;
}
}
break;
default:{
error(33);
}
break;
}
break;
case 3:{//lod
Top ++;
Stack[Top] = Stack[Base(Instructor.levdiff) + Instructor.Addr];
}
break;
case 4:{//sto
Stack[Base(Instructor.levdiff) + Instructor.Addr] = Stack[Top];
Top --;
}
break;
case 5:{//cal
Stack[Top+1] = Base(Instructor.levdiff);
Stack[Top+2] = CurBase;
Stack[Top+3] = Ip;
CurBase=Top+1;
//Top
Ip = Instructor.Addr;
}
break;
case 6:Top = Top + Instructor.Addr;break;//int
case 7:Ip = Instructor.Addr;break;//jmp
case 8:{//jpc
if(Stack[Top] == 0)
Ip = Instructor.Addr;
Top --;
}
break;
default:{
}
break;
}
}while(Ip !=0);
}
void CPL0Doc::OnExecute()
{
// TODO: Add your command handler code here
CString result;
result.Empty();
CView * cv;
POSITION p=GetFirstViewPosition();
cv=GetNextView(p);
bool Interrupt=false;
int Count=1;
if(OnCodesAnalyze())
{
cv->SetWindowText(result);
Interpret(Interrupt,Count);
}
CString finished;
finished.Empty();
if(Interrupt==false)
finished+="执行完毕";
else
finished+="中途停止";
result.Empty();
cv->GetWindowText(result);
result+=finished;
cv->SetWindowText(result);
}
void CPL0Doc::OnCodesview()
{
// TODO: Add your command handler code here
CString a,b,c,d,e,n;
n+=(char)13;
n+=(char)10;
a.Empty();
a+="代码:(功能,层差,偏移地址|数值)"+n;
for(int i=0;i<CIndex;i++)
{
b.Empty();
c.Empty();
d.Empty();
e.Empty();
switch(Codes[i].function)
{
case 1:b="lit";break;
case 2:b="opr";break;
case 3:b="lod";break;
case 4:b="sto";break;
case 5:b="cal";break;
case 6:b="init";break;
case 7:b="jmp";break;
case 8:b="jpc";break;
}
c.Format("%d",Codes[i].levdiff);
d.Format("%d",Codes[i].Addr);
e.Format("%d",i);
a+=( e+": " + b+ " ----- " + c+ " ----- "+ d+ " " + n );
}
CView* cv;
POSITION p=GetFirstViewPosition();
cv=GetNextView(p);
cv=GetNextView(p);
cv=GetNextView(p);
cv->SetWindowText(a);
}
void CPL0Doc::OnInstru()
{
// TODO: Add your command handler code here
CInstruction dlg;
dlg.DoModal();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -