?? pl0.java
字號:
package pl0Compiler;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Scanner;
public class Pl0 {
final int tableMax =100;
final int numLength = 14;
final int identLength =10;
final int levMax =3;
final int codeMax=200;
final int stackSize=500;
final int symnum=32;
enum Symbol{
nul, ident, number, plus, minus,
multiply, divide, oddsym, eql, neq,
lss, leq, gtr, geq, lparen,
rparen, comma, semicolon,period, assign,
beginsym, endsym, ifsym, thensym, whilesym,
writesym, readsym, dosym, callsym, constsym,
varsym, proceduresym
};
enum Object{
constant,
variable,
procedure,
};
enum Function{
lit, opr, lod, sto, cal, inte, jmp, jpc,
};
class Instruction
{
Function f;
int l;//層差,標識符引用層減去定義層
int a;
};
class TableStruct
{
String name;
Object kind;
int val;
int level;
int adr;
int size;
};
char ch;
Symbol sym;
String token="";
int num;
int cc,ll;
int cx;
char[] line=new char[81];
Instruction[] code=new Instruction[codeMax];
Symbol[] kwsym={Symbol.beginsym,Symbol.callsym,Symbol.constsym,Symbol.dosym,Symbol.endsym,Symbol.ifsym,
Symbol.oddsym,Symbol.proceduresym,Symbol.readsym,Symbol.thensym,Symbol.varsym,Symbol.whilesym,Symbol.writesym};
TableStruct[] table=new TableStruct[tableMax];
File SourceFile;
RandomAccessFile randomAFile;
String SourceFileName="E:/三年級課程/編譯原理/編譯原理實驗/pl02.txt";//"E:/三年級課程/編譯原理/PL0源碼C語言版/pl0.txt";
int err;
public static void main(String args[])
{
Pl0 pl=new Pl0();
pl.init();
pl.getsym();
pl.block(0,0);
if(pl.sym!=Symbol.period)
pl.error(9);
System.out.println("The ultimate code is following:");
pl.listcode(0);
if(pl.err==0)
pl.interpret();
else
System.out.printf("Errors in pl/0 program");
}
void init()
{
SourceFile = new File(SourceFileName);
try {
randomAFile = new RandomAccessFile(this.SourceFile, "r");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
for(int j=0;j<table.length;j++)
table[j]=new TableStruct();
for(int j=0;j<code.length;j++)
code[j]=new Instruction();
err=0;
cc=0;
cx=0;
ll=0;
ch=' ';
}
void error(int n)
{
System.out.printf("----------%c\n",ch);
System.out.println("**********"+n);
err++;
}
String contact(String token, char ch) {
token= token + String.valueOf(ch);
return token;
}
void getch()
{ if(cc==ll){
ll=0;
cc=0;
System.out.printf("%d ",cx );
ch=' ';
while(ch!=10){
try{
ch=(char) randomAFile.readByte();
} catch (IOException e) {
line[ll]=0;
break;
}
System.out.printf("%c",ch);
line[ll]=ch;
ll++;
}
System.out.printf("\n");
}
ch=line[cc];
cc++;
}
void getsym()
{
while(ch==' '|(byte)ch==13|(byte)ch==10|ch==9)
getch();
int i,k;
if(ch>='a'&&ch<='z')
{ String s="";
k=0;
do{
if(k<identLength)
{ s=contact(s,ch);
k++;
}
getch();
}while(ch>='a'&&ch<='z'||ch>='0'&&ch<='9');
token=s;
s=s+"sym";
for(i=0;i<kwsym.length;i++){
if(s.equalsIgnoreCase(kwsym[i].name()))
{ sym=kwsym[i];
break;
}
}
if(i==kwsym.length)
sym=Symbol.ident;
}
else if(ch>='0'&&ch<='9')
{ String s="";
num=0;
sym=Symbol.number;
do{
s=contact(s,ch);
getch();
}while(ch>='0'&&ch<='9');
num=Integer.parseInt(s);
if(s.length()>numLength)
{
error(30);
}
}
else if(ch==':')
{
getch();
if(ch=='=')
{
sym=Symbol.assign;
getch();
}
else
sym=Symbol.nul;
}
else if(ch=='<')
{ getch();
if(ch=='=')
{
sym=Symbol.leq;
getch();
}
else sym=Symbol.lss;
}
else if(ch=='>')
{
getch();
if(ch=='=')
{
sym=Symbol.geq;
getch();
}
else
{
sym=Symbol.gtr;
}
}
else
{ switch(ch){
case '+':
sym=Symbol.plus;
break;
case '-':
sym=Symbol.minus;
break;
case '*':
sym=Symbol.multiply;
break;
case '/':
sym=Symbol.divide;
break;
case '(':
sym=Symbol.lparen;
break;
case ')':
sym=Symbol.rparen;
break;
case '=':
sym=Symbol.eql;
break;
case ',':
sym=Symbol.comma;
break;
case '.':
sym=Symbol.period;
break;
case '#':
sym=Symbol.neq;
break;
case ';':
sym=Symbol.semicolon;
break;
}
if(sym!=Symbol.period)
getch();
}
}
void gen(Function x,int y,int z)
{
if(cx>=codeMax)
{
System.out.printf("Program is too long!");
System.exit(0);
}
code[cx].f=x;
code[cx].l=y;
code[cx].a=z;
cx++;
}
void block(int lev,int tx)
{
int i;
int dx; //名字分配到的相對地址
int tx0; //保留本過程名在名字表中的位置
int cx0; //保留本過程目標代碼的起始位置
int[] x=new int[2];
dx=3; //為該過程變量分配存儲空間的起始位置,也就是相對基地址的偏移量
tx0=tx; //保留當前table表指針值,是該過程名在table表中的位置
table[tx].adr=cx;//保留當前code指針值到過程名的adr域
gen(Function.jmp,0,0);//生成轉(zhuǎn)向過程體入口的指令,地址待回填
if(lev > levMax)
{
error(32);
}
do{
if(sym==Symbol.constsym)
{
getsym();
do{
x=constdeclaration(tx,lev,dx);
tx=x[0];
dx=x[1];
while(sym==Symbol.comma)
{
getsym();
x=constdeclaration(tx,lev,dx);
tx=x[0];
dx=x[1];
}
if(sym==Symbol.semicolon)
getsym();
else
error(5); /*漏掉了逗號或者分號*/
}while(sym==Symbol.ident);
}
if(sym==Symbol.varsym)
{
getsym();
do{
x=vardeclaration(tx,lev,dx);
tx=x[0];
dx=x[1];
while(sym==Symbol.comma)
{
getsym();
x=vardeclaration(tx,lev,dx);
tx=x[0];
dx=x[1];
}
if(sym==Symbol.semicolon)
getsym();
else
error(5);
}while(sym==Symbol.ident);
}
while(sym==Symbol.proceduresym)
{
getsym();
if(sym==Symbol.ident)
{
x=enter(Object.procedure,tx,lev,dx);
tx=x[0];
dx=x[1];
getsym();
}
else
error(4);//procedure后應(yīng)為標識符
if(sym==Symbol.semicolon)
getsym();
else
error(5);//漏掉了分號
block(lev+1,tx);//遞歸進入分程序
if(sym==Symbol.semicolon)
getsym();
else
error(5); /*漏掉了分號*/
}
}while(sym==Symbol.constsym|sym==Symbol.varsym|sym==Symbol.proceduresym);
code[table[tx0].adr].a=cx;//回填過程入口地址到code的a中
table[tx0].adr=cx; //記錄過程在code的入口到table中的adr域
table[tx0].size=dx;//過程占的空間填 寫在table中,聲明部分中每增加一條聲明都會給dx增加1,聲明部分已經(jīng)結(jié)束,dx就是當前過程數(shù)據(jù)的size
cx0=cx;//保留過程在code中的入口地址,打印目標代碼用
gen(Function.inte,0,dx);//生成過程入口指令
System.out.print("TABLE:\n");
if(tx0+1>tx)
{
System.out.printf("NULL\n");
}
for(i=tx0+1;i<=tx;i++)
{
switch(table[i].kind)
{
case constant:
System.out.println(i+" NAME:"+table[i].name+" KIND:"+
Object.constant+" VALUE:"+table[i].val);
break;
case variable:
System.out.println(i+" NAME:"+table[i].name+" KIND:"+
Object.variable+" LEVEL:"+table[i].level+" ADDRESS:"+table[i].adr);
break;
case procedure:
System.out.println(i+" NAME:"+table[i].name+" KIND:"+
Object.procedure+" LEVEL:"+table[i].level+" ADDRESS:"+table[i].adr+" SIZE:"+table[i].size);
break;
}
}
tx=statement(tx,lev);
gen(Function.opr,0,0); //過程出口都要釋放數(shù)據(jù)段
listcode(cx0);
}
int[] enter (Object k,int ptx,int lev, int pdx)
{ int[]x=new int[2];
ptx++;
table[ptx].name=token;
table[ptx].kind=k;
switch(k)
{
case constant:
table[ptx].val=num;
break;
case variable:
table[ptx].level=lev;
table[ptx].adr=pdx;
pdx++;
break;
case procedure:
table[ptx].level=lev;
break;
}
x[0]=ptx;
x[1]=pdx;
return x;
}
int position(String idt,int tx)
{
int i;
table[0].name=idt;
i=tx;
while(table[i].name.compareToIgnoreCase(idt)!=0)
i--;
return i;
}
int[] constdeclaration(int ptx,int lev,int pdx)
{ int[]x=new int[2];
if(sym==Symbol.ident)
{
getsym();
if(sym==Symbol.eql )
{
getsym();
if(sym==Symbol.number)
{
x=enter(Object.constant,ptx,lev,pdx);
ptx=x[0];
pdx=x[1];
getsym();
}
else
error(2);
}
else
error(3);
}
else
error(4);
return x;
}
int[] vardeclaration(int ptx,int lev,int pdx)
{
int[]x=new int[2];
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -