软件体系结构的第二次实验(解释器风格与管道过滤器风格)
一、实验目的
1.熟悉体系结构的风格的概念
2.理解和应用管道过滤器型的风格。
3、理解解释器的原理
4、理解编译器模型
二、实验环境
硬件:
软件:Python或任何一种自己喜欢的语言
三、实验内容
1、实现“四则运算”的简易翻译器。
结果要求:
1)实现加减乘除四则运算,允许同时又多个操作数,如:2+3*5-6 结果是11
2)被操作数为整数,整数可以有多位
3)处理空格
4)输入错误显示错误提示,并返回命令状态“CALC”
图1 实验结果示例
加强练习:
1、有能力的同学,可以尝试实现赋值语句,例如x=2+3*5-6,返回x=11。(注意:要实现解释器的功能,而不是只是显示)
2、尝试实现自增和自减符号,例如x++
2、采用管道-过滤器(Pipes and Filters)风格实现解释器
图2 管道-过滤器风格
图 3 编译器模型示意图
本实验,实现的是词法分析和语法分析两个部分。
四、实验步骤:
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 100
#define SYMBOLSIZE 50
typedef struct oper_symbol
{
char oper;
unsigned int index;
}oper_symbol;
double caculate(char * expression);
double get_data(char * str,int beg,int end);
int is_operator_symbol(char ch);
long int power(int base,int times);
int main()
{
char *expression = NULL;
double ret;
expression = (char*)malloc(sizeof(char)*MAXSIZE);
if(expression == NULL)
{
printf("内存分配失败.\n");
return -1;
}
memset(expression,0,MAXSIZE*sizeof(char));
while(1)
{
printf("请输入一个表达式: ");
scanf("%s",expression);
ret = caculate(expression);
printf("表达式计算结果为: %lf\n",ret);
}
free(expression);
system("pause");
return 0;
}
double caculate(char * expression)
{
unsigned int i,j,k;
unsigned int symbol_len = 0;
unsigned int datas_len = 0;
unsigned int symbol_index_len=0;
double left_data,right_data;
double temp,ret;
double *datas = (double*)malloc(sizeof(double)*MAXSIZE);
char *symbols = (char*)malloc(sizeof(char*)*SYMBOLSIZE);
oper_symbol * symbols_index = (oper_symbol*)malloc(sizeof(oper_symbol)*SYMBOLSIZE);
if(datas == NULL || symbols == NULL || symbols_index == NULL)
{
printf("内存分配失败.\n");
return 0;
}
for(i=0;i<strlen(expression);i++)
{
if(is_operator_symbol(expression[i]))
{
symbols_index[symbol_index_len].oper = expression[i];
symbols_index[symbol_index_len].index = i;
symbol_index_len++;
}
}
for(j=0,i=0;j<symbol_index_len;j++)
{
if(datas_len == 0)
left_data = get_data(expression,i,symbols_index[j].index);
else
left_data = datas[--datas_len];
if( j+1 == symbol_index_len)
right_data = get_data(expression,symbols_index[j].index+1,strlen(expression));
else
right_data = get_data(expression,symbols_index[j].index+1,symbols_index[j+1].index);
if(symbols_index[j].oper == '*' || symbols_index[j].oper == '/')
{
switch(symbols_index[j].oper)
{
case '*':
temp = left_data * right_data;
break;
case '/':
temp = left_data / right_data;
break;
}
datas[datas_len++] = temp;
}
else
{
datas[datas_len++] = left_data;
datas[datas_len++] = right_data;
symbols[symbol_len++] = symbols_index[j].oper;
}
}
k = symbol_len;
while(k)
{
left_data = datas[--datas_len];
right_data = datas[--datas_len];
k = symbol_len-1;
switch(symbols[k])
{
case '+':
temp = right_data + left_data;
break;
case '-':
temp = left_data - right_data;
break;
}
datas[datas_len++] = temp;
symbol_len--;
}
ret = datas[0];
free(datas);
free(symbols);
free(symbols_index);
return ret;
}
int is_operator_symbol(char ch)
{
if(ch == '+' || ch == '-' || ch == '*' || ch == '/')
return 1;
return 0;
}
double get_data(char * str,int beg,int end)
{
int i,k;
double ret = 0.0f;
double integer = 0.0f;
double decimal = 0.0f;
double temp;
i = beg;
while(str[i] != '.' && i < end)
{
integer *= 10;
integer += str[i] ^ 0x30;
i++;
}
if(str[i] == '.')
{
i++;
k=1;
while(i<end)
{
temp = str[i] ^ 0x30;
temp /= power(10,k);
decimal += temp;
k++;
i++;
}
}
ret = integer+decimal;
return ret;
}
long int power(int base,int times)
{
long ret = 1;
int i;
for(i=0;i<times;i++)
ret *= base;
return ret;
}
截图:
总体结构:
输入表达式——检查运算符优先级并排序——计算——输出结果
五、实验总结
加深了体系结构的理解,并温习了C语言。
参考资料: