📄 pl0.cpp
字号:
/************ PL0.c *************/
/* pl0 compiler source code */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#include "set.h"
#include "pl0.h"
#include "set.cpp"
/*////////////////////////////////////////*/
/* print error message.*/
void error(int n)
{
int i;
printf(" ");
for (i = 1; i <= cc - 1; i++)
printf(" ");
printf("^\n");
printf("Error %3d: %s\n", n, err_msg[n]);
err++;
} /* error*/
/*//////////////////////////////////////////////////////////////////*/
void getch(void)
{
if (cc == ll)
{
if (feof(infile))
{
printf("\nPROGRAM COMPLETE\n");
exit(1);
}
ll = cc = 0;
printf("%5d ", cx);
while (!feof(infile) && (ch=getc(infile))!='\n')
{
printf("%c", ch);
line[++ll] = ch;
} /* while*/
printf("\n");
line[++ll] = ' ';
}
ch = line[++cc];
} /* getch*/
/*/////////////////////////////////*/
/* gets a symbol from input stream.*/
void getsym(void)
{
int i, k;
char a[MAXIDLEN + 1];
FILE* hbin;
char ichar='\n';
hbin = fopen("wdsyml.txt", "a");
while (isspace(ch))
getch();
if (isalpha(ch)!=0)
{ /* symbol is a reserved word or an identifier.*/
k = 0;
do
{
if (k < MAXIDLEN)
a[k++] = ch;
getch();
}while (isalnum(ch)!=0);//alpha or digit
a[k]=0;
strcpy(id, a);
word[0] = id;
i = NRW;
while (strcmp(id, word[i--]));
if (++i)
{
sym = wsym[i]; /* symbol is a reserved word*/
printf(" %s_wsym[%d]\n",id,i);
i=i+'0';
if(i>'9') i=i+7;
fwrite(id,1,k+1,hbin);
fwrite(&i,1,1,hbin);
fwrite(&ichar,1,1,hbin);
}
else
{//不是保留字,就是标识符
sym = SYM_IDENTIFIER; /* symbol is an identifier*/
//加入识别数组的symbol 处理处理数组
if(ch=='[')
{
sym=SYM_ARRAY;
getch();
}
//******************************
}
}
else if (isdigit(ch)!=0)
{ /* symbol is a number.*/
sym = SYM_NUMBER;
k = num = 0;
do
{
num = num * 10 + ch - '0';
k++;
getch();
}
while (isdigit(ch));
if (k > MAXNUMLEN)
error(25); /* The number is too great.*/
}
else if(ch == '=')
{
sym=SYM_EQU;
fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
getch();
}
else if(ch == ';')
{
sym=SYM_SEMICOLON;
fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
getch();
}
else if (ch == ':')
{
fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
getch();
if (ch == '=')
{
sym = SYM_BECOMES; /* :=*/
fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
getch();
}
else /*加入的 ':'*/
{
sym = SYM_MAOHAO;
fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
getch();
}
}
else if (ch == '>')
{ fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
getch();
if (ch == '=')
{
sym = SYM_GEQ; /* >=*/
fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
getch();
}
else
{
sym = SYM_GTR; /* >*/
fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
}
}
else if(ch=='[') { sym=SYM_LP; getch();} /*加入的'['*/
else if(ch==']') {sym=SYM_RP; getch();} /*加入的']'*/
else if(ch=='.')
{ getch();
if(ch=='.')
{
sym=SYM_TWOPOINT; /*加入的 '..'*/
getch();
}
else sym=SYM_PERIOD;
}
else if (ch == '<')
{
fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
getch();
if (ch == '=')
{
sym = SYM_LEQ; /* <=*/
fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
getch();
}
else if (ch == '>')
{
sym = SYM_NEQ; /* <>*/
fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
getch();
}
else
{
sym = SYM_LES; /* <*/
fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
}
}
else if(ch=='$') /* 加入的布尔运算符*/
{
sym=SYM_AND;
}
else if(ch=='|')
{
sym=SYM_OR;
}
else if(ch=='!') sym=SYM_NOT; /*布尔运算符*/
//加入以下部分为pl0的注释作准备
else if(ch=='(')
{ fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
getch();
if(ch=='*')
{
sym=SYM_EXPL1;
fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
getch();
}
else sym=SYM_LPAREN;
}
else if(ch=='*')
{ fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
getch();
if(ch==')')
{
sym=SYM_EXPL2;
fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
getch();
}
else sym=SYM_TIMES;
}
//***********************************//
else
{ /* other tokens*/
i = NSYM;
csym[0] = ch;
while (csym[i--] != ch);
if (++i)
{
sym = ssym[i];
fwrite(&ch,1,1,hbin);
fwrite(&ichar,1,1,hbin);
getch();
}
else
{
printf("Fatal Error: %c is an Unknown character.\n" ,ch );
exit(1);
}
}
} /* getsym*/
//******************加入的处理pl0注释的函数************************
void explanation()
{
while(ch!='*') getch();
getsym(); if(sym==SYM_EXPL1) explanation();
while(sym!=SYM_EXPL2)
{
while(ch!='*') getch();
if(ch=='*') getsym(); if(sym==SYM_EXPL1) explanation();
}
getsym(); if(sym==SYM_EXPL1) explanation();
}
/*//////////////////////////////////////////////////////////////////*/
/* generates (assembles) an instruction.*/
void gen(int x, int y, int z)
{
if (cx > CXMAX)
{
printf("Fatal Error: Program too long.\n");
exit(1);
}
code[cx].f = x;
code[cx].l = y;
code[cx++].a = z;
} /* gen*/
/*////////////////////////////////////////////////////////////////////*/
/* tests if error occurs and skips all symbols that do not belongs to s1 or s2.*/
void test(symset s1, symset s2, int n)
{
symset s;
if (! inset(sym, s1))
{
error(n);
s = uniteset(s1, s2);
while(! inset(sym, s))
getsym(); if(sym==SYM_EXPL1) explanation();
destroyset(s);
}
} /* test*/
/*////////////////////////////////////////////////////////////////////*/
int dx; /* data allocation index*/
/* enter object(constant, variable or procedre) into table.*/
void enter(int kind)
{
mask* mk;
////////////////////////////
char str[100];
char tempstr[10];
char nl='_', nl1='\n';
int strlength;
int i;
FILE* ifile;
if(!(ifile=fopen("ll1.txt","a"))){
printf("can't be opened!");
exit(1);
}
/////////////////////////////
tx++;
//printf("\n_%d_\n",tx);
strcpy(table[tx].name, id);
strcpy(str,table[tx].name);////////////////////
table[tx].kind = kind;
///////////////////////////////////
sprintf(tempstr,"%d",kind);
// printf("\n%s\n",str);
//strcat(str,&nl);
///////////////////////////////////
switch (kind)
{
case ID_CONSTANT:
if (num > MAXADDRESS)
{
error(25); /* The number is too great.*/
num = 0;
}
/// printf("\n%s\n",tempstr);
table[tx].value = num;
sprintf(tempstr,"%d",num);
printf("\n_%s_%d_%s\n",table[tx].name,table[tx].kind,tempstr);
break;
case ID_VARIABLE:
mk = (mask*) &table[tx];
mk->level = level;
sprintf(str,"%d",level);
//strcat(str,&nl);
mk->address = dx++;
sprintf(tempstr,"%d",dx);
//strcat(str,tempstr);
strlength=strlen(str);
i=0;
while((strlength--)>=0)
fwrite(&str[i++],sizeof(char),1,ifile);
printf("\n_%s_%d_%d_%d_\n",table[tx].name,table[tx].kind,mk->level,mk->address);
break;
case ID_PROCEDURE:
mk = (mask*) &table[tx];
mk->level = level;
sprintf(tempstr,"%d",level);
//strcat(str,&nl);
//strcat(str,tempstr);
strlength=strlen(str);
i=0;
while((strlength--)>=0)
fwrite(&str[i++],sizeof(char),1,ifile);
printf("\n_%s_%d_%d_%d_\n",table[tx].name,table[tx].kind,mk->level,mk->address);
break;
case ID_BOOL: //加入的布尔类型
mk =(mask *) &table[tx];
mk->level=level;
sprintf(tempstr,"%d",level);
//strcat(str,&nl);
//strcat(str,tempstr);
mk->address=dx++;
sprintf(tempstr,"%d",dx);
//strcat(str,tempstr);
strlength=strlen(str);
i=0;
while((strlength--)>=0)
fwrite(&str[i++],sizeof(char),1,ifile);
printf("\n_%s_%d_%d_%d_\n",table[tx].name,table[tx].kind,mk->level,mk->address);
break;
} /* switch*/
for(i=0;i<strlength;i++)
str[i]=0;
} /* enter*/
/*////////////////////////////////////////////////////////////////////*/
/* locates identifier in symbol table.*/
int position(char* id)
{
int i;
strcpy(table[0].name, id);
i = tx + 1;
while (strcmp(table[--i].name, id) != 0);
return i;
} /* position*/
/*/////////////////////////////////////////////////////////////////////*/
void constdeclaration()
{ /*常量的声明*/
if (sym == SYM_IDENTIFIER)
{
getsym(); if(sym==SYM_EXPL1) explanation();
if (sym == SYM_EQU )
{
getsym(); if(sym==SYM_EXPL1) explanation();
if (sym == SYM_NUMBER)
{
enter(ID_CONSTANT);
getsym(); if(sym==SYM_EXPL1) explanation();
}
else
{
error(2); //There must be a number to follow '='.
}
}
else
{
error(3); /* There must be an '=' to follow the identifier.*/
}
}
else error(4); /* There must be an identifier to follow 'const', 'var', or 'procedure'.*/
} /* constdeclaration*/
/*////////////////////////////////////////////////////////////////////*/
void vardeclaration(void)
{ /*标示符的声明 */
if (sym == SYM_IDENTIFIER)
{
enter(ID_VARIABLE);
getsym();
if(sym==SYM_EXPL1) explanation(); //处理pl0的注释
}
else error(4); /* There must be an identifier to follow 'const', 'var', or 'procedure'.*/
} /* vardeclaration*/
/************************************************/
void booldeclaration()
{
if(sym==SYM_IDENTIFIER)
{
enter(ID_BOOL);
getsym();
}
else error(4);
}
/***********************************************/
void arraydeclaration()
{
getsym();
if(sym==SYM_EXPL1) explanation(); //处理pl0的注释
if(sym==SYM_NUMBER)
{
m=num;
getsym();
if(sym==SYM_EXPL1) explanation(); //处理pl0的注释
if(sym==SYM_TWOPOINT)
{
getsym();
if(sym==SYM_EXPL1) explanation(); //处理pl0的注释
}
else error(30);
if(sym==SYM_NUMBER) n=num;
}
else error(26);
if(m>n) error(26);
else
{
for(;m<=n;m++) enter(ID_VARIABLE);
}
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
if(sym==SYM_RP)
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
}
else error(28);
}
void fdeclaration(void ) /*此函数是加入的pl0函数的处理过程*/
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
while(sym!=SYM_RPAREN)
{
if(sym==SYM_IDENTIFIER)
vardeclaration();
while (sym==SYM_COMMA)
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
if(sym!=SYM_IDENTIFIER)
vardeclaration();
} /*while*/
}
if(sym==SYM_RPAREN)
{
getsym();
if(sym==SYM_EXPL1) explanation(); //处理pl0的注释
}
else error(22);
}/*fdeclaration()*/
/*/////////////////////////////////////////////////////////////////////*/
void listcode(int from, int to)/*显示生成的代码函数*/
{
int i;
printf("\nGENERATE CODE AS FOLLOW:\n");
for (i = from; i < to; i++)
{
printf("%5d %s\t%d\t%d\n", i, mnemonic[code[i].f], code[i].l, code[i].a);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -