⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pl0.h

📁 pl0
💻 H
字号:
#include "stdio.h"
#define NRW        20     // 保留字的个数
#define TXMAX      100    // 标识符表的长度(容量)
#define MAXNUMLEN  14     // 数字允许的最长位数
#define MAXIDLEN   10     // 标识符最长长度
#define MAXADDRESS 2047   // 寻址空间
#define MAXLEVEL   3      //  最大允许的块嵌套层数
#define CXMAX      200    // 类PCODE目标代码数组长度(可容纳代码行数)
#define NSYM       10     // 符号的个数
#define MAXSYM     30     // maximum number of symbols  
#define STACKSIZE  500    // 常量定义,假想的栈式计算机有500个栈单元
 

enum symtype  //symset是symbol类型的一个集合类型,可用于存放一组symbol,symobl类型标识了不同类型的词汇
{
	SYM_NULL,            // 0
	SYM_IDENTIFIER,      // 1
	SYM_NUMBER,          // 2
	SYM_PLUS,            // 3  +
	SYM_MINUS,           // 4  -
	SYM_TIMES,           // 5  *
	SYM_SLASH,           // 6  /
	SYM_ODD,             // 7  odd
	SYM_EQU,             // 8  =
	SYM_NEQ,             // 9  <>
	SYM_LSS,             // 10 < 
	SYM_LEQ,             // 11 <=
	SYM_GTR,             // 12 >
	SYM_GEQ,             // 13 >=
	SYM_LPAREN,          // 14 (
	SYM_RPAREN,          // 15 )
	SYM_COMMA,           // 16 ,
	SYM_SEMICOLON,       // 17 ;
	SYM_PERIOD,          // 18 .
	SYM_BECOMES,         // 19 :=
    SYM_BEGIN,           // 20 begin
	SYM_END,             // 21 end
	SYM_IF,              // 22 if
	SYM_THEN,            // 23 then
	SYM_WHILE,           // 24 while
	SYM_DO,              // 25 do
	SYM_CALL,            // 26 call
	SYM_CONST,           // 27 const
	SYM_VAR,             // 28 var
	SYM_PROCEDURE,       // 29 procedure
	SYM_READ,            // 30 read
	SYM_WRITE,           // 31 write
	SYM_ELSE,            // 32 else
    SYM_DOWNTO,          // 33 downto
	SYM_BY,              // 34 by
	SYM_TO,              // 35 to
	SYM_FOR,             // 36 for
	SYM_REPEAT,          // 37 repeat
	SYM_UNTIL            // 38 until	
};

enum idtype  //idtype标识符的类型
{
	ID_CONSTANT, ID_VARIABLE, ID_PROCEDURE
};

enum opcode  //opcode类型分别标识类PCODE的各条指令 
{
	LIT, OPR, LOD, STO, CAL, INT, JMP, JPC, RED, WRT
};

enum oprcode
{
	OPR_RET, OPR_NEG, OPR_ADD, OPR_MIN,
	OPR_MUL, OPR_DIV, OPR_ODD, OPR_EQU,
	OPR_NEQ, OPR_LSS, OPR_LEQ, OPR_GTR,
	OPR_GEQ
};


typedef struct  //类PCODE指令类型,包含三个字段:指令f、层差l和另一个操作数a 
{
	int f; // function code
	int l; // level
	int a; // displacement address
} instruction;

//////////////////////////////////////////////////////////////////////
char* err_msg[] =
{
/*  0 */    "",
/*  1 */    "常数说明中的\"=\"写成\":=\"!",
/*  2 */    "常数说明中的\"=\"后应是数字!",
/*  3 */    "常数说明中标识符后应是\"=\"!",
/*  4 */    "'const', 'var', 'procedure'后应为标识符!",
/*  5 */    "漏掉了\',\' 或\';\'!",
/*  6 */    "过程说明后的符号不正确(应是语句开始符,或过程定义符)!",
/*  7 */    "应是语句开始符!",
/*  8 */    "程序体内语句部分后的符号不正确!",
/*  9 */    "程序结尾丢了句号\'.\'!",
/* 10 */    "语句之间漏';'!",
/* 11 */    "标识符未说明!",
/* 12 */    "赋值语句中, 赋值号左部标识符属性应是变量,不可向常量或过程赋值!",
/* 13 */    "赋值语句左部标识符后应是赋值号\':=\'!",
/* 14 */    "'call'后应为标识符!",
/* 15 */    "不可调用常量或变量.",
/* 16 */    "条件语句中丢了\'then\'!",
/* 17 */    "丢了\'end\' 或\';\'!",
/* 18 */    "while 型循环语句中丢了\'do\'!",
/* 19 */    "语句后的符号不正确!",
/* 20 */    "应为关系运算符!",
/* 21 */    "表达式内标识符属性不能是过程!",
/* 22 */    "表达式中漏掉右括号\')\'!",
/* 23 */    "因子后的非法符号!",
/* 24 */    "表达式不能以此符号开始!",
/* 25 */    "“for”后应为变量标识符",
/* 26 */    "缺少“to”或“downto”",		
/* 27 */    "应为“do”或“by”",
/* 28 */    "应为“do”",
/* 29 */    "repeat 型循环语句中没有until!",
/* 30 */    "数值过大",
/* 31 */    "编译器溢出",
/* 32 */    "过程嵌套过深",
/* 33 */    "read语句括号中的标识符不是变量!",
/* 34 */    "应当为右括号",
/* 35 */    "应为负数",
/* 36 */    "应为正数",
/* 40 */	"应当为左括号"
};

   
    
  
//////////////////////////////////////////////////////////////////////全局变量定义
char ch;         // 主要用于词法分析器,存放最近一次从文件中读出的字符
int  sym;        // 词法分析器输出结果之用,存放最近一次识别出来的token的类型
char id[MAXIDLEN + 1]; // 词法分析器输出结果之用,存放最近一次识别出来的标识符的名字
int  num;        // d词法分析器输出结果之用,存放最近一次识别出来的数字的值
int  cc;         // 行缓冲区指针
int  ll;         // 行缓冲区长度
int  err;
int  cx;         //代码分配指针,代码生成模块总在cx所指位置生成新的代码
int  level = 0;
int  tx = 0;
char line[80];  //行缓冲区,用于从文件读出一行,供词法分析获取单词时之用
instruction code[CXMAX];  //生成的类PCODE代码表,存放编译得到的类PCODE代码

char* word[NRW +1] =  //保留字表
{
	"", /* place holder */
	"begin", "call", "const", "do", "end","if",
	"odd", "procedure", "then", "var", "while",
	"read", "write", "else","downto","by","to",
	"for", "repeat", "until"
};

int wsym[NRW +1] =  //保留字表中每一个保留字对应的symbol类型 
{
	SYM_NULL, SYM_BEGIN, SYM_CALL, SYM_CONST, SYM_DO, SYM_END,
	SYM_IF, SYM_ODD, SYM_PROCEDURE, SYM_THEN, SYM_VAR, SYM_WHILE,
    SYM_READ, SYM_WRITE, SYM_ELSE,SYM_DOWNTO,SYM_BY,SYM_TO,SYM_FOR,
	SYM_REPEAT,	SYM_UNTIL
};

int ssym[NSYM + 1] = //一些符号对应的symbol类型表
{
	SYM_NULL, SYM_PLUS, SYM_MINUS, SYM_TIMES, SYM_SLASH,
	SYM_LPAREN, SYM_RPAREN, SYM_EQU, SYM_COMMA, SYM_PERIOD,	SYM_SEMICOLON 
};

char csym[NSYM + 1] =
{
	' ', '+', '-', '*', '/', '(', ')', '=', ',', '.', ';'
};

#define MAXINS   10
char* mnemonic[MAXINS] =
{
	"LIT", "OPR", "LOD", "STO", "CAL", "INT", "JMP", "JPC", "RED", "WRT"
};

typedef struct
{
	char name[MAXIDLEN + 1];
	int  kind;
	int  value;
} comtab;

comtab table[TXMAX];

typedef struct
{
	char  name[MAXIDLEN + 1];
	int   kind;
	short level;
	short address;
} mask;

FILE* infile, *outfile;//in文本文件用于指向输入的源程序文件,out程序中没有用到

typedef struct snode
{
	int elem;
	struct snode* next;
}
snode, *symset;

symset phi, declbegsys, statbegsys, facbegsys, relset;  //定义的结构体symset的变量

symset uniteset(symset s1, symset s2)
{
	symset s;
	snode* p;	
	s = p = (snode*) malloc(sizeof(snode));
	s1 = s1->next; 
	s2 = s2->next; 	
	while (s1 && s2)
	{
		p->next = (snode*) malloc(sizeof(snode));
		p = p->next;
		if (s1->elem < s2->elem)
		{
			p->elem = s1->elem;
			s1 = s1->next;
		}
		else
		{
			p->elem = s2->elem;
			s2 = s2->next;
		}
	}	
	if (s2)	
		s1 = s2;
	while (s1)
	{
		p->next = (snode*) malloc(sizeof(snode));
		p = p->next;
		p->elem = s1->elem;
		s1 = s1->next;
		
	}
	p->next = NULL;
	return s;
} 

void setinsert(symset s, int elem)
{
	snode* p = s;
	snode* q;
	while (p->next && p->next->elem < elem)
		p = p->next;	
	q = (snode*) malloc(sizeof(snode));
	q->elem = elem;
	q->next = p->next;
	p->next = q;
}

symset createset(int elem, .../* SYM_NULL */)
{
	va_list list;
	symset s;
	s = (snode*) malloc(sizeof(snode));
	s->next = NULL;
	va_start(list, elem);
	while (elem)
	{
		setinsert(s, elem);
		elem = va_arg(list, int);
	}
	va_end(list);
	return s;
}

void destroyset(symset s) //释放空间
{
	snode* p;
	while (s)
	{
		p = s;
		s = s->next;
		free(p);
	}
} 

int inset(int elem, symset s)
{
	s = s->next;
	while (s && s->elem < elem)
		s = s->next;
	if (s && s->elem == elem)
		return 1;
	else
		return 0;
} 


void showset(symset s) //输出
{
	s = s->next;
	while (s)
	{
		printf("%d,", s->elem);
		s = s->next;
	}
	printf("\n");
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -