.. . .. . .
k=0; num=0; sym=number; do{ num=10*num+ch-'0'; k++; getchdo; }while(ch>='0'&&ch<='9'); /*获取数字的值*/ k--; if(k>nmax) { error(30); } } else { if(ch==':') /*检测赋值符号*/ { getchdo; if(ch=='=') { sym=becomes; getchdo; } else { sym=nul; /*不能识别的符号*/ } } else { if(ch=='<') /*检测小于或小于等于符号*/ { getchdo; if(ch=='=') { sym=leq; getchdo; } else { sym=lss; } }
S. . . . . ..
.. . .. . .
else { if(ch=='>') /*检测大于或大于等于符号*/ { getchdo; if(ch=='=') { sym=geq; getchdo; } else { sym=gtr; } } else { sym=ssym[ch];/* 当符号不满足上述条件时,全部按照单字符号处理*/ //getchdo; //richard if(sym!=period) { getchdo; } //end richard } } } } } return 0; } /*
*生成虚拟机代码 *
*x:instruction.f; *y:instruction.l; *z:instruction.a; */
int gen(enum fct x,int y,int z) { if(cx>=cxmax) {
S. . . . . ..
.. . .. . .
printf(\程序过长*/ return -1; } code[cx].f=x; code[cx].l=y; code[cx].a=z; cx++; return 0; } /*
*测试当前符号是否合法 *
*在某一部分(如一条语句,一个表达式)将要结束时时我们希望下一个符号属于某集合 *(该部分的后跟符号) test 负责这项检测,并且负责当检测不通过时的补救措施
*程序在需要检测时指定当前需要的符号集合和补救用的集合(如之前未完成部分的后跟 *符号),以及不通过时的错误号 *
*S1:我们需要的符号
*s2:如果不是我们需要的,则需要一个补救用的集合 *n:错误号 */
int test(bool* s1,bool* s2,int n) {
if(! inset(sym,s1)) { error(n); /*当检测不通过时,不停获取符号,直到它属于需要的集合或补救的集合*/ while((! inset(sym,s1))&&(! inset(sym,s2))) { getsymdo; } }
return 0; } /*
*编译程序主体 *
*lev:当前分程序所在层 *tx:名字表当前尾指针
*fsys:当前模块后跟符号集合 */
int block(int lev,int tx,bool* fsys)
S. . . . . ..
.. . .. . .
{
int i;
int dx; /*名字分配到的相对地址*/ int tx0; /*保留初始tx*/ int cx0; /*保留初始cx*/
bool nxtlev[symnum]; /*在下级函数的参数中,符号集合均为值参,但由于使用数组
实现,传递进来的是指针,为防止下级函数改变上级函数的
集合,开辟新的空间传递给下级函数*/ dx=3;
tx0=tx; /*记录本层名字的初始位置*/ table[tx].adr=cx; gendo(jmp,0,0); if(lev > levmax) { error(32); } do{
if(sym==constsym) /*收到常量声明符号,开始处理常量声明*/ { getsymdo; do{
constdeclarationdo(&tx,lev,&dx); /*dx的值会被constdeclaration改变,使用
指针*/ while(sym==comma) {
getsymdo;
constdeclarationdo(&tx,lev,&dx); }
if(sym==semicolon) {
getsymdo; } else { error(5); /*漏掉了逗号或者分号*/ } }while(sym==ident); } if(sym==varsym)/*收到变量声名符号,开始处理变量声名*/ { getsymdo;
S. . . . . ..
.. . .. . .
do{ vardeclarationdo(&tx,lev,&dx); while(sym==comma) { getsymdo; vardeclarationdo(&tx,lev,&dx); } if(sym==semicolon) { getsymdo; } else { error(5); } }while(sym==ident); } while(sym==procsym)/*收到过程声名符号,开始处理过程声名*/ { getsymdo; if(sym==ident) { enter(procedur,&tx,lev,&dx);/*记录过程名字*/ getsymdo; } else { error(4);/*procedure后应为标识符*/ } if(sym==semicolon) { getsymdo; } else { error(5);/*漏掉了分号*/ } memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[semicolon]=true; if(-1==block(lev+1,tx,nxtlev)) { return -1;/*递归调用*/ }
if(sym==semicolon)
S. . . . . ..