📄 pl0complier.cpp
字号:
#include <stdio.h>
#include <set>
#include <string>
#include <iostream>
#include <iostream>
#include <vector>
#define WIRTH_ZYC_
using namespace std;
const int norw=13;
const int txmax=100;
const int al=10;
const int nmax=14;
const int amax=2047;
const int levmax=3;
const int cxmax=20000;
const int lineLength=82;
typedef enum {NUL,IDENT,NUMBER,PLUS,MINUS,TIMES,SLASH,ODDSYM,EQL,NEQ,LSS,LEQ,GTR,GEQ,LPAREN,RPAREN,COMMA,SEMICOLON,PERIOD,BECOMES,BEGINSYM,ENDSYM,IFSYM,THENSYM,WHILESYM,WRITESYM,READSYM,DOSYM,CALLSYM,CONSTSYM,VARSYM,PROCSYM} symbol;
typedef char alfa[al+1];
typedef enum{CONSTANT,VARIABLE,PROCEDURE}obj0;
typedef enum {LIT,OPR,LOD,STO,CAL,INT,JMP,JPC} fct;
typedef set<symbol> symset;
struct instruction{
fct f;
int l;
int a;
};
typedef struct{
alfa name;
obj0 kind;
union {
struct{int level,adr,size;}inOther;
int val;
}other;
} Table;
void SaveCode();
void listcode(int cx0);
void error(int n);
void getsym();
void getch();
void gen(fct x,int y,int z);
void test(symset s1,symset s2,int n);
void block(int lev,int tx,symset fsys);
void enter(obj0 k,int &tx,int &dx,int lev);
int position(alfa id,int tx);
void constdeclaration(int&tx,int&dx,int lev);
void vardeclaration(int&tx,int&dx,int lev);
void factor(symset fsys,int tx,int lev);
void term(symset fsys,int tx,int lev);
void expression(symset fsys,int tx,int lev);
void condition(symset fsys,int tx,int lev);
void statement(symset fsys,int tx,int lev);
int base(int l,int b,int s[]);
void interpret();
bool listswitch,sourceEnd;
char ch;
symbol sym;
alfa id;
int num;
int cc;
int ll;
int kk,err;
int cx;
int codeNo;
char line[lineLength];
vector<string> errorString;
alfa a;
instruction code[cxmax+1];
alfa word[norw+1];
symbol wsym[norw+1];
symbol ssym[100];
char mnemonic[8][6];
symset declbegsys,statbegsys,facbegsys;
Table table[txmax+1];
FILE* fin,*fout;
string errStr[]={" ",
"error 0001: write = as := ", "error 0019: need a num after = ",
"error 0002: lose = after identifier", "error 0020: need a identifier after const,var,procedure ",
"error 0003: lose , or ; ", "error 0021: error symbol",
"error 0004: error symbol", "error 0022: error symbol",
"error 0005: lose . ", "error 0023: lose ; ",
"error 0006: undeclar identifier ", "error 0024: must be defined as variable",
"error 0007: the symbol must be :=", "error 0025: need an identifier after call ",
"error 0008: call's property should be process", "error 0026: be lack for then",
"error 0009: need end or ;", "error 0027: need while",
"error 0010: uncorect identifier", "error 0028: it shuold be operator",
"error 0011: shuold not be process", "error 0029: lose ) ",
"error 0012: unreferenced identifier", "error 0030: can not be this identifier",
"error 0013: wrong end ", "error 0031: shuod not end here ",
"error 0014: ","error 0015: ","error 0016: ","error 0017: ",
"error 0018: over flow", "error 0032: err read "
};
void error(int n)
{
char s[10];
sprintf(s,"第 %d 行出错:",codeNo);
errorString.push_back(s+errStr[n]);
err= err+1;//error count
}
void getch()
{
if(cc==ll)
{
if(feof(fin))
{
if(sym!=PERIOD)
error(25);
sourceEnd=true;
return;
}
cc= 0;
fgets(line,lineLength,fin);
codeNo++;
ll=strlen(line);
if(line[ll-1]==10)ll--;
}
ch= line[cc];
cc= cc+1;
}
void getsym()
{
if(sourceEnd)
return;
int i,j,k;
while (ch ==' '||ch==9)
getch();
if(isalpha(ch))
{
k=0;
memset(a,0,al+1);
do{
if (k < al)
{
a[k]= ch;
k= k+1;
}
getch();
if(sourceEnd)
return;
}while(isalpha(ch)||isdigit(ch));
if(k >= kk)
kk= k;
else
{
do{
a[kk]= ' ';
kk= kk-1;
}while(kk > k);
}
strcpy(id,a);
i= 1;
j= norw;
do{
k= (i+j) / 2;
if(strcmp(id, word[k])<=0)
j= k-1;
if(strcmp(id,word[k])>=0)
i= k+1;
}while(i<=j);
if(i-1 > j)
sym= wsym[k];
else
sym= IDENT;
}
else if(isdigit(ch))
{
k= 0;
num= 0;
sym= NUMBER;
do{
num= 10 * num+ch-'0';
k= k+1;
getch();
}while(isdigit(ch));
if(k > nmax)
error(30);
}
else if (ch == ':')
{
getch();
if( ch== '=')
{
sym= BECOMES;
getch();
}
else
sym= NUL;
}
else if(ch == '<')
{
getch();
if (ch== '=')
{
sym= LEQ;
getch();
}
else if(ch=='>')
{
sym=NEQ;
getch();
}
else
sym= LSS;
}
else if (ch == '>')
{
getch();
if( ch == '=')
{
sym= GEQ;
getch();
}
else
sym= GTR;
}
else
{
sym= ssym[ch];
getch();
}
}
void gen(fct x,int y,int z)
{
if (cx > cxmax)
{
cout<<"Program too long\n";
return;
}
code[cx].f= x;
code[cx].l= y;
code[cx].a= z;
cx= cx+1;
}
void test(symset s1,symset s2,int n)
{
if(sourceEnd)return;
if (s1.find(sym)==s1.end())
{
error(n);
symset::iterator it;
for(it=s2.begin();it!=s2.end();it++)
s1.insert(*it);
while (s1.find(sym)==s1.end())
getsym();
}
}
void enter(obj0 k,int &tx,int &dx,int lev)
{
tx= tx+1;
strcpy(table[tx].name,id);
table[tx].kind=k;
switch(k)
{
case CONSTANT:
if(num>amax)
{
error(31);
num=0;
}
table[tx].other.val=num;
break;
case VARIABLE:
table[tx].other.inOther.level=lev;
table[tx].other.inOther.adr=dx;
dx++;
break;
case PROCEDURE:
table[tx].other.inOther.level=lev;
break;
}
}
int position(alfa id,int tx)
{
int i;
strcpy(table[0].name, id);
i= tx;
while (strcmp(table[i].name,id)!=0)i--;
return i;
}
void constdeclaration(int&tx,int&dx,int lev)
{
if(sym = IDENT)
{
getsym();
if(sym>=EQL&&sym<=BECOMES)
{
if( sym ==BECOMES)
error(1);
getsym();
if( sym == NUMBER)
{
enter(CONSTANT,tx,dx,lev);
getsym();
}
else
error(2);
}
else
error(3);
}
else
error(4);
}
void vardeclaration(int&tx,int&dx,int lev)
{
if( sym == IDENT)
{
enter(VARIABLE,tx,dx,lev);
getsym();
}
else
error(4);
}
void listcode(int cx0)
{
int i;
if(listswitch)
for (i= cx0;i<cx;i++)
cout<<" "<<i<<" "<<mnemonic[code[i].f]
<<" "<<code[i].l<<" "<<code[i].a<<endl;
}
void factor(symset fsys,int tx,int lev)
{
int i;
test(facbegsys,fsys,24);
while(facbegsys.find(sym)!=facbegsys.end())
{
if( sym ==IDENT)
{
i= position(id,tx);
if( i == 0)
error(11);
else
switch(table[i].kind)
{
case CONSTANT:
gen(LIT,0,table[i].other.val);
break;
case VARIABLE:
gen(LOD,lev-table[i].other.inOther.level,table[i].other.inOther.adr);
break;
case PROCEDURE:
error(21);
break;
}
getsym();
}
else if (sym ==NUMBER)
{
if (num>amax)
{
error(31);
num= 0;
}
gen(LIT,0,num);
getsym();
}
else if( sym ==LPAREN)
{
getsym();
symset tmp=fsys;
tmp.insert(RPAREN);
expression(tmp,tx,lev);
if (sym == RPAREN)
getsym();
else
error(22);
}
test(fsys,facbegsys,23);
}
}
void term(symset fsys,int tx,int lev)
{
if(sourceEnd)
return;
symbol mulop;
symset tmp=fsys;
for(int t=TIMES;t<=SLASH;t++)
tmp.insert((symbol)t);
factor(tmp,tx,lev);
while( sym>=TIMES && sym<=SLASH)
{
mulop= sym;
getsym();
factor(tmp,tx,lev);
if (mulop ==TIMES)
gen(OPR,0,4);
else
gen(OPR,0,5);
}
}
void expression(symset fsys,int tx,int lev)
{
symbol addop;
symset tmp=fsys;
for(int t=PLUS;t<=MINUS;t++)
tmp.insert((symbol)t);
if( sym>=PLUS&&sym<=MINUS)
{
addop= sym;
getsym();
term(tmp,tx,lev);
if( addop ==MINUS)
gen(OPR,0,1);
}
else
term(tmp,tx,lev);
while (sym >=PLUS&&sym<=MINUS)
{
addop= sym;
getsym();
term(tmp,tx,lev);
if (addop ==PLUS)
gen(OPR,0,2);
else
gen(OPR,0,3);
}
}
void condition(symset fsys,int tx,int lev)
{
symbol relop;
symset tmp=fsys;
tmp.insert(EQL),tmp.insert(NEQ),tmp.insert(LSS),tmp.insert(LEQ),tmp.insert(GTR),tmp.insert(GEQ);
if( sym ==ODDSYM)
{
getsym();
expression(fsys,tx,lev);
gen(OPR,0,6);
}
else
{
expression(tmp,tx,lev);
if(tmp.find(sym)==tmp.end())
error(20);
else
{
relop= sym;
getsym();
expression(fsys,tx,lev);
switch(relop)
{
case EQL: gen(OPR,0,8);
break;
case NEQ: gen(OPR,0,9);
break;
case LSS: gen(OPR,0,10);
break;
case GEQ: gen(OPR,0,11);
break;
case GTR: gen(OPR,0,12);
break;
case LEQ: gen(OPR,0,13);
break;
}
}
}
}
void statement(symset fsys,int tx,int lev)
{
if(sourceEnd)
return;
int i,cx1,cx2;
if(sym ==IDENT)
{
i= position(id,tx);
if (i == 0)
error(11);
else if (table[i].kind!=VARIABLE)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -