读书人

哪位大哥帮帮忙编译原理的实验pl0的

发布时间: 2012-06-19 14:45:20 作者: rapoo

哪位大哥帮帮忙,编译原理的实验pl0的程序
1、分析原来的IF语句的BNF


<条件语句>::=IF <条件>THEN <语句>


和扩展后的IF语句的BNF


<条件语句>::=IF <条件>THEN <语句>[ELSE <语句>]

在原有的程序上把if----then 扩展为if then else(不是改程序里的if then,而是实现能分析if then else,原有的只能分析if then)



2、pl0的一维数组扩充
分析BNF


<数组变量声明>::=<标识符> ( <下界>: <上界>)


<数组变量引用>::= <标识符> ( <表达式> )


在实现上的要求



找到应该修改的地方,进行修改和扩充


[解决办法]
下面是代码生成与解释执行部分:

C/C++ code
//增加两个虚拟机指令 lda, sta, 分别用来从数组中取数和存到数组中//数组元素的访问和存储,是将()后的当成表达式,先处理,得到元素的索引,放在栈顶//最后根据数组的首地址,得到某个元素的地址#define arraycoefdo(a,b,c)  if(-1==arraycoef(a,b,c)) return -1/** 数组元素索引计算与“虚拟机”生成*/int arraycoef(bool *fsys, int *ptx, int lev){    bool nxtlev[symnum];    int i = position(id, *ptx);    getsymdo;    if (sym == lparen) /* 索引是括号内的表达式 */    {        getsymdo;        memcpy(nxtlev, fsys, sizeof(bool)*symnum);        nxtlev[rparen] = true;        expressiondo(nxtlev, ptx, lev);        if (sym == rparen)        {            gendo(lit, 0, table[i].data);            gendo(opr, 0, 3);   /* 系数修正,减去下界的值 */            return 0;        }        else        {            error_no(22);  /* 缺少右括号 */        }    }    else    {        error_no(51);  /* 数组访问错误 */    }    return -1;}//表达式中访问元素:int factor(bool* fsys, int* ptx, int lev){   ...   if(sym == ident)   {    ...    case variable:        gendo(lod, lev-table[i].level, table[i].adr);        break;    case array:     /* 名字为数组名 */        arraycoefdo(fsys, ptx, lev);        gendo(lda, lev-table[i].level, table[i].adr);   /* 找到变量地址并将其值入栈 */        break;   }}//将结果存到表达式中,数组处理仅仅在获得左值时与普通变量不同int statement(bool* fsys, int* ptx, int lev){    int i, cx1, cx2;    bool nxtlev[symnum];    if (sym == ident)   /* 准备按照赋值语句处理 */    {        i = position(id, *ptx);        if (i == 0)        {            error_no(11);  /* 变量未找到 */        }        else        {            enum fct fct1 = sto;            switch(table[i].kind)            {            case array:                arraycoefdo(fsys, ptx, lev);                fct1 = sta;  /* 数组保存,要多读一个栈 */                /* go through */            case variable:                {                    getsymdo;                    if(sym == becomes)                    {                        getsymdo;                    }                    else                    {                        error_no(13);  /* 没有检测到赋值符号 */                    }                    memcpy(nxtlev, fsys, sizeof(bool)*symnum);                    expressiondo(nxtlev, ptx, lev); /* 处理赋值符号右侧表达式 */                    if(i != 0)                    {                        /* expression将执行一系列指令,但最终结果将会保存在栈顶,执行sto命令完成赋值 */                        gendo(fct1, lev-table[i].level, table[i].adr);                    }                }                break;            default:                error_no(12);  /* 赋值语句格式错误 */                i = 0;                break;            }//switch        }//if (i == 0)    }    else    {    ...    }    return 0;}////以下是虚拟机解释增加的两个虚拟机代码的处理////刚刚想了下,其实应该可以不增加lda和sta,利用opr定义类似的操作就可以了void interpret(){   ...   case lda:   /* 数组元素访问,当前栈顶为元素索引,执行后,栈顶变成元素的值 */      s[t-1] = s[base(i.l,s,b) + i.a + s[t-1]];      break;   case sta:   /* 栈顶的值存到数组中,索引为栈顶之下的那个值 */      t-=2;      s[base(i.l,s,b) + i.a + s[t]] = s[t+1];      break;   ...} 

读书人网 >C语言

热点推荐