PL/0语言编译器

本实验可以分成两部分:
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;
}
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值