PL/0编译器功能扩充

部署运行你感兴趣的模型镜像

1 增加语句for(<语句>;<条件>;<语句>)

Step1: 在pl0.h中修改

    pl0.h中在enum symbol { } 符号枚举集中加入
    forsym, 并更改符号的个数 symnum

Step2: 增加保留字名字并增加对应的保留字符号

    名字: strcpy(&(word[6][0]),"for");
    符号: wsym[6]=forsym;
    (: 顺序按26个字母的顺序重新排列)

Step3: 增加语句开始符号集

    statbegsys[forsym]=true;

Step4: 语句处理函数内添加关于for语句的处理

//int i , cx1 , cx2 , cx3 , cx4 , cx5; (cx3,cx4,cx5为新增加的地址)
if(sym == forsym)
{
    getsymdo;
    if(sym != lparen)  error(34);//没有左括号出错
    else 
    {
        getsymdo;
        statementdo(nxtlev, ptx, lev);  //S1代码
        //语句缺少分号出错
        if(sym != semicolon)  error(10);                 
        else
        {
            /*cx是当前指令的地址 保存判断条件操作的    位置 */
            cx1=cx;
            getsymdo;
            conditiondo(nxtlev, ptx, lev);   //E代码
            if(sym != semicolon)  error(10);                              
            else 
            {   
                cx2=cx;
                gendo(jpc,0,0);
                cx3=cx;
                gendo(jmp,0,0);
                getsymdo;
                cx4=cx;
                //S2代码
                statementdo(nxtlev, ptx, lev);    
                if(sym != rparen)  error(22);  //缺少右括号出错
                else 
                {
                    gendo(jmp,0,cx1); // 回头重新判断条件 
                    getsymdo;
                    cx5=cx;
                    statementdo(nxtlev, ptx, lev);  //S3代码
                    code[cx3].a=cx5;
                    gendo(jmp,0,cx4); 
                    code[cx2].a=cx;  // 反填跳出循环的地址,与if类似
                }
            }
        }
    }
}

2 扩充语句if <条件> then <语句> else <语句>

Step1: 在pl0.h中修改

    pl0.h中在enum symbol { } 符号枚举集中加入
    elsesym, 并更改符号的个数 symnum

Step2: 增加保留字名字并增加对应的保留字符号

    名字: strcpy(&(word[4][0]),"else");
    符号: wsym[4]=elsesym;
    (: 顺序按26个字母的顺序重新排列)

Step3: 语句处理函数内添加关于if语句的处理

if(sym==ifsym) /*准备按照if语句处理*/
{
    getsymdo;
    memcpy(nxtlev,fsys,sizeof(bool)*symnum);
    nxtlev[thensym]=true;
    nxtlev[dosym]=true; /*后跟符号为then或do*/
    conditiondo(nxtlev,ptx,lev); /*调用条件处理(逻辑运算)函数*/
    if(sym==thensym)
    {
        getsymdo;
    }
    else
    {
        error(16); /*缺少then*/
    }
    cx1=cx; /*保存当前指令地址*/
    gendo(jpc,0,0); /*生成条件跳转指令,跳转地址暂写0*/
    statementdo(fsys,ptx,lev); /*处理then后的语句*/
    if(sym==semicolon)
    {
        getsymdo;
        if(sym==elsesym)    /*then语句后出现else*/
        {
            getsymdo;
            cx2=cx;
            /*cx为当前的指令地址,cx+1即为then语句执行后的else语句的位置,回填地址*/
            code[cx1].a=cx+1; 
            gendo(jmp,0,0);
            statementdo(fsys,ptx,lev);
            /*经statement处理后,cx为else后语句执行
            完的位置,它正是前面未定的跳转地址,回填地址*/
            code[cx2].a=cx; 
        }
        else
        {
            /*经statement处理后,cx为then后语句执行完的位置,它正是前面未定的跳转地址*/
            code[cx1].a=cx; 
        }
    }
    else
    {
        error(5);
    }
}

3 增加语句repeat <语句> until <条件>

Step1: 在pl0.h中修改

    pl0.h中在enum symbol { } 符号枚举集中加入
    repeatsym, untilsym, 并更改符号的个数 symnum

Step2: 增加保留字名字并增加对应的保留字符号

    名字: strcpy(&(word[11][0]),"repeat");
         strcpy(&(word[13][0]),"until");
    符号: wsym[11]=repeatsym;
         wsym[13]=untilsym;
    (: 顺序按26个字母的顺序重新排列)

Step3: 增加语句开始符号集

    statbegsys[repeatsym]=true;

Step4: 语句处理函数内添加关于repeat语句的处理

else if(sym==repeatsym)
{
    cx1=cx; /*保存当前指令地址*/
    getsymdo;
    memcpy(nxtlev,fsys,sizeof(bool)*symnum);
    nxtlev[untilsym]=true;
    statementdo(fsys,ptx,lev);
    if(sym==semicolon)
    {
        getsymdo;
        if(sym==untilsym)
        {
            getsymdo;
            conditiondo(fsys,ptx,lev);
            /*经condition处理后,cx1为repeat后循环语句的位置,条件为假时一直循环*/
            gendo(jpc,0,cx1); 
        }
    }
    else
    {
        error(5);
    }
}

4. 增加自增自减运算

对于++和–的扩充,分为两种情况:

    作为语句的情况
    例如: ++i,--i,i++,i--;
    作为表达式的因子的情况
    例如:  b:=a++;b:=a--;
           b:=++a;b:=--a;

第一种作为语句情况的扩充:
Step1: 在pl0.h中修改

    pl0.h中在enum symbol { } 符号枚举集中加入
    addadd, subsub, 并更改符号的个数 symnum

Step2: 语句处理函数内添加关于++ 和–的处理

else if(sym==addadd) /*检测到后置++符号*/
 {
     getsymdo; 
     // 如果++后面跟的量可以在名字表中找到 
     if(i!=0)
     {
         gendo(lod,lev-table[i].level,table[i].adr);
         gendo(lit,0,1);
         gendo(opr,0,2);
         gendo(sto,lev-table[i].level,table[i].adr);
     }
 }
 else if(sym==subsub) /*检测到后置--符号*/
 {
     getsymdo;
     // 如果 -- 后面跟的量可以在名字表中找到 
     if(i!=0)
     {
         gendo(lod,lev-table[i].level,table[i].adr);
         gendo(lit,0,1);
         gendo(opr,0,3);
         gendo(sto,lev-table[i].level,table[i].adr);
     }
 }

 if(sym==addadd) /*检测到前置++符号*/
 {
     getsymdo;
     if(sym==ident) /*后面跟的是变量*/
     {
         i=position(id,*ptx);
         if(i==0)
         {
             error(11);
         }
         else
         {
             if(table[i].kind!=variable)
             {         
                 /*++后没跟变量,出错*/
                 error(12);
                 i=0;
             }
             else
             {     
                 /*++后跟变量,处理生成中间代码*/
                 getsymdo;
                 /*先取    值到栈顶*/
                 gendo(lod,lev-table[i].level,table[i].adr);
                 gendo(lit,0,1);  /*将1放到栈顶*/
                 gendo(opr,0,2); /*加法,即+1,栈顶加次栈顶*/
                 /*出栈取值到内存*/
                 gendo(sto,lev-table[i].level,table[i].adr);
             }
         }
     }
 }

 else if(sym==subsub) /*检测到前置--符号*/
 {
     getsymdo;
     if(sym==ident) /*后面跟的是变量*/
     {
         i=position(id,*ptx);
         if(i==0)
         {
             error(11);
         }
         else
         {
             /*--后没跟变量,出错*/
             if(table[i].kind!=variable) 
             {
             error(12);
             i=0;
             }
             else /*--后跟变量,处理生成中间代码*/
             {
                 if(table[i].kind==variable) /*后跟变量*/
                 {
                     getsymdo;
                     /*先取值到栈顶*/
                     gendo(lod,lev-table[i].level,table[i].adr);
                     gendo(lit,0,1); /*将1放到栈顶*/
                     gendo(opr,0,3); /*减法,即-1,栈顶减次栈顶*/
                     /*出栈取值到内存*/
                     gendo(sto,lev-table[i].level,table[i].adr);
                 }
             }
         }
     }
 }

第二种作为语句情况的扩充:

Step1: 添加因子开始符号集

   facbegsys[addadd]=true; /*前置++*/
   facbegsys[subsub]=true; /*前置--*/

Step2: 在因子处理函数factor中添加 ++和–相关处理

if(sym==addadd) /*因子出2现b:=a++类型*/
{
    gendo(lit,lev-table[i].level,1); /*将值入栈*/
    /*加法,即+1,栈顶加次栈顶*/
    gendo(opr,lev-table[i].level,2);         
    /*出栈取值到内存*/                                                    
    gendo(sto,lev-table[i].level,table[i].adr); 
    /*取值到栈顶*/

    gendo(lod,lev-table[i].level,table[i].adr); 
    gendo(lit,0,1);
    gendo(opr,0,3); /*栈顶值减*/
    getsymdo;
}
else if(sym==subsub) /*因子出现b:=a--类型*/
{
    gendo(lit,lev-table[i].level,1); /*将值入栈*/
    /*减法,即-1,栈顶减次栈顶*/
    gendo(opr,lev-table[i].level,3); 
    /*出栈取值到内存*/    
    gendo(sto,lev-table[i].level,table[i].adr);                         
    gendo(lod,lev-table[i].level,table[i].adr);
    gendo(lit,0,1);
    gendo(opr,0,2); /*栈顶值加*/
    getsymdo;
}
else if(sym==addadd) /*因子出现b:=++a类型*/
{
    getsymdo;
    if(sym==ident)
    {
        getsymdo;
        i=position(id,*ptx);
        if(i==0)
        {
            error(11);
        }
        else
        {
            if(table[i].kind==variable) /*变量*/
            {     
                /*先加后再用a*/
                /*先取值到栈顶*/
                gendo(lod,lev-table[i].level,table[i].adr);
                gendo(lit,0,1);/*将值入栈*/
                gendo(opr,0,2);/*加法,即+1,栈顶加次栈顶*/
                /*出栈取值到内存*/
                gendo(sto,lev-table[i].level,table[i].adr);
                /*取值到栈顶*/
                gendo(lod,lev-table[i].level,table[i].adr);
            }
        }
    }
}
else if(sym==subsub) /*因子出现b:=--a类型*/
{
    getsymdo;
    if(sym==ident)
    {
        getsymdo;
        i=position(id,*ptx);
        if(i==0)
        {
            error(11);
        }
        else
        {
            if(table[i].kind==variable) /*变量*/
            { 
                /*先减后再用a*/
                /*先取值到栈顶*/
                gendo(lod,lev-table[i].level,table[i].adr);
                gendo(lit,0,1); /*将值入栈*/
                gendo(opr,0,3); /*减法,即-1,栈顶减次栈顶*/
                /*出栈取值到内存*/
                gendo(sto,lev-table[i].level,table[i].adr);
                /*取值到栈顶*/
                gendo(lod,lev-table[i].level,table[i].adr); 
            }
        }
    }
}

5. 增加+=,-=,*=,/=运算

Step1: 在pl0.h中修改

    pl0.h中在enum symbol { } 符号枚举集中加入
    addequal,subequal, timeseql, slasheql,, 并更
    改符号的个数 symnum

Step2: 在getSym()函数中处理:

if(ch=='+')
{
    getchdo;
    if(ch=='=')
    {
        sym=addequal;
        getchdo;
    }
    else{
        sym=plus;
    }
}
else
{
    if(ch=='-')
    {
        getchdo;
        if(ch=='=')
        {
            sym=subequal;
            getchdo;
        }else{
            sym=minus;
        }
    }
    else 
    {
        if(ch=='*')
        {
            getchdo;
            if(ch=='=')
            {
                sym=timeseql;
                getchdo;
            }
            else
            {
                sym=times;
            }
        } 
        else
        {
            if(ch=='/')
            {
                getchdo;
                if(ch=='=')
                {
                    sym=slasheql;
                    getchdo;
                }
                getchdo;
            } else{
                sym=slash;
            }
        }else{
            /*当符号不满足上述条件时,全部按照单字符号处理*/
            sym=ssym[ch]; 
            if(sym!=period)
            {
                getchdo;
            }
        }
    }
}

Step3: 在语句处理函数中添加处理

else if(sym==addequal) /*检测到+=符号*/
{
    getsymdo;
    /*找到变量地址并将其值入栈*/
    gendo(lod,lev-table[i].level,table[i].adr); 
    if(sym==semicolon)
    {
        getsymdo;
        printf("+=后面直接跟了分号");
    }
    memcpy(nxtlev,fsys,sizeof(bool)* symnum);
    expressiondo(nxtlev,ptx,lev);
    gendo(opr,0,2);
    if(i!=0)
    {
        gendo(sto,lev-table[i].level,table[i].adr);
    }
}
else if(sym==subequal) /*检测到-=符号*/
{
    getsymdo;
    /*找到变量地址并将其值入栈*/
    gendo(lod,lev-table[i].level,table[i].adr);                          
    if(sym==semicolon)
    { 
        getsymdo;
    }
    memcpy(nxtlev,fsys,sizeof(bool)* symnum);
    expressiondo(nxtlev,ptx,lev);
    gendo(opr,0,3);
    if(i!=0)
    {
        gendo(sto,lev-table[i].level,table[i].adr);
    }
}
else if(sym==timeseql) /*检测到*=符号*/
{
    getsymdo;
    /*找到变量地址并将其值入栈*/
    gendo(lod,lev-table[i].level,table[i].adr);                        
    if(sym==semicolon)
    {
        getsymdo;
    }
    memcpy(nxtlev,fsys,sizeof(bool)* symnum);
    expressiondo(nxtlev,ptx,lev);
    gendo(opr,0,4);
    if(i!=0)
    { 
        gendo(sto,lev-table[i].level,table[i].adr);
    }
}
else if(sym==slasheql) /*检测到/=符号*/
{
    getsymdo;
     /*找到变量地址并将其值入栈*/
    gendo(lod,lev-table[i].level,table[i].adr);
    if(sym==semicolon)
    {
        getsymdo;
    }
    memcpy(nxtlev,fsys,sizeof(bool)* symnum);
    expressiondo(nxtlev,ptx,lev);
    gendo(opr,0,5);
    if(i!=0)
    {
        gendo(sto,lev-table[i].level,table[i].adr);
    }
}

您可能感兴趣的与本文相关的镜像

Seed-Coder-8B-Base

Seed-Coder-8B-Base

文本生成
Seed-Coder

Seed-Coder是一个功能强大、透明、参数高效的 8B 级开源代码模型系列,包括基础变体、指导变体和推理变体,由字节团队开源

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值