📄 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 + -