📄 pll.h
字号:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include"pl.h"
int init()//init correctly return 0,else return -1;
{
//cc=ll=0;
//ch=0;
/*fin=fopen("test.pl","r");
if(fin==NULL)
{
printf("can't read the source file!\n");
return -1;
}
fout=fopen("test.out","a+");
if(fout==NULL)
{
printf("can't create the out file!\n");
return -1;
}*/
linenum=0;
strcpy(&(keyword[0][0]),"begin");
strcpy(&(keyword[1][0]),"case");
strcpy(&(keyword[2][0]),"char");
strcpy(&(keyword[3][0]),"const");
strcpy(&(keyword[4][0]),"do");
strcpy(&(keyword[5][0]),"downto");
strcpy(&(keyword[6][0]),"else");
strcpy(&(keyword[7][0]),"end");
strcpy(&(keyword[8][0]),"for");
strcpy(&(keyword[9][0]),"function");
strcpy(&(keyword[10][0]),"if");
strcpy(&(keyword[11][0]),"integer");
strcpy(&(keyword[12][0]),"of");
strcpy(&(keyword[13][0]),"plchar");
strcpy(&(keyword[14][0]),"procedure");
strcpy(&(keyword[15][0]),"read");
strcpy(&(keyword[16][0]),"real");
strcpy(&(keyword[17][0]),"then");
strcpy(&(keyword[18][0]),"to");
strcpy(&(keyword[19][0]),"var");
strcpy(&(keyword[20][0]),"write");
//keyword symbol inint
//这个序列与上面keyword的次序是一致的,为了方便对应取值
keysym[0]=beginsym;
keysym[1]=casesym;
keysym[2]=charsym;
keysym[3]=constsym;
keysym[4]=dosym;
keysym[5]=downtosym;
keysym[6]=elsesym;
keysym[7]=endsym;
keysym[8]=forsym;
keysym[9]=functionsym;
keysym[10]=ifsym;
keysym[11]=integersym;
keysym[12]=ofsym;
keysym[13]=charsym;
keysym[14]=proceduresym;
keysym[15]=readsym;
keysym[16]=realsym;
keysym[17]=thensym;
keysym[18]=tosym;
keysym[19]=varsym;
keysym[20]=writesym;
////////////////
//下面主要用于在打印符号表时将中间码以字符串形式打出
//借鉴资料方法,设为一哈希表,简单
strcpy(&(charcode[lit][0]),"lit");
strcpy(&(charcode[opr][0]),"opr");
strcpy(&(charcode[lod][0]),"lod");
strcpy(&(charcode[sto][0]),"sto");
strcpy(&(charcode[cal][0]),"cal");
strcpy(&(charcode[inte][0]),"inte");
strcpy(&(charcode[jmp][0]),"jmp");
strcpy(&(charcode[jpc][0]),"jpc");
strcpy(&(charcode[red][0]),"red");
strcpy(&(charcode[wrt][0]),"wrt");
return 0;
}
//关于错误处理的几个函数,
//主要是关于集合的运算,为了减少错误扩散
//the first one :in_set
//判断是否在集合中
int in_set(int i,bool *set)
{
return set[i];
//如果在集合中,则返回true,1,否则返回false 0,
}
int set_combination(bool *set,bool *seta,bool *setb,int n)
{
//seta and setb have the same elements n
int i=0;
int varnum=0;
for(i=0;i<n;i++)
{
set[i]=seta[i]||setb[i];
}
return 0;
}
int set_substrack(bool *set,bool *seta,bool *setb,int n)
{
//n is the number of the setb, n of seta >=n
// pay attention
int i=0;
for(i=0;i<n;i++)
{
set[i]=seta[i]&&(!setb[i]);
}
return 0;
}
int set_multiple(bool *set,bool *seta,bool *setb,int n)
{
int i;
for(i=0;i<n;i++)
{
set[i]=seta[i]&&setb[i];
}
return 0;
}
int getch()
{
if(cc==ll)
{
if(ch==EOF)
{
printf("To the end of the souce file!");
return -1;
}
ll=0;
cc=0;
ch=' ';
while(ch!='\n')
{
if(EOF==fscanf(fin,"%c",&ch))
{
line[ll]='\0';
break;
}
// printf("%c",ch);
// fprintf(fout,"%c",ch);//write to the file out in order to compare
line[ll]=ch;//add to the line;
ll++;//add the length of the read line
}
//printf("\n");
// fprintf(fout,"%c","\n");
}
ch=line[cc];//read from the line ,every time read a char;
cc++;//move the point forward;
return 0;//return correctly
}
void close()
{
if(fin!=NULL)
fclose(fin);
if(fout!=NULL)
fclose(fout);
if(ftab!=NULL)
fclose(ftab);
if(fcode!=NULL)
fclose(fcode);
}
void printerr(int index)
{
printf("Error %d :",nerror++);
printf("in the line %d ",linenum);
printf(" int the col %d ",cc-1);
switch(index)
{
case 0:printf("the error is :此处应有';'");break;
case 1:printf("the error is :常量定义缺少'='");break;
case 2:printf("the error is :实数型定义错误,少'.'");break;
case 3:printf("the error is :字符定义错误,少'''");break;
case 4:printf("the error is :无此类型.");break;
case 5:printf("the error is :标识符后缺少':'");break;
case 6:printf("the error is :分程序后少';break;'");break;
case 7:printf("the error is :缺少')'");break;
case 8:printf("the error is :赋值语句有误,缺少':='");break;
case 9:printf("the error is :多余'*'");break;
case 10:printf("the error is :没有then与之匹配");break;
case 11:printf("the error is :缺少'('");break;
case 12:printf("the error is :没有downto或to与之匹配.");break;
case 13:printf("the error is :缺少'end'");break;
case 14:printf("the error is :该数字位数过长,超出系统限制.");break;
case 15:printf("the error is :符号定义错误,是否为':='");break;
case 16:printf("the error is :虚拟机代码过长,超出系统限制.");break;
case 17:printf("the error is :嵌套层过深,超出系统限制.");break;
case 18:printf("the error is :过程定义错误,无标识符.");break;
case 19:printf("the error is :常量定义错误,无标识符.");break;
case 20:printf("the error is :常量定义错误,其后类型不正确.");break;
case 21:printf("the error is :变量定义错误.");break;
case 22:printf("the error is :字符定义错误.");break;
case 23:printf("the error is :字符串定义错误.");break;
case 24:printf("the error is :地址越界.");break;
case 25:printf("the error is :未声明.");break;
case 26:printf("the error is :赋值语句有误,该对象非变量.");break;
case 27:printf("the error is :读语句有误.");break;
case 28:printf("the error is :read应该对已声明的变量进行操作.");break;
case 29:printf("the error is :write语句定义错误.");break;
case 30:printf("the error is :标识符定义错误.");break;
case 31:printf("the error is :过程名应为标识符.");break;
case 32:printf("the error is :标识符定义错误,无')'");break;
case 33:printf("the error is :条件语句中无正确关系运算符.");break;
case 34:printf("the error is :引用错误,无实参.");break;
case 35:printf("the error is :实参类型不符.");break;
case 36:printf("the error is :不能直接调用函数.");break;
case 37:printf("the error is :前后类型不符.");break;
case 38:printf("the error is :函数名定义应为标志符.");break;
case 39:printf("the error is :函数定义后应有:.");break;
case 40:printf("the error is :for后应为标识符.");break;
case 41:printf("the error is :无:=,标识符应初始化.");break;
case 42:printf("the error is :无与之匹配的do语句.");break;
case 43:printf("the error is :case语句定义错误.");break;
case 44:printf("the error is :无:.");break;
case 45:printf("the error is :case语句末尾无end与之匹配.");break;
case 46:printf("the error is :函数无返回值.");break;
}
printf("\n");
}
int getsym()
{
int i,j,k,sw;
i=0;
j=0;
k=0;
sw=0;
//char a[maxlen];//has been defined in the pl.h
while(ch==' '||ch==10||ch==13||ch==9)
{
if(ch=='\n')// a marco ,which is defined in pl.h if((getch()==0)return 0 else return -1;
linenum++;
getchdo; // becuase this function is used always,so it's a convinent way
}
if(ch>='a'&&ch<='z')
{
k=0;
do
{
if(k<maxlen)// <10
{
a[k]=ch;// a is buffer to keep the word
k++;
}
getchdo;
}while(ch>='a'&&ch<='z'||ch>='0'&&ch<='9');
a[k]=0;//make the last \0
strcpy(id,a);
//binary search
/*i=0;
j=20;
do
{
printf("get into the loop %d\n",i);
// now the k is nouse .so can use it again don't have to need a new variable
k=(i+j)/2;
if(strcmp(id,keyword[k])<0)
{
j=k-1;//the first half;
}
if(strcmp(id,keyword[k])>0)
{
i=k+1;
}
else
{
sym=keysym[k];//第一次匹配成功
break;
}
}while(i<=j);
if(i<=j)
{
sym=keysym[k];
}
else
{
sym=ident;//是一个标识符
}*/
for(i=0;i<21;i++)
{
if(strcmp(id,keyword[i])==0)
{
sym=keysym[i];
break;
}
}
if(i==21)
sym=ident;
}
//check if it is a number
else if(ch>='0'&&ch<='9')
{
k=0;
num=0;
fnum=0.;
m=0.1;
//init the value
sym=integersym;
//标识符为数字
do
{
num=10*num+(ch-'0');
k++;
getchdo;
if(ch=='.')
{
getchdo;//说明此处为实数
while(ch>='0'&&ch<='9')
{
sym=realsym;//changer it to real;
fnum=num+m*(ch-'0');
m=m/10;
getchdo;
}
}
}while(ch>='0'&&ch<='9');
k++;
if(k>nummax)
{
printerr(14);//error 14:位数过长
}
}
else if(ch=='=')
{
//printf("here\n");
sym=eql;
getchdo;
}
else if(ch==':')
{
getchdo;
if(ch=='=')
//if it is :=
{
sym=assign;
getchdo;
}
else
{
sym=colon;
// printerr(15);
//don't need to getchdo;
}
}
else if(ch=='<')
{
getchdo;
if(ch=='=')
{
sym=leql;
//it is the <=
getchdo;
}
else if(ch=='>')
{
sym=neql;
getchdo;
}
else
{
sym=less;
//pay attention ,here don't need to read again
}
}
else if(ch=='>')
{
getchdo;
if(ch=='=')
{
sym=geql;
getchdo;
}
else
{
sym=grt;
}
}
else if(ch=='+')
{
sym=plus;
getchdo;
}
else if(ch=='-')
{
sym=minus;
getchdo;
}
else if(ch=='*')
{
sym=multi;
getchdo;
}
else if(ch=='/')
{
sym=divid;
getchdo;
}
else if(ch=='(')
{
sym=lparen;
getchdo;
}
else if(ch==')')
{
sym=rparen;
getchdo;
}
else if(ch==39)//对字符处理
{
//sym=squot;
//getchdo;
getchdo;//get the next;
if(ch>='0'||ch<='9'||ch>='a'||ch<='z')
{
//为合法字符
sym=charsym;//vip
char_buffer=ch;
//printf("the char_buffer is :%c\n",char_buffer);
getchdo;
if(ch!=39)//vip
printerr(3);
else
getchdo;//vip
}
else
printerr(22);
}
else if(ch==',')
{
sym=comma;
getchdo;
}
else if(ch==';')
{
sym=semicolon;
getchdo;
}
else if(ch=='"')
{
//sym=quote;
//getchdo;
getchdo;
if(ch>='0'||ch<='9'||ch>='a'||ch<='z')
{
while(ch!='"'&&sw<19)
{
string_buffer[sw++]=ch;
getchdo;
}
if(sw<=19)
string_buffer[sw]='\0';
if(ch!='"')
{
printerr(23);
//return -1;//vip
}
else
{
sym=stringsym;
getchdo;
}
}
else
printerr(23);
}
else if(ch=='.')
{
getchdo;
if(ch==0)
{
sym=period;
printf("To Source End!\n");
}
}
return 0;
}
int genecode(enum vmcode x,int y,struct para p,enum typeset type)//generate the code of he vm
{
if(cx>=500)
{
printerr(16);
return -1;
}
code[cx].vc=x;
code[cx].l=y;
//code[cx].a=z;
if(type==integer)
{
code[cx].a=p.i;
code[cx].flag=0;//0 is the integer
}
if(type==plchar)
{
code[cx].c=p.c;
code[cx].flag=1;
}//1 means the char
if(type==real)
{
code[cx].d=p.d;
code[cx].flag=2;
}
cx++;
return 0;
}
int test(bool *seta,bool *setb,int n)
{
if(! in_set(sym,seta))
{
printerr(4);
while((!in_set(sym,seta))&&(!in_set(sym,setb)))
{
getsymdo;
}
}
return 0;
}
int senantic(int lev,int tx,bool * fsys) //block function
{
//pay attention to the firstsym
//test the right word
int i=0;
int varnum=0;
int j=0;
int dx;
//相对地址
int tx0;
int cx0;
int rex;//return
bool nextlev[keynum];
bool statement_firstset[keynum];
bool block_firstset[keynum];
for(j=0;j<keynum;j++)
statement_firstset[j]=false;
for(j=0;j<keynum;j++)
block_firstset[keynum]=false;
statement_firstset[beginsym]=true;
statement_firstset[ifsym]=true;
statement_firstset[forsym]=true;
statement_firstset[casesym]=true;
block_firstset[constsym]=true;
block_firstset[varsym]=true;
block_firstset[proceduresym]=true;
block_firstset[functionsym]=true;
//
dx=3;//vip
tx0=tx;//recode the init position
table[tx].adr=cx;
pa.i=0;
//printf("have get to here.\n");
do_genecode(jmp,0,pa,integer);////
//getsymdo;
//sym=constsym;
//printf("tx=%d\n",tx);
if(lev>maxlev)
//overload the level
{
printerr(17);
return -1;
}
do//
{
if(sym==constsym)
//const
{
getsymdo;
do
{
//常量处理函数
//递归调用
do_deal_constant(&tx,lev,&dx);
while(sym==comma)
//define repeatly
{
getsymdo;
//常量处理
//调用
do_deal_constant(&tx,lev,&dx);
}
if(sym==semicolon)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -