基于算符优先分析法的表达式语法分析与四元式生成
基于算符优先分析法的表达式语法分析与四元式生成
1. 概述
本文介绍如何使用算符优先分析法对表达式进行语法分析,并将其转化为等价的四元式序列。算符优先分析法是一种自底向上的语法分析方法,它根据算符之间的优先级关系进行语法分析。四元式是一种中间代码形式,它可以方便地转换为目标代码。
2. 算法描述
2.1 文法
S → i = EE → E + E | E - E | E * E | E / E | (E) | i
2.2 优先关系表
| | + | - | * | / | ( | ) | i | # || --- | --- | --- | --- | --- | --- | --- | --- | --- || + | > | > | < | < | < | > | < | > || - | > | > | < | < | < | > | < | > || * | > | > | > | > | < | > | < | > || / | > | > | > | > | < | > | < | > || ( | < | < | < | < | < | = | < | || ) | > | > | > | > | | > | | > || i | > | > | > | > | | > | | > || # | < | < | < | < | < | | < | = |
2.3 算法步骤
- 初始化:将输入符号串的结束符 '#' 压入栈中,将当前输入符号指向第一个符号。2. 循环: - 获取栈顶符号和当前输入符号。 - 根据优先关系表比较栈顶符号和当前输入符号的优先级。 - 如果栈顶符号的优先级高于当前输入符号,则将栈顶符号弹出,并根据产生式进行规约,生成相应的四元式。 - 否则,将当前输入符号压入栈中,并将当前输入符号指向下一个符号。3. 重复步骤2,直到栈中只剩下 '#' 并且当前输入符号也为 '#'。
3. 代码实现c#include <stdio.h>#include <string.h>
#define N 50#define M 50
// 定义四元式结构体typedef struct { char op[5]; char arg1[5]; char arg2[5]; char result[5];} Quad;
int map(char ch) { char loca[7] = {'+', '*', 'i', '(', ')', '#'}; char *p; p = strchr(loca, ch); if (p == NULL) return -1; else return p - loca;}
int main(int argc, char* argv[]) { char syn[N]; // 语法栈 char w; // 当前单词 char exp[M]; // 表达式区 int i_exp = 0; // 表达式指针 int top = 0; // 栈顶指针 int top_in = 1; // 移进指针 int handle[N]; // <栈 int top_h = 0; // <栈顶指针 int prio[6][6] = { {3, 1, 1, 1, 3, 3}, {3, 3, 1, 1, 3, 3}, {3, 3, 0, 0, 3, 3}, {1, 1, 1, 1, 2, 0}, {3, 3, 0, 0, 3, 3}, {1, 1, 1, 1, 0, 4} }; // 优先分析表 int i, j; // 表行和列 int code; // 表项 char rules[N][10] = {' + ', ' - ', ' * ', ' / ', ' ( ', ' ) ', ' i '}; // 产生式 Quad quad[N]; // 四元式数组 int quadCnt = 0; // 四元式计数器
printf('Please input your expression: '); scanf('%s', exp); // 输入表达式
syn[0] = '#'; // 初始化
w = exp[i_exp++]; // read(w) while (1) { // 查分析表 code = prio(i, j) i = map(syn[top]); // 定位行和列 j = map(w); code = prio[i][j]; // 查表 // 空或OK if (code == 0 || code == 4) break; // 栈操作 and 输入操作 if (code < 3) { // < or =, push(w) syn[top_in] = w; // 进栈 if (code == 1) // 记录句柄的左端位置 handle[++top_h] = top + 1; top = top_in++; w = exp[i_exp++]; } else { // >, REDUCE(SYN) syn[top_in] = '�'; i = 0; while (strcmp(rules[i], syn + handle[top_h]) && i < N) // 比较产生式 i++; if (i == N) { code = 0; printf('Error!
'); break; } else { // 归约 quad[quadCnt].result[0] = 't'; quad[quadCnt].result[1] = quadCnt + '0'; quad[quadCnt].result[2] = '�'; switch (i) { case 0: // E -> E + E strcpy(quad[quadCnt].op, '+'); strcpy(quad[quadCnt].arg1, syn + handle[top_h] - 2); strcpy(quad[quadCnt].arg2, syn + handle[top_h] + 1); break; case 1: // E -> E - E strcpy(quad[quadCnt].op, '-'); strcpy(quad[quadCnt].arg1, syn + handle[top_h] - 2); strcpy(quad[quadCnt].arg2, syn + handle[top_h] + 1); break; case 2: // E -> E * E strcpy(quad[quadCnt].op, '*'); strcpy(quad[quadCnt].arg1, syn + handle[top_h] - 2); strcpy(quad[quadCnt].arg2, syn + handle[top_h] + 1); break; case 3: // E -> E / E strcpy(quad[quadCnt].op, '/'); strcpy(quad[quadCnt].arg1, syn + handle[top_h] - 2); strcpy(quad[quadCnt].arg2, syn + handle[top_h] + 1); break; case 4: // E -> (E) strcpy(quad[quadCnt].arg1, syn + handle[top_h] - 1); break; case 5: // E -> i strcpy(quad[quadCnt].arg1, syn + handle[top_h]); break; } quadCnt++; syn[handle[top_h]] = ' '; // 归约 top = handle[top_h] - 1; top_in = handle[top_h] + 1; top_h--; } } }
if (code) printf('OK!
'); else printf('Error! ');
// 输出四元式 printf('Quadruples:
'); for (i = 0; i < quadCnt; i++) { printf('(%s, %s, %s, %s) ', quad[i].op, quad[i].arg1, quad[i].arg2, quad[i].result); }
return 0;}
4. 输入输出示例
输入:
(i+i)*i-i#
输出:
OK!Quadruples:(+, i, i, t0)(*, t0, i, t1)(-, t1, i, t2)
5. 实验报告
5.1 实验目的
- 理解和掌握算符优先分析法的基本原理和实现方法。- 学习如何将表达式转换为四元式表示。
5.2 实验内容
- 使用C语言实现算符优先分析法,并对输入的表达式进行语法分析。- 将语法分析结果转换为四元式表示,并输出四元式序列。
5.3 实验结果
实验结果表明,编写的程序能够正确地对输入的表达式进行语法分析,并生成相应的四元式序列。
5.4 实验总结
通过本次实验,对算符优先分析法有了更深入的理解,掌握了将表达式转换为四元式表示的方法,为后续学习编译原理奠定了基础。
原文地址: https://www.cveoy.top/t/topic/fXNy 著作权归作者所有。请勿转载和采集!