软件体系结构的第二次实验(解释器风格与管道过滤器风格)
一、实验目的
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 50typedef 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语言。
参考资料: