C语言:编写PL/0编译程序的语义分析程序,并生成四元式形式的中间代码
时间: 2024-03-05 11:54:44 浏览: 275
好的,针对您的问题,我可以给出以下C语言代码示例,实现PL/0编译程序的语义分析和四元式生成:
```
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_SYMBOL_TABLE_SIZE 1000 // 符号表最大大小
#define MAX_CODE_LENGTH 1000 // 代码最大长度
#define MAX_IDENTIFIER_LENGTH 10 // 标识符最大长度
#define MAX_NUMBER_LENGTH 5 // 数字最大长度
// 符号表结构体
struct Symbol {
char name[MAX_IDENTIFIER_LENGTH]; // 符号名称
int kind; // 符号类型:1表示const,2表示var,3表示procedure
int val; // 符号值
int level; // 符号所在层次
int addr; // 符号地址
};
// 代码结构体
struct Code {
char op[3]; // 操作符
int l; // 左操作数
int r; // 右操作数
int d; // 结果
};
char error_msg[50]; // 错误信息
char code[MAX_CODE_LENGTH][5]; // 输入的代码
int code_length; // 代码长度
struct Symbol symbol_table[MAX_SYMBOL_TABLE_SIZE]; // 符号表
int symbol_table_size; // 符号表大小
struct Code intermediate_code[MAX_CODE_LENGTH]; // 中间代码
int intermediate_code_length; // 中间代码长度
int level; // 当前层次
int addr; // 当前地址
int cx; // 当前代码指针
// 获取下一个token
void get_token(char* token) {
if (code[cx][0] == '\0') {
strcpy(token, "");
return;
}
int i = 0;
while (code[cx][i] != ' ' && code[cx][i] != '\0') {
token[i] = code[cx][i];
i++;
}
token[i] = '\0';
cx++;
}
// 查找符号在符号表中的位置
int find_symbol(char* name) {
int i;
for (i = symbol_table_size - 1; i >= 0; i--) {
if (strcmp(symbol_table[i].name, name) == 0) {
return i;
}
}
return -1;
}
// 向符号表中添加符号
void add_symbol(char* name, int kind, int val, int level, int addr) {
if (symbol_table_size >= MAX_SYMBOL_TABLE_SIZE) {
strcpy(error_msg, "符号表已满,无法添加符号!");
return;
}
strcpy(symbol_table[symbol_table_size].name, name);
symbol_table[symbol_table_size].kind = kind;
symbol_table[symbol_table_size].val = val;
symbol_table[symbol_table_size].level = level;
symbol_table[symbol_table_size].addr = addr;
symbol_table_size++;
}
// 生成中间代码
void generate_code(char* op, int l, int r, int d) {
if (intermediate_code_length >= MAX_CODE_LENGTH) {
strcpy(error_msg, "中间代码已满,无法添加代码!");
return;
}
strcpy(intermediate_code[intermediate_code_length].op, op);
intermediate_code[intermediate_code_length].l = l;
intermediate_code[intermediate_code_length].r = r;
intermediate_code[intermediate_code_length].d = d;
intermediate_code_length++;
}
// 语法分析函数
void parse();
// 语法分析函数:常量声明
void parse_const_declaration() {
char name[MAX_IDENTIFIER_LENGTH];
char token[MAX_NUMBER_LENGTH];
get_token(name);
if (strlen(name) == 0) {
strcpy(error_msg, "常量声明语句不完整!");
return;
}
if (find_symbol(name) >= 0) {
strcpy(error_msg, "符号已经定义!");
return;
}
get_token(token);
if (strlen(token) == 0 || strcmp(token, "=") != 0) {
strcpy(error_msg, "常量声明语句不完整!");
return;
}
get_token(token);
if (strlen(token) == 0) {
strcpy(error_msg, "常量值未指定!");
return;
}
add_symbol(name, 1, atoi(token), level, addr);
addr++;
get_token(token);
if (strlen(token) == 0 || strcmp(token, ";") != 0) {
strcpy(error_msg, "常量声明语句不完整!");
return;
}
}
// 语法分析函数:变量声明
void parse_var_declaration() {
char name[MAX_IDENTIFIER_LENGTH];
char token[MAX_NUMBER_LENGTH];
get_token(name);
if (strlen(name) == 0) {
strcpy(error_msg, "变量声明语句不完整!");
return;
}
if (find_symbol(name) >= 0) {
strcpy(error_msg, "符号已经定义!");
return;
}
add_symbol(name, 2, 0, level, addr);
addr++;
get_token(token);
if (strlen(token) == 0 || strcmp(token, ";") != 0) {
strcpy(error_msg, "变量声明语句不完整!");
return;
}
}
// 语法分析函数:过程声明
void parse_procedure_declaration() {
char name[MAX_IDENTIFIER_LENGTH];
get_token(name);
if (strlen(name) == 0) {
strcpy(error_msg, "过程声明语句不完整!");
return;
}
if (find_symbol(name) >= 0) {
strcpy(error_msg, "符号已经定义!");
return;
}
add_symbol(name, 3, 0, level, cx);
get_token(name);
if (strlen(name) == 0 || strcmp(name, ";") != 0) {
strcpy(error_msg, "过程声明语句不完整!");
return;
}
level++;
parse();
level--;
}
// 语法分析函数:因子
void parse_factor() {
char token[MAX_NUMBER_LENGTH];
char name[MAX_IDENTIFIER_LENGTH];
get_token(token);
if (strlen(token) == 0) {
strcpy(error_msg, "因子不完整!");
return;
}
if (strcmp(token, "(") == 0) {
parse();
get_token(token);
if (strlen(token) == 0 || strcmp(token, ")") != 0) {
strcpy(error_msg, "因子不完整!");
return;
}
} else if (strcmp(token, "ident") == 0) {
get_token(name);
int symbol_index = find_symbol(name);
if (symbol_index < 0) {
strcpy(error_msg, "变量未定义!");
return;
}
if (symbol_table[symbol_index].kind == 1) {
generate_code("lit", 0, symbol_table[symbol_index].val, 0);
} else if (symbol_table[symbol_index].kind == 2) {
generate_code("lod", level - symbol_table[symbol_index].level, symbol_table[symbol_index].addr, 0);
} else {
strcpy(error_msg, "变量类型不正确!");
return;
}
} else if (strcmp(token, "number") == 0) {
get_token(token);
generate_code("lit", 0, atoi(token), 0);
} else {
strcpy(error_msg, "因子不完整!");
return;
}
}
// 语法分析函数:项
void parse_term() {
char token[MAX_NUMBER_LENGTH];
char op[MAX_NUMBER_LENGTH];
parse_factor();
while (1) {
get_token(token);
if (strlen(token) == 0) {
break;
}
if (strcmp(token, "*") == 0 || strcmp(token, "/") == 0) {
strcpy(op, token);
parse_factor();
if (strcmp(op, "*") == 0) {
generate_code("opr", 0, 4, 0);
} else {
generate_code("opr", 0, 5, 0);
}
} else {
cx--;
break;
}
}
}
// 语法分析函数:表达式
void parse_expression() {
char token[MAX_NUMBER_LENGTH];
char op[MAX_NUMBER_LENGTH];
if (strcmp(code[cx], "+") == 0 || strcmp(code[cx], "-") == 0) {
strcpy(op, code[cx]);
cx++;
}
parse_term();
if (strcmp(op, "-") == 0) {
generate_code("opr", 0, 1, 0);
}
while (1) {
get_token(token);
if (strlen(token) == 0) {
break;
}
if (strcmp(token, "+") == 0 || strcmp(token, "-") == 0) {
strcpy(op, token);
parse_term();
if (strcmp(op, "+") == 0) {
generate_code("opr", 0, 2, 0);
} else {
generate_code("opr", 0, 3, 0);
}
} else {
cx--;
break;
}
}
}
// 语法分析函数:条件
void parse_condition() {
char token[MAX_NUMBER_LENGTH];
char op[MAX_NUMBER_LENGTH];
if (strcmp(code[cx], "odd") == 0) {
cx++;
parse_expression();
generate_code("opr", 0, 6, 0);
} else {
parse_expression();
get_token(token);
if (strlen(token) == 0 || (strcmp(token, "=") != 0 && strcmp(token, "<>") != 0 && strcmp(token, "<") != 0 && strcmp(token, ">") != 0 && strcmp(token, "<=") != 0 && strcmp(token, ">=") != 0)) {
strcpy(error_msg, "条件不完整!");
return;
}
strcpy(op, token);
parse_expression();
if (strcmp(op, "=") == 0) {
generate_code("opr", 0, 8, 0);
} else if (strcmp(op, "<>") == 0) {
generate_code("opr", 0, 9, 0);
} else if (strcmp(op, "<") == 0) {
generate_code("opr", 0, 10, 0);
} else if (strcmp(op, ">") == 0) {
generate_code("opr", 0, 11, 0);
} else if (strcmp(op, "<=") == 0) {
generate_code("opr", 0, 12, 0);
} else if (strcmp(op, ">=") == 0) {
generate_code("opr", 0, 13, 0);
}
}
}
// 语法分析函数:语句
void parse_statement() {
char name[MAX_IDENTIFIER_LENGTH];
char token[MAX_NUMBER_LENGTH];
if (strcmp(code[cx], "ident") == 0) {
get_token(name);
int symbol_index = find_symbol(name);
if (symbol_index < 0) {
strcpy(error_msg, "变量未定义!");
return;
}
if (symbol_table[symbol_index].kind != 2) {
strcpy(error_msg, "变量类型不正确!");
return;
}
get_token(token);
if (strlen(token) == 0 || strcmp(token, ":=") != 0) {
strcpy(error_msg, "赋值语句不完整!");
return;
}
parse_expression();
generate_code("sto", level - symbol_table[symbol_index].level, symbol_table[symbol_index].addr, 0);
} else if (strcmp(code[cx], "call") == 0) {
get_token(name);
int symbol_index = find_symbol(name);
if (symbol_index < 0) {
strcpy(error_msg, "过程未定义!");
return;
}
if (symbol_table[symbol_index].kind != 3) {
strcpy(error_msg, "过程名称不正确!");
return;
}
generate_code("cal", level - symbol_table[symbol_index].level, symbol_table[symbol_index].addr, 0);
} else if (strcmp(code[cx], "if") == 0) {
parse_condition();
get_token(token);
if (strlen(token) == 0 || strcmp(token, "then") != 0) {
strcpy(error_msg, "if语句不完整!");
return;
}
int cx1 = intermediate_code_length;
generate_code("jpc", 0, 0, 0);
parse();
intermediate_code[cx1].d = intermediate_code_length;
} else if (strcmp(code[cx], "begin") == 0) {
cx++;
parse();
while (strcmp(code[cx], ";") == 0) {
cx++;
parse();
}
get_token(token);
if (strlen(token) == 0 || strcmp(token, "end") != 0) {
strcpy(error_msg, "begin-end语句不完整!");
return;
}
} else if (strcmp(code[cx], "while") == 0) {
int cx1 = intermediate_code_length;
parse_condition();
get_token(token);
if (strlen(token) == 0 || strcmp(token, "do") != 0) {
strcpy(error_msg, "while语句不完整!");
return;
}
int cx2 = intermediate_code_length;
generate_code("jpc", 0, 0, 0);
parse();
generate_code("jmp", 0, 0, cx1);
intermediate_code[cx2].d = intermediate_code_length;
}
}
// 语法分析函数:程序
void parse() {
char token[MAX_IDENTIFIER_LENGTH];
while (strlen(code[cx]) > 0) {
if (strcmp(code[cx], "const") == 0) {
cx++;
parse_const_declaration();
} else if (strcmp(code[cx], "var") == 0) {
cx++;
parse_var_declaration();
} else if (strcmp(code[cx], "procedure") == 0) {
cx++;
parse_procedure_declaration();
} else {
parse_statement();
if (strlen(error_msg) > 0) {
return;
}
}
}
}
// 输出
阅读全文