本实验可以分成两部分:
1,PL/0语言的编译器—compiler
2.中间代码的解析器----interpreter
#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<stack>
#include<fstream>
using namespace std;
const string KeyWordlist[]={"","CONST","VAR","PROCEDURE","BEGIN","END","ODD","IF","THEN","CALL","WHILE","DO","READ","WRITE"};
//表中节点信息
struct tnode{
string val;
int row,col;
};
vector<tnode>vTable[50];
//存放临时结果
struct node{
int id;
int addr;
};
vector<node>anstring;
//抽象语法树的节点结构
struct Treenode{
string val;
vector<Treenode*>son;
Treenode():val(""){}
Treenode(string s):val(s){}
};
//符号表
struct Symnode{
string name,type;
int val,ProNum,offset;
};
vector<Symnode>SymTb;
//目标代码
struct Pcode{
string op;
int l,a;
Pcode(string op,int l,int a){
this->op=op;
this->l=l;
this->a=a;
}
Pcode(){
op="-1";
l=-1;
a=-1;
}
};
vector<Pcode>Code;
enum OPS
{
OP_RET = 0, OP_MOD = 1,OP_ADD = 2, OP_MINUS = 3, OP_MUL = 4, OP_DIV = 5,
OP_NEQ = 6, OP_EQ = 7, OP_LSS = 8, OP_LE = 9, OP_GT = 10, OP_GE =11,
OP_READ = 12, OP_WRITE = 13
};
vector<string>SmBuffer;//建立扫描缓冲区
int SBsize;
int row,col;//表示搜索指示器的位置。
char ch;//字符变量,存放最新读进的源程序字符。
string strToken;//字符数组,存放构成单词符号的字符串。
void Init(){ //初始化.
strToken="";
row=0,col=0;
SBsize=0;
string str="";
while(getline(cin,str)){
SmBuffer.push_back(str);
for(int i=0;i<SmBuffer[SBsize].size();i++)
if(SmBuffer[SBsize][i]>='a'&&SmBuffer[SBsize][i]<='z')SmBuffer[SBsize][i]-=32;
SmBuffer[SBsize].push_back('\t');
SBsize++;
}
SmBuffer.push_back("");
//cout<<SBsize<<endl;
//for(int i=0;i<SBsize;i++)cout<<SmBuffer[i]<<endl;
}
void Getchar(){ //将下一个输入字符读到ch中,搜索指示器前移一字符位置。
ch=SmBuffer[row][col];
if(col<SmBuffer[row].size()-1)col++;
else row++,col=0;
}
void GetBC(){ //检查ch中的字符是否为空白,若是,则调用Getchar()直至ch不是空白符。
while(ch==' '||ch=='\t')Getchar();
}
void Concat(){ //将ch中的字符连接到strToken之后。
strToken.push_back(ch);
}
bool IsLetter(){ //判断ch中的字符是否为字母。
if(ch>='A'&&ch<='Z')return true;
return false;
}
bool IsDight(){ //判断ch中的字符是否为数字。
if(ch>='0'&&ch<='9')return true;
return false;
}
int Reserve(){ //对strToken中的字符串查找保留字表,返回编码
for(int i=1;i<=13;i++){
if(strToken==KeyWordlist[i])return i;
}
return 0;
}
void Retract(){ //将搜索指示器回调一个字符位置,
if(col==0){
row--;
col=SmBuffer[row].size()-1;
}
else col--;
ch=' ';
}
int InsertvTable(int id){ //将strToken中的标识符插入符号表,并返回符号表指针。
vTable[id].push_back({strToken,row,col});
return vTable[id].size()-1;
}
void Clean(){ //去除数字的前导零。
int i=0;
while(i<strToken.size()-1&&strToken[i]=='0')i++;
strToken=strToken.substr(i);
}
void PrintAnstring(){ //打印结果
for(int i=0;i<anstring.size();i++){
cout<<vTable[anstring[i].id][anstring[i].addr].val<<endl;
}
}
bool solve1(){
while(row!=SBsize){
// cout<<row<<' '<<col<<endl;
strToken="";
Getchar();
GetBC();
if(row==SBsize)return true;
if(IsLetter()){
while(IsLetter()||IsDight()){
Concat();
Getchar();
}
Retract();
int code=Reserve();
if(code==0){
if(strToken.size()>10)return false;
else {
anstring.push_back({14,InsertvTable(14)});
}
}
else {
anstring.push_back({code,InsertvTable(code)});
}
}
else if(IsDight()){
while(IsDight()){
Concat();
Getchar();
}
if(IsLetter())return false;
Retract();
Clean();
anstring.push_back({15,InsertvTable(15)});
}
else if(ch=='='){Concat();anstring.push_back({16,InsertvTable(16)});}
else if(ch=='+'){Concat();anstring.push_back({17,InsertvTable(17)});}
else if(ch=='-'){Concat();anstring.push_back({18,InsertvTable(18)});}
else if(ch=='*'){Concat();anstring.push_back({19,InsertvTable(19)});}
else if(ch=='/'){Concat();anstring.push_back({20,InsertvTable(20)});}
else if(ch=='#'){Concat();anstring.push_back({21,InsertvTable(21)});}
else if(ch==';'){Concat();anstring.push_back({22,InsertvTable(22)});}
else if(ch==','){Concat();anstring.push_back({23,InsertvTable(23)});}
else if(ch=='.'){Concat();anstring.push_back({24,InsertvTable(24)});}
else if(ch=='('){Concat();anstring.push_back({25,InsertvTable(25)});}
else if(ch==')'){Concat();anstring.push_back({26,InsertvTable(26)});}
else if(ch==':'){
Getchar();
if(ch=='='){strToken=":=";anstring.push_back({27,InsertvTable(27)});}
else return false;
}
else if(ch=='<'){
Getchar();
if(ch=='='){strToken="<=";anstring.push_back({28,InsertvTable(28)});}
else{
Retract();
{strToken="<";anstring.push_back({29,InsertvTable(29)});}
}
}
else if(ch=='>'){
Getchar();
if(ch=='='){strToken=">=";anstring.push_back({30,InsertvTable(30)});}
else{
Retract();
{strToken=">";anstring.push_back({31,InsertvTable(31)});}
}
}
else return false;
}
return true;
}
//语法分析
int ansid=0;//当前处理到的词语的位置
string sym;//当前符号
int ndid;//当前符号所属的类型
int ProNum=0;//记录当前过程说明部分的层数
Treenode *Proroot;//整个程序的根节点
int pc=0;//下一条生成的目标代码的下标
//打印错误
void printErr(const char *err)
{
//printf("Line %d:%s\n", row, err);
//exit(-1);
}
//在符号表中存放标识符.当类型是常量时,var代表值;否则为偏移量offset
bool EnterSymTb(string name,string type,int var){
int id= SymTb.size()-1;
if(type=="VAR"||type=="CONST"){
//变量不能和同过程的变量,常量同名
while(id>=0&&SymTb[id].type!="PROCEDURE"){
if(SymTb[id].name==name){
printErr("Semantic errors 变量重复定义");
return false;
}
id--;
}
//变量不能和该区域能够调用的过程名同名,现在只能考虑本身,兄长和上级
while(id>=0){
if(SymTb[id].type=="PROCEDURE"&&SymTb[id].name==name&&SymTb[id].ProNum<=ProNum){
printErr("Semantic errors 变量与过程名相同!");
return false;
}
id--;
}
//变量的未初始化的初值这里暂定为-1;
if(type=="VAR") SymTb.push_back({name,type,-1,ProNum,var});
else SymTb.push_back({name,type,var,ProNum,0});
return true;
}
else{
//过程名不能与同过程的标识符相同
while(id>=0&&SymTb[id].type!="PROCEDURE"){
if(SymTb[id].name==name){
printErr("Semantic errors 过程名与标识符冲突");
return false;
}
id--;
}
//过程名和过程名
while(id>=0){
if(SymTb[id].type=="PROCEDURE"&&SymTb[id].name==name&&SymTb[id].ProNum<=ProNum){
printErr("Semantic errors 过程名与过程名定义相同!");
return false;
}
id--;
}
SymTb.push_back({name,type,-1,ProNum,pc});
//cout<<name<<' '<<type<<' '<<-1<<' '<<ProNum<<' '<<pc<<endl;
return true;
}
}
//在符号表中查找可以访问的标识符(变量或常量)
int lookup(string name){
int id=SymTb.size()-1;
//把子过程略过
while(SymTb[id].ProNum>ProNum)id--;
//先在当前过程中查找
while(id>=0&&SymTb[id].type!="PROCEDURE"){
if(SymTb[id].name==name)return id;
id--;
}
if(id<0)return id;
else{
//略过层次同等的和更深层次的
id--;
while(id>=0){
//从下往上,遇到一个层数低的则进去找
if(SymTb[id].ProNum<ProNum){
while(id>=0&&SymTb[id].type!="PROCEDURE"){
if(SymTb[id].name==name)return id;
id--;
}
}
id--;
}
return id;
}
}
//查找可以调用的过程名
int lookupp(string name){
int id=SymTb.size()-1;
while(id>=0){
if((SymTb[id].name==name&&SymTb[id].type=="PROCEDURE")
&&(SymTb[id].ProNum==ProNum+1||SymTb[id].ProNum<=ProNum))
return id;
id--;
}
return id;
}
//获取一个词
void getSym(){
node nd=anstring[ansid];
ndid=nd.id;
sym=vTable[nd.id][nd.addr].val;
row=vTable[nd.id][nd.addr].row;
col=vTable[nd.id][nd.addr].col;
ansid++;
}
//建立语法树
Treenode* MakeTree(Treenode* root,string s){
Treenode* newnode=new Treenode(s);
Treenode* fp=newnode;
root->son.push_back(fp);
return fp;
}
//函数声明部分
bool SubPro(Treenode* root,int offset);
bool SenTence(Treenode* root);
bool ConstDsp(Treenode* root);
bool ConstDfn(Treenode* root);
bool VarDsp(Treenode* root,int &offset);
bool ProHead(Treenode* root);
bool ProDsp(Treenode* root);
bool Factor(Treenode* root);
bool Item(Treenode* root);
bool Expression(Treenode* root);
bool Condition(Treenode* root);
bool AssignMent(Treenode* root);
bool IfSent(Treenode* root);
bool WhileSent(Treenode* root);
bool ReadWrite(Treenode* root);
bool CombSent(Treenode* root);
void MakeCode(string op,int l,int a);
//生成一条目标代码
void MakeCode(string op,int l,int a){
Pcode pcode(op,l,a);
Code.push_back(pcode);
pc++;
}
//常量定义部分
bool ConstDfn(Treenode* root){
if(ndid==14){
Treenode *tmp=MakeTree(root,"CONSTANTDEFINE");
string Symname=sym;
MakeTree(tmp,sym);getSym();
if(sym=="="){
MakeTree(tmp,sym);getSym();
if(ndid==15){
if(!EnterSymTb(Symname,"CONST",atoi(sym.c_str()))) return false;//语义分析
MakeTree(tmp,sym);getSym();
return true;
}
else return false;
}
else return false;
}
else return false;
}
//常量说明部分,返回常量的个数.
bool ConstDsp(Treenode* root){
if(sym=="CONST"){
Treenode *tmp=MakeTree(root,"CONSTANTDECLARE");
MakeTree(tmp,sym);getSym();
if(!ConstDfn(tmp))return false;
while(sym==","){
MakeTree(tmp,"COMMA");getSym();
if(!ConstDfn(tmp))return false;
}
if(sym==";"){
MakeTree(tmp,sym);getSym();
return true;
}
return false;
}
return true;
}
//变量说明部分
bool VarDsp(Treenode* root,int &offset){
if(sym=="VAR"){
Treenode *tmp=MakeTree(root,"VARIABLEDECLARE");
MakeTree(tmp,sym);getSym();
if(ndid==14){
if(!EnterSymTb(sym,"VAR",offset++))return false;//语义分析
MakeTree(tmp,sym);getSym();
while(sym==","){
MakeTree(tmp,"COMMA");getSym();
if(ndid==14){
if(!EnterSymTb(sym,"VAR",offset++))return false;//语义分析
MakeTree(tmp,sym);getSym();
}
else {return false;}
}
if(sym==";"){
MakeTree(tmp,sym);getSym();
return true;
}
return false;
}
return false;
}
return true;
}
//过程首部
bool ProHead(Treenode* root){
MakeTree(root,sym);getSym();
if(ndid==14){
if(!EnterSymTb(sym,"PROCEDURE",-1))return false;//语义分析
MakeTree(root,sym);getSym();
if(sym==";"){
MakeTree(root,sym);getSym();
return true;
}
return false;
}
return false;
}
//过程说明部分
bool ProDsp(Treenode* root){
if(sym=="PROCEDURE") {
ProNum++;
//cout<<"过程说明部分 "<<ProNum<<"层"<<endl;
if(ProNum>3)return false;
Treenode *tmp=MakeTree(root,"PROCEDUREDECLARE");
Treenode *tmpp=MakeTree(tmp,"PROCEDUREHEAD");
if(!ProHead(tmpp))return false;
//由该过程说明部分推出来的分程序再推出来的过程说明部分,最多不超过三层
if(!SubPro(tmp,3))return false;
ProNum--;
if(sym==";"){
MakeTree(tmp,sym);getSym();
while(sym=="PROCEDURE"){
if(!ProDsp(tmp))return false;
}
return true;
}
else return false;
}
return true;
}
//因子
bool Factor(Treenode* root){
Treenode *tmp=MakeTree(root,"FACTOR");
if(ndid==14){
int tid=lookup(sym);
if(tid<0) {printErr("Identifier not found!");return false;}
if(SymTb[tid].type=="CONST") MakeCode("LIT",0,SymTb[tid].val);
else MakeCode("LOD",ProNum-SymTb[tid].ProNum,SymTb[tid].offset);
MakeTree(tmp,sym);getSym();
return true;
}
else if(ndid==15){
MakeCode("LIT",0,atoi(sym.c_str()));
MakeTree(tmp,sym);getSym();
return true;
}
else if(sym=="("){
MakeTree(tmp,"LP");getSym();
if(!Expression(tmp))return false;
if(sym==")"){
MakeTree(tmp,"RP");getSym();
return true;
}
return false;
}
return false;
}
//项
bool Item(Treenode* root){
Treenode *tmp=MakeTree(root,"ITEM");
if(!Factor(tmp))return false;
string op=sym;
while(sym=="*"||sym=="/"){
MakeTree(tmp,sym);getSym();
if(!Factor(tmp))return false;
//根据前一位的符号生成相应的指令。
if(op=="*") MakeCode("OPR",0,OP_MUL);
else MakeCode("OPR",0,OP_DIV);
op=sym;
}
return true;
}
//表达式
bool Expression(Treenode* root){
Treenode *tmp=MakeTree(root,"EXPRESSION");
string op=sym;
if(sym=="+"||sym=="-"){
MakeTree(tmp,sym);getSym();
}
if(op=="-")MakeCode("LIT",0,0);
if(!Item(tmp))return false;
//如果前面有负号,则取反
if(op=="-") MakeCode("OPR",0,OP_MINUS);
while(sym=="+"||sym=="-"){
op=sym;
MakeTree(tmp,sym);getSym();
if(!Item(tmp))return false;
if(op=="+") MakeCode("OPR",0,OP_ADD);
else MakeCode("OPR",0,OP_MINUS);
}
return true;
}
//条件
bool Condition(Treenode* root){
Treenode *tmp=MakeTree(root,"CONDITION");
if(sym=="ODD"){
MakeTree(tmp,sym);getSym();
if(!Expression(tmp))return false;
MakeCode("OPR",0,OP_MOD);
return true;
}
else{
if(!Expression(tmp))return false;
if(sym=="="||sym=="#"||sym=="<"||sym=="<="||sym==">"||sym==">="){
string op=sym;
MakeTree(tmp,sym);getSym();
if(!Expression(tmp))return false;
if(op=="=")MakeCode("OPR",0,OP_EQ);
else if(op=="#")MakeCode("OPR",0,OP_NEQ);
else if(op=="<")MakeCode("OPR",0,OP_LSS);
else if(op=="<=")MakeCode("OPR",0,OP_LE);
else if(op==">")MakeCode("OPR",0,OP_GT);
else if(op==">=")MakeCode("OPR",0,OP_GE);
return true;
}
return false;
}
}
//赋值语句
bool AssignMent(Treenode* root){
Treenode *tmp=MakeTree(root,"ASSIGNMENT");
int tid = lookup(sym);//结果地址
if(tid==-1) {printErr("Variable not found!");return false;}
if(SymTb[tid].type=="CONST"){printErr("constant can't be a r-value!");return false;}
MakeTree(tmp,sym);getSym();
if(sym==":="){
MakeTree(tmp,sym);getSym();
if(!Expression(tmp))return false;
//赋值
MakeCode("STO",ProNum-SymTb[tid].ProNum,SymTb[tid].offset);
return true;
}
return false;
}
//条件语句
bool IfSent(Treenode* root){
Treenode *tmp=MakeTree(root,"IFSENTENCE");
MakeTree(tmp,sym);getSym();
if(!Condition(tmp))return false;
int cpc=pc;
MakeCode("JPC",0,0);
if(sym=="THEN"){
MakeTree(tmp,sym);getSym();
if(!SenTence(tmp))return false;
Code[cpc].a=pc;//条件不满足跳转的地址
return true;
}
return false;
}
//当型循环语句
bool WhileSent(Treenode* root){
Treenode *tmp=MakeTree(root,"WHILESENTENCE");
MakeTree(tmp,sym);getSym();
int cpc=pc;
if(!Condition(tmp))return false;
int jpc=pc;
MakeCode("JPC",0,0);
if(sym=="DO"){
MakeTree(tmp,sym);getSym();
if(!SenTence(tmp))return false;
MakeCode("JMP",0,cpc);//无条件跳转到判断条件是否成立
Code[jpc].a=pc;//条件不满足时的跳转地址
return true;
}
return false;
}
//过程调用语句
bool CallSent(Treenode* root){
Treenode *tmp=MakeTree(root,"CALLSENTENCE");
MakeTree(tmp,sym);getSym();
if(ndid==14){
int tid=lookupp(sym);
if(tid<0) {printErr("identifier not found!");return false;}
//---------SymTb[tid].offset
MakeCode("CAL",ProNum-SymTb[tid].ProNum,SymTb[tid].offset);
MakeTree(tmp,sym);getSym();
return true;
}
return false;
}
//读/写语句
bool ReadWrite(Treenode* root){
Treenode *tmp=nullptr;
string type=sym;
if(type=="READ") tmp=MakeTree(root,"READSENTENCE");
else tmp=MakeTree(root,"WRITESENTENCE");
MakeTree(tmp,sym);getSym();
if(sym=="("){
MakeTree(tmp,"LP");getSym();
if(ndid==14){
int tid=lookup(sym);
if(tid<0) {printErr("identifier not found!");return false;}
if(type=="READ"){
if(SymTb[tid].type!="VAR") {printErr("variable expected!");return false;}
MakeCode("OPR",0,OP_READ);
MakeCode("STO",ProNum-SymTb[tid].ProNum,SymTb[tid].offset);
}
else{
if(SymTb[tid].type=="VAR") MakeCode("LOD",ProNum-SymTb[tid].ProNum,SymTb[tid].offset);
else MakeCode("LIT",0,SymTb[tid].val);
MakeCode("OPR",0,OP_WRITE);
}
MakeTree(tmp,sym);getSym();
while(sym==","){
MakeTree(tmp,"COMMA");getSym();
if(ndid==14){
int tid=lookup(sym);
if(tid<0) {printErr("identifier not found!");return false;}
if(type=="READ"){
if(SymTb[tid].type!="VAR") {printErr("variable expected!");return false;}
MakeCode("OPR",0,OP_READ);
MakeCode("STO",ProNum-SymTb[tid].ProNum,SymTb[tid].offset);
}
else{
if(SymTb[tid].type=="VAR") MakeCode("LOD",ProNum-SymTb[tid].ProNum,SymTb[tid].offset);
else MakeCode("LIT",0,SymTb[tid].val);
MakeCode("OPR",0,OP_WRITE);
}
MakeTree(tmp,sym);getSym();
}
else return false;
}
if(sym==")"){
MakeTree(tmp,"RP");getSym();
return true;
}
return false;
}
return false;
}
return false;
}
//复合语句
bool CombSent(Treenode* root){
Treenode *tmp=MakeTree(root,"COMBINED");
MakeTree(tmp,sym);getSym();
if(!SenTence(tmp))return false;
while(sym==";"){
MakeTree(tmp,sym);getSym();
if(!SenTence(tmp))return false;
}
if(sym=="END"){
MakeTree(tmp,sym);getSym();
return true;
}
return false;
}
//语句
bool SenTence(Treenode* root){
Treenode *tmp=MakeTree(root,"SENTENCE");
if(ndid==14){ //赋值语句
if(!AssignMent(tmp))return false;
}
else if(sym=="IF"){ //条件语句
if(!IfSent(tmp))return false;
}
else if(sym=="WHILE"){ //当型循环语句
if(!WhileSent(tmp))return false;
}
else if(sym=="CALL"){ //过程调用语句
if(!CallSent(tmp))return false;
}
else if(sym=="READ"||sym=="WRITE"){ //读语句或写语句
if(!ReadWrite(tmp))return false;
}
else if(sym=="BEGIN"){ //复合语句
if(!CombSent(tmp))return false;
//else cout<<"复合语句"<<endl;
}
else { //没有语句满足上面几个语句,可以假定此刻是一个空语句,但也可能是一个错误的语法。
//cout<<sym<<endl;
MakeTree(tmp,"EMPTY");
}
return true;
}
//分程序
bool SubPro(Treenode *root,int offset){
int tpc=pc;
MakeCode("JMP",0,0);//跳转指令
Treenode*tmp=MakeTree(root,"SUBPROG");
if(!ConstDsp(tmp))return false;
if(!VarDsp(tmp,offset))return false;
if(!ProDsp(tmp))return false;
//是否有子过程
Code[tpc].a=pc;
MakeCode("INT",0,offset);//为该子过程分配所需的空间,正是offset的值。
if(!SenTence(tmp))return false;
MakeCode("OPR",0,OP_RET);//
return true;
}
//程序
bool ProGram(){
Proroot=new Treenode("PROGRAM");//整个程序的根节点
if(!SubPro(Proroot,3))return false;
if(sym=="."){
MakeTree(Proroot,sym);
return true;
}
return false;
}
int NspSize=0;//空格的数量
//打印语法分析树
void PrintTree(Treenode* root){
for(int i=0;i<NspSize;i++)printf(" ");
cout<<root->val;
int sz=root->son.size();
if(sz>0){
cout<<"("<<endl;
NspSize++;
for(int i=0;i<sz;i++){
PrintTree(root->son[i]);
if(i==sz-1)printf("\n");
else printf(",\n");
}
NspSize--;
for(int i=0;i<NspSize;i++)printf(" ");
cout<<")";
}
}
string AnsBrack;//最后的括号结果形式的字符串。
//以括号形式打印结果
void PrintBracket(Treenode* root){
AnsBrack+=root->val;
int sz=root->son.size();
if(sz>0){
AnsBrack+="(";
for(int i=0;i<sz;i++){
PrintBracket(root->son[i]);
if(i<sz-1) AnsBrack+=",";
}
AnsBrack+=")";
}
}
//打印符号表
void PrintSymTb(){
int sz=SymTb.size();
for(int i=0;i<sz;i++){
cout<<SymTb[i].name<<' '<<SymTb[i].type<<" "<<SymTb[i].val<<' '<<SymTb[i].ProNum<<' '<<SymTb[i].offset<<endl;
}
}
//输出目标代码
void WriteCode(){
int sz=Code.size();
ofstream fout("program.code");
for(int i=0;i<sz;i++){
fout<<Code[i].op<<' '<<Code[i].l<<' '<<Code[i].a<<endl;
}
fout.close();
}
//打印目标代码
void PrintCode(){
int sz=Code.size();
for(int i=0;i<sz;i++){
cout<<Code[i].op<<' '<<Code[i].l<<' '<<Code[i].a<<endl;
}
}
int main(){
// freopen("test5.txt","r",stdin);
Init();
bool flag=solve1();
if(!flag)return -1;
//cout<<"Lexical Error"<<endl;
else{ //此时已经完成了词法分析。
//PrintAnstring();
//添加一个程序终结符
vTable[0].push_back({"@",row,col-1});
anstring.push_back({0,0});
//开始语法分析,读取第一个字符。
getSym();
if(!ProGram()||ansid!=anstring.size()-1){
// cout<<"error in "<<row<<","<<col<<" "<<sym<<endl;
//cout<<"Syntax Error"<<endl;
return -1;
}
else{
//cout<<"语法分析成功!"<<endl;
//PrintTree(Proroot);
//PrintBracket(Proroot);
//cout<<AnsBrack<<endl;
//PrintSymTb();
WriteCode();
PrintCode();
}
}
return 0;
}
#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<fstream>
using namespace std;
//目标代码
struct Pcode{
string op;
int l,a;
Pcode(string op,int l,int a){
this->op=op;
this->l=l;
this->a=a;
}
Pcode(){
op="-1";
l=-1;
a=-1;
}
};
vector<Pcode>Code;
enum OPS
{
OP_RET = 0, OP_MOD = 1,OP_ADD = 2, OP_MINUS = 3, OP_MUL = 4, OP_DIV = 5,
OP_NEQ = 6, OP_EQ = 7, OP_LSS = 8, OP_LE = 9, OP_GT = 10, OP_GE =11,
OP_READ = 12, OP_WRITE = 13
};
int PC=0;
//加载目标代码
void Init(){
ifstream fin("program.code");
string op;
int l,a;
while(fin>>op>>l>>a){
Code.push_back({op,l,a});
}
PC=Code.size();
}
//打印目标代码
void PrintCode(){
int sz=Code.size();
for(int i=0;i<sz;i++){
cout<<i<<' '<<Code[i].op<<' '<<Code[i].l<<' '<<Code[i].a<<endl;
}
}
const int ret_addr = 1, dynamic_link = 0, static_link = 2;
Pcode IR;
int IP=0,SP=0,BP=0;//----下一条指令寄存器;栈顶寄存器;基址寄存器
int stack[91000000]={0};
//解释器
void Interpret(){
while(IP<PC){
IR=Code[IP++];
if(IR.op=="LIT"){
stack[SP++]=IR.a;
}
else if(IR.op=="LOD"){
if(IR.l==0) stack[SP++]=stack[BP+IR.a];
else
{
int out_bp=stack[BP+static_link];
while(--IR.l) out_bp=stack[out_bp+static_link];
stack[SP++]=stack[out_bp+IR.a];
}
}
else if(IR.op=="STO"){
if(IR.l==0) stack[BP+IR.a]=stack[SP-1];
else
{
int out_bp=stack[BP+static_link];
while(--IR.l) out_bp=stack[out_bp+static_link];
stack[out_bp+IR.a]=stack[SP-1];
}
}
else if(IR.op=="CAL"){
stack[SP+ret_addr]=IP;
stack[SP+dynamic_link]=BP;
switch(IR.l){
case -1://子过程
{
stack[SP+static_link]=BP;
break;
}
case 0://同级过程
{
stack[SP+static_link]=stack[BP+static_link];
break;
}
case 1://父亲过程
{
stack[SP+static_link]=stack[stack[BP+static_link]+static_link];
break;
}
case 2://爷爷过程
{
stack[SP+static_link]=stack[stack[stack[BP+static_link]+static_link]+static_link];
break;
}
}
IP=IR.a;
BP=SP;
}
else if(IR.op=="INT"){
SP+=IR.a;
}
else if(IR.op=="JMP"){
IP=IR.a;
}
else if(IR.op=="JPC"){
if(stack[SP-1]==0)IP=IR.a;
}
else if(IR.op=="OPR"){
switch(IR.a){
case OP_RET:
{
IP=stack[BP+ret_addr];
SP=BP;
BP=stack[BP+dynamic_link];
if(SP==0){//---
//printf("program exited normally!\n");
return;
}
break;
}
case OP_MOD:
{
stack[SP-1]=stack[SP-1]%2;
break;
}
case OP_ADD:
{
stack[SP-2]=stack[SP-1]+stack[SP-2];
SP--;
break;
}
case OP_MINUS:
{
stack[SP-2]=stack[SP-2]-stack[SP-1];//
SP--;
break;
}
case OP_MUL:
{
stack[SP-2]=stack[SP-1]*stack[SP-2];
SP--;
break;
}
case OP_DIV:
{
stack[SP-2]=stack[SP-2]/stack[SP-1];
SP--;
break;
}
case OP_NEQ:
{
stack[SP-2]=(stack[SP-1]!=stack[SP-2])?1:0;
SP--;
break;
}
case OP_EQ:
{
stack[SP-2]=(stack[SP-1]==stack[SP-2])?1:0;
SP--;
break;
}
case OP_LSS:
{
stack[SP-2]=(stack[SP-2]<stack[SP-1])?1:0;
SP--;
break;
}
case OP_LE:
{
stack[SP-2]=(stack[SP-2]<=stack[SP-1])?1:0;
SP--;
break;
}
case OP_GT:
{
stack[SP-2]=(stack[SP-2]>stack[SP-1])?1:0;
SP--;
break;
}
case OP_GE:
{
stack[SP-2]=(stack[SP-2]>=stack[SP-1])?1:0;
SP--;
break;
}
case OP_READ:
{
//cout << "Please input a number:" << endl;
cin >> stack[SP++];
break;
}
case OP_WRITE:
{
cout<<stack[SP-1]<<endl;
break;
}
default:
{
printf("Unexpected operation!\n"); return;
}
}
}
else{
return;
}
}
}
int main(){
Init();
PrintCode();
Interpret();
return 0;
}