
PL0源代码C语言版.doc
33页/*PL/0 编译系统C版本头文件 pl0.h*/# define norw 13 //a number of reserved word /*关键字个数*/ # define t*ma* 100 //length of identifier table /*名字表容量*/# define nma* 14 //ma* number of digits in numbers /*number的最大位数*/# define al 10 //length of identifier /*符号的最大长度*/# define ama* 2047 //ma*imum address /*地址上界*/# define levma* 3 //ma* depth of block nesting /*最大允许过程嵌套声明层数[0,le*ma*]*/# define c*ma* 200 //size of code array /*最多的虚拟机代码数*//*符号*/enum symbol{ nul, ident, number, plus, minus, times, slash, oddsym, eql, neq, //slash斜线 lss, leq, gtr, geq, lparen, //leq :less than or equal to; gtr: great than;lparen:left parenthesisrparen, ma, semicolon,period, bees,//ma逗号 semicolon分号 period句号 bees赋值号 beginsym, endsym, ifsym, thensym, whilesym,writesym, readsym, dosym, callsym, constsym,varsym, procsym,};#define symnum 32/*-------------*/enum object{ //object为三种标识符的类型 constant, variable, procedur,};/*--------------*/enum fct{ //fct类型分别标识类PCODE的各条指令lit, opr, lod, sto, cal, inte, jmp, jpc, //书本P23 };#define fctnum 8/*--------------*/struct instruction //指令 { enum fct f; //功能码 int l; //层次差 int a; //P23};FILE * fas; //输知名字表 FILE * fa; //输出虚拟机代码 FILE * fa1; //输出源文件及其各行对应的首地址 FILE * fa2; //输出结果 bool tableswitch; //显示名字表与否 bool listswitch; //显示虚拟机代码与否 char ch; //获取字符的缓冲区,getch使用 enum symbol sym; //当前符号 char id[al+1]; //当前ident,多出一个字节用于存放0 int num; //当前number int cc,ll; //getch使用的计数器,cc表示当前字符(ch)的位置 int c*; //虚拟机代码指针,取值围[0,c*ma*-1]char line[81]; //读取行缓冲区 char a[al+1]; //临时符号,多出的一个字节用于存放0 struct instruction code[c*ma*]; //存放虚拟机代码的数组 char word[norw][al]; //保存字enum symbol wsym[norw]; //保存字对应的符号值 enum symbol ssym[256]; //单字符的符号值 char mnemonic[fctnum][5]; //虚拟机代码指令名称 bool declbegsys[symnum]; //表示声明开场的符号集合 ,declaring begin symbol setbool statbegsys[symnum]; //表示语句开场的符号集 , statementbool facbegsys[symnum]; //表示因子开场的符号集合 ,factor/*------------------------------*/struct tablestruct{ char name[al]; /*名字*/ enum object kind; /*类型:const,var,array or procedure*/ int val; /*数值,仅const使用*/ int level; /*所处层,仅const不使用*/ int adr; /*地址,仅const不使用*/ int size; /*需要分配的数据区空间,仅procedure使用*/};struct tablestruct table[t*ma*]; /*名字表*/FILE * fin; //fin文本文件用于指向输入的源程序文件FILE* fout; //fout文本文件用于指向输出的文件char fname[al];int err; /*错误计数器*//*当函数中会发生fatal error时,返回-1告知调用它的函数,最终退出程序*/#define getsymdo if(-1==getsym())return -1#define getchdo if(-1==getch())return -1#define testdo(a,b,c) if(-1==test(a,b,c))return -1#define gendo(a,b,c) if(-1==gen(a,b,c))return -1#define e*pressiondo(a,b,c) if(-1==e*pression(a,b,c))return -1#define factordo(a,b,c) if(-1==factor(a,b,c))return -1#define termdo(a,b,c) if(-1==term(a,b,c))return -1#define conditiondo(a,b,c) if(-1==condition(a,b,c))return -1#define statementdo(a,b,c) if(-1==statement(a,b,c))return -1#define constdeclarationdo(a,b,c) if(-1==constdeclaration(a,b,c))return -1#define vardeclarationdo(a,b,c) if(-1==vardeclaration(a,b,c))return -1void error(int n);int getsym();int getch();void init();int gen(enum fct *,int y,int z);int test(bool*s1,bool*s2,int n);int inset(int e,bool*s);int addset(bool*sr,bool*s1,bool*s2,int n);int subset(bool*sr,bool*s1,bool*s2,int n);int mulset(bool*sr,bool*s1,bool*s2,int n);int block(int lev,int t*,bool* fsys);void interpret();int factor(bool* fsys,int* pt*,int lev);int term(bool*fsys,int*pt*,int lev);int condition(bool*fsys,int*pt*,int lev);int e*pression(bool*fsys,int*pt*,int lev);int statement(bool*fsys,int*pt*,int lev);void listcode(int c*0);int vardeclaration(int* pt*,int lev, int* pd*);int constdeclaration(int* pt*,int lev, int* pd*);int position(char* idt,int t*);void enter(enum object k,int* pt*,int lev,int* pd*);int base(int l,int* s,int b);//A.2 C 版 本/*编译和运行环境:*1Visual C++6.0,VisualC++.NET and Visual C++.NET 2003*WinNT, Win 200, Win*P and Win2003 *2 gcc version 3.3.2 20031022(Red Hat Linu* 3.3.2-1)*Redhat Fedora core 1*Intel 32 platform*使用方法:*运行后输入PL/0 源程序文件名*答复是否输出虚拟机代码*答复是否输知名字。
