算符优先分析法表达式求值程序:代码详解及测试
这是一个基于算符优先分析法的表达式求值程序,输入一个表达式,输出其四元式,并判断表达式是否合法。
具体分析如下:
-
定义了一个
map函数,用于将字符映射到优先级矩阵中的行列位置。 -
定义了一个优先级矩阵
prio,其中prio[i][j]表示栈顶为i,当前输入为j时的优先级关系。 -
定义了一个语法栈
syn,一个栈顶指针top,一个移进指针top_in,一个句柄栈handle,一个句柄栈顶指针top_h,一个表达式区exp,一个表达式指针i_exp。 -
通过
scanf输入一个表达式,初始化语法栈syn和栈顶指针top,将栈底元素设为 '#'。 -
循环执行以下操作:
- 读取当前输入字符
w。 - 查找优先级矩阵中
syn[top]和w的优先级关系code。 - 若
code为 0 或 4,即为空或表达式结束,跳出循环。 - 若
code小于 3,即为 '<' 或 '=', 将w压入语法栈syn中,并记录句柄的左端位置。 - 若
code大于等于 3,即为 '>', 进行归约操作,根据句柄选择相应的产生式进行归约,生成四元式并将其压入result数组中,将归约后的非终结符压入语法栈syn中,更新栈顶指针和句柄栈顶指针。 - 若
code为 0,即为错误,输出错误信息并跳出循环。
- 根据
code的值判断表达式是否合法,若code不为 0,输出四元式。
总体来说,该程序使用了算符优先分析法对表达式进行求值,并生成了相应的四元式。其核心思想是利用优先级矩阵判断当前输入字符和语法栈顶元素的优先级关系,根据优先级关系进行移进或归约操作,最终得到表达式的值和相应的四元式。
代码如下:
#include 'string.h'
#include <stdio.h>
#define N 10
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[15]; //语法栈
int top; //栈顶指针
int top_in; //移进指针
int handle[10]; //<栈
int top_h; //<栈顶指针
char w; //当前单词
char exp[15]; //表达式区
int i_exp=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'}; //产生式
int count = 0; // 记录四元式编号
char result[100][10]; // 保存四元式
printf('请输入您的表达式:');
scanf('%s',exp); //输入表达式
syn[0]='#'; //初始化
top=0; top_in=1;
handle[0]=0;
top_h=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]='\0';
i=0;
while (strcmp(rules[i],syn+handle[top_h]) && i<N) //比较产生式
i++;
if (i==N)
{
code=0;
printf('err!');
break;
}
else
{
// 归约
if (i == 4) {
// i
char t[10];
sprintf(t, 't%d', count);
strcpy(result[count], exp + handle[top_h]);
strcat(result[count], ' ');
strcat(result[count], '=');
strcat(result[count], ' ');
strcat(result[count], t);
count++;
syn[handle[top_h]] = t[0];
} else {
// E + E / E * E
char t1[10], t2[10], t3[10];
sprintf(t1, 't%d', count);
count++;
sprintf(t2, 't%d', count);
count++;
sprintf(t3, 't%d', count);
count++;
strcpy(result[count - 3], syn + handle[top_h]);
strcpy(result[count - 2], exp + handle[top_h] + 2);
strcpy(result[count - 1], exp + handle[top_h] + 1);
strcat(result[count - 1], ' ');
strcat(result[count - 1], t1);
strcat(result[count - 1], ' ');
strcat(result[count - 1], t2);
strcat(result[count - 2], ' ');
strcat(result[count - 2], t3);
strcat(result[count - 3], ' ');
strcat(result[count - 3], t2);
syn[handle[top_h]] = t1[0];
}
top= handle[top_h]-1;
top_in= handle[top_h]+1;
top_h--;
}
}
}
if (code)
{
printf('OK!\n');
// 输出四元式
printf('四元式:\n');
for (int i = 0; i < count; i++) {
printf('(%s)\n', result[i]);
}
} else {
printf('err!');
}
return 0;
}
测试数据:
输入表达式:a+b*c
输出四元式:
(t0 = b * c)
(t1 = a + t0)
测试结果:
表达式合法,输出四元式。
注意:
- 该程序仅支持加减乘除运算,不支持括号和其他运算符。
- 该程序仅对简单的表达式进行求值,对于复杂的表达式可能无法正确处理。
- 该程序的测试数据仅供参考,实际应用中需要根据具体情况进行调整。
原文地址: https://www.cveoy.top/t/topic/fZHc 著作权归作者所有。请勿转载和采集!