简易四则运算

一、实验目的

  1.熟悉体系结构的风格的概念

  2.理解和应用管道过滤器型的风格。

  3、理解解释器的原理

  4、理解编译器模型

二、实验环境

  硬件: 

  软件:Python或任何一种自己喜欢的语言

三、实验内容

  1、实现“四则运算”的简易翻译器。

  结果要求:

    1)实现加减乘除四则运算,允许同时又多个操作数,如:2+3*5-6 结果是11

    2)被操作数为整数,整数可以有多位

    3)处理空格

    4)输入错误显示错误提示,并返回命令状态“CALC”

     简易四则运算_第1张图片

      图1    实验结果示例

  加强练习:

    1、有能力的同学,可以尝试实现赋值语句,例如x=2+3*5-6,返回x=11。(注意:要实现解释器的功能,而不是只是显示)

    2、尝试实现自增和自减符号,例如x++ 

    3、采用管道-过滤器(Pipes and Filters)风格实现解释器

简易四则运算_第2张图片

 

                        图2  管道-过滤器风格

 简易四则运算_第3张图片

#include

#include

#include

#include

#include

#include

#define Stack_Size 50

 

typedef struct

{

char elem[Stack_Size];

int top;

}SepStack;

typedef struct

{

int elem[Stack_Size];

int top;

}SepStackOperand;

typedef struct //运算符栈的定义

{

char elem[Stack_Size];

int top;

}SeqStack;

typedef struct //运算数栈的定义

{

int elem[Stack_Size];

int top;

}SeqStackOperand;

 

 

void CalFace(); //鼠标按键响应

void MainFace(); //界面

char ops[7]={'+', '-', '*', '/', '(', ')', '#'};

int cmp[7][7]=

{

{2,2,1,1,1,2,2},

{2,2,1,1,1,2,2},

{2,2,2,2,1,2,2},

{2,2,2,2,1,2,2},

{1,1,1,1,1,3,0},

{2,2,2,2,0,2,2},

{1,1,1,1,1,0,3}

};

 

 

void InitStack(SeqStack*S) //初始化运算符栈

{

S->top=-1;

}

void InitStacknOperand(SeqStackOperand*S) //初始化运算数栈

{

S->top=-1;

}

int IsEmpty(SeqStack*S) //判断栈S为空栈时返回值为真,反之为假

{

return (S->top==-1?TRUE:FALSE);

}

int IsEmptynOperand(SeqStackOperand*S) //判断栈S为空栈时返回值为真,反之为假

{

return (S->top==-1?TRUE:FALSE);

}

int IsFull(SeqStack*S) //判断栈S为满栈时返回值为真,反之为假

{

return (S->top==Stack_Size-1?TRUE:FALSE);

}

int IsFullOperand(SeqStackOperand*S) //判断栈S为满栈时返回值为真,反之为假

{

return (S->top==Stack_Size-1?TRUE:FALSE);

}

int Push(SeqStack*S, char x) //运算符栈入栈函数

{

if(S->top==Stack_Size-1)

{

printf("Stack is full!\n");

return FALSE;

}

else

{

S->top++;

S->elem[S->top]=x;

return TRUE;

}

}

int PushOperand(SeqStackOperand*S, int x) //运算数栈入栈函数

{

if(S->top==Stack_Size-1)

{

printf("Stack is full!\n");

return FALSE;

}

else

{

S->top++;

S->elem[S->top]=x;

return TRUE;

}

}

int Pop(SeqStack*S, char *x) //运算符栈出栈函数

{

if(S->top==-1)

{

printf("运算符栈空!\n");

return FALSE;

}

else

{

*x=S->elem[S->top];

S->top--;

return TRUE;

}

}

int PopOperand(SeqStackOperand*S, int *x) //运算数栈出栈函数

{

if(S->top==-1)

{

printf("运算数栈空!\n");

return FALSE;

}

else

{

*x=S->elem[S->top];

S->top--;

return TRUE;

}

}

char GetTop(SeqStack*S) //运算符栈取栈顶元素函数

{

if(S->top==-1)

{

printf("运算符栈空!\n");

return FALSE;

}

else

{

return (S->elem[S->top]);

}

}

int GetTopOperand(SeqStackOperand*S) //运算数栈取栈顶元素函数

{

if(S->top==-1)

{

printf("运算符栈空!\n");

return FALSE;

}

else

{

return (S->elem[S->top]);

}

}

int Isoperator(char ch) //判断输入字符是否为运算符函数,是返回TRUE,不是返回FALSE

{

int i;

for(i=0; i<7; i++)

{

if(ch==ops[i])

return TRUE;

}

return FALSE;

}

char Compare(char ch1, char ch2) //比

 

较运算符优先级函数

{

int i, m, n;

char pri;

int priority;

for(i=0; i<7; i++) //找到相比较的两个运算符在比较矩阵里的相对位置

{

if(ch1==ops[i])

m=i;

if(ch2==ops[i])

n=i;

}

priority=cmp[m][n];

switch(priority)

{

case 1:

pri='<';

break;

case 2:

pri='>';

break;

case 3:

pri='=';

break;

case 0:

pri='$';

printf("表达式错误!\n");

break;

}

return pri;

}

int Execute(int a, char op, int b) //运算函数

{

int result;

switch(op)

{

case '+':

result=a+b;

break;

case '-':

result=a-b;

break;

case '*':

result=a*b;

break;

case '/':

result=a/b;

break;

}

return result;

}

int ExpEvaluation(char *str) //读入一个简单算术表达式并计算其值,operator和operand分别为运算符栈和运算数栈,ops为运算符集合

{

int a, b, v, temp;

char ch, op;

int i=0;

SeqStack operatordata;

SeqStackOperand operand;

InitStack (&operatordata);

InitStacknOperand (&operand);

Push (&operatordata, '#');

ch=*str++;

while(ch!='#' || GetTop(&operatordata)!='#')

{

if(!Isoperator(ch))

{

temp=ch-'0'; //将字符转换为十进制数

ch=*str++;

i++;

while(!Isoperator(ch))

{

temp=temp*10+ch-'0'; //将逐个读入运算符的各位转化为十进制数

ch=*str++;

i++;

}

PushOperand(&operand, temp);

}

else

{

switch(Compare(GetTop(&operatordata), ch))

{

case '<':

Push(&operatordata, ch);

ch=*str++;

i++;

break;

case '=':

Pop(&operatordata, &op);

ch=*str++;

i++;

break;

case '>':

Pop(&operatordata, &op);

PopOperand(&operand, &b);

PopOperand(&operand, &a);

v=Execute(a, op, b);

PushOperand(&operand, v);

break;

}

}

}

v=GetTopOperand(&operand);

return v;

}

 

 

void MainFace()

{

int i, j, ch, n;

initgraph(500, 300);

bar(15, 15, 480, 70);

setcolor(WHITE);

rectangle(10, 10, 490, 290);

setcolor(WHITE);

for(j=0; j<2; j++)

for(i=0; i<7; i++)

{

if(i<3)

circle(55+65*i, 110+65*j, 20);

else

rectangle(55+65*i-20, 110+65*j-20, 55+65*i+20, 110+65*j+20);

}

for(i=0; i<7; i++)

{

if(i<4)

circle(55+65*i, 110+65*j, 20);

else

rectangle(55+65*i-20, 110+65*j-20, 55+65*i+20, 110+65*j+20);

}

 

outtextxy(50, 105, "7");

outtextxy(115, 105, "8");

outtextxy(180, 105, "9");

outtextxy(240, 105, "C");

outtextxy(310, 105, "+");

outtextxy(375, 105, "(");

outtextxy(440, 105, ")");

outtextxy(50, 170, "4");

outtextxy(115, 170, "5");

outtextxy(180, 170, "6");

outtextxy(240, 170, ".");

outtextxy(310, 170, "-");

outtextxy(370, 170, "sqrt");

outtextxy(440, 170, "<-");

outtextxy(50, 235, "3");

outtextxy(115, 235, "2");

outtextxy(180, 235, "1");

outtextxy(240, 235, "0");

outtextxy(310, 235, "*");

outtextxy(370, 235, "/");

outtextxy(440, 235, "=

 

");

}

 

 

void CalFace()

{

int i, j, ch, n;

char string[50]="", str1[50]="", str2[10]="";

MOUSEMSG m; //定义一个鼠标动作

MainFace();

m=GetMouseMsg(); //记录鼠标操作

i=0;

while(true)

{

m=GetMouseMsg(); //记录鼠标操作

if(m.uMsg==WM_LBUTTONDOWN)

{

setcolor(WHITE);

if(m.x>35 && m.x<=75 && m.y>90 && m.y<130)

{

strcat(string, "7");

outtextxy(25, 40, string);

}

if(m.x>100 && m.x<=140 && m.y>90 && m.y<130)

{

strcat(string, "8");

outtextxy(25, 40, string);

}

if(m.x>165 && m.x<=205 && m.y>90 && m.y<130)

{

strcat(string, "9");

outtextxy(25, 40, string);

}

if(m.x>225 && m.x<=265 && m.y>90 && m.y<130)

{

setcolor(WHITE);

bar(15, 15, 480, 70);

strcpy(string, "");

}

if(m.x>290 && m.x<=330 && m.y>90 && m.y<130)

{

strcat(string, "+");

outtextxy(25, 40, string);

}

if(m.x>355 && m.x<=395 && m.y>90 && m.y<130)

{

strcat(string, "(");

outtextxy(25, 40, string);

}

if(m.x>420 && m.x<=460 && m.y>90 && m.y<130)

{

strcat(string, ")");

outtextxy(25, 40, string);

}

if(m.x>35 && m.x<=75 && m.y>155 && m.y<195)

{

strcat(string, "4");

outtextxy(25, 40, string);

}

if(m.x>100 && m.x<=140 && m.y>155 && m.y<195)

{

strcat(string, "5");

outtextxy(25, 40, string);

}

if(m.x>165 && m.x<=205 && m.y>155 && m.y<195)

{

strcat(string, "6");

outtextxy(25, 40, string);

}

if(m.x>225 && m.x<=265 && m.y>155 && m.y<195)

{

strcat(string, ".");

outtextxy(25, 40, string);

}

if(m.x>290 && m.x<=330 && m.y>155 && m.y<195)

{

strcat(string, "-");

outtextxy(25, 40, string);

}

if(m.x>355 && m.x<=395 && m.y>155 && m.y<195)

{

n=strlen(string);

switch(n) //不超过位

{

case 5:

i=string[0]*10000+string[1]*1000+string[2]*100+string[3]*10+string[4];

break;

case 4:

i=string[0]*1000+string[1]*100+string[2]*10+string[3];

break;

case 3:

i=string[0]*100+string[1]*10+string[2];

break;

case 2:

i=string[0]*10+string[1];

break;

case 1:

i=string[0];

break;

}

 

itoa(sqrt(i), string, 10);

setcolor(BLACK);

bar(15, 15, 480, 70);

setcolor(WHITE);

outtextxy(25, 40, string);

}

if(m.x>420 && m.x<=460 && m.y>155 && m.y<195)

{

n=strlen(string);

printf("n=%d.", n);

string[n-1]='\0';

bar(15, 15, 480, 70);

setcolor(WHITE);

outtextxy(25, 40, string);

}

if(m.x>35 && m.x<=75 && m.y>215 && m.y<255)

{

strcat(string, "3");

outtextxy(25, 40, string);

}

if(m.x>100 && m.x<=140 && m.y>215 && m.y<255)

{

strcat(string, "2");

outtextxy(25, 40, string);

}

if(m.x>165 && m.x<=205 && m.y>215 && m.y<255)

{

strcat(string, "1");

outtextxy(25, 40, string);

}

if(m.x>225 && m.x<=265

 

&& m.y>215 && m.y<255)

{

strcat(string, "0");

outtextxy(25, 40, string);

}

if(m.x>290 && m.x<=330 && m.y>215 && m.y<255)

{

strcat(string, "*");

outtextxy(25, 40, string);

}

if(m.x>355 && m.x<=395 && m.y>215 && m.y<255)

{

strcat(string, "/");

outtextxy(25, 40, string);

}

if(m.x>420 && m.x<=460 && m.y>215 && m.y<255)

{

strcpy(str1, string);

strcat(string, "=");

outtextxy(25, 40, string);

strcat(str1, "#");

itoa(ExpEvaluation(str1), str2, 10);

strcat(string, str2);

outtextxy(25, 40, string);

}

}

}

getch(); //按任意键继续

closegraph(); //关闭图形界面

}

 

 

int main(void)

{

CalFace();

return 0;

}

 

#include

#include

#include

#include

#include

#include

#define Stack_Size 50

 

typedef struct

{

char elem[Stack_Size];

int top;

}SepStack;

typedef struct

{

int elem[Stack_Size];

int top;

}SepStackOperand;

typedef struct //运算符栈的定义

{

char elem[Stack_Size];

int top;

}SeqStack;

typedef struct //运算数栈的定义

{

int elem[Stack_Size];

int top;

}SeqStackOperand;

 

 

void CalFace(); //鼠标按键响应

void MainFace(); //界面

char ops[7]={'+', '-', '*', '/', '(', ')', '#'};

int cmp[7][7]=

{

{2,2,1,1,1,2,2},

{2,2,1,1,1,2,2},

{2,2,2,2,1,2,2},

{2,2,2,2,1,2,2},

{1,1,1,1,1,3,0},

{2,2,2,2,0,2,2},

{1,1,1,1,1,0,3}

};

 

 

void InitStack(SeqStack*S) //初始化运算符栈

{

S->top=-1;

}

void InitStacknOperand(SeqStackOperand*S) //初始化运算数栈

{

S->top=-1;

}

int IsEmpty(SeqStack*S) //判断栈S为空栈时返回值为真,反之为假

{

return (S->top==-1?TRUE:FALSE);

}

int IsEmptynOperand(SeqStackOperand*S) //判断栈S为空栈时返回值为真,反之为假

{

return (S->top==-1?TRUE:FALSE);

}

int IsFull(SeqStack*S) //判断栈S为满栈时返回值为真,反之为假

{

return (S->top==Stack_Size-1?TRUE:FALSE);

}

int IsFullOperand(SeqStackOperand*S) //判断栈S为满栈时返回值为真,反之为假

{

return (S->top==Stack_Size-1?TRUE:FALSE);

}

int Push(SeqStack*S, char x) //运算符栈入栈函数

{

if(S->top==Stack_Size-1)

{

printf("Stack is full!\n");

return FALSE;

}

else

{

S->top++;

S->elem[S->top]=x;

return TRUE;

}

}

int PushOperand(SeqStackOperand*S, int x) //运算数栈入栈函数

{

if(S->top==Stack_Size-1)

{

printf("Stack is full!\n");

return FALSE;

}

else

{

S->top++;

S->elem[S->top]=x;

return TRUE;

}

}

int Pop(SeqStack*S, char *x) //运算符栈出栈函数

{

if(S->top==-1)

{

printf("运算符栈空!\n");

return FALSE;

}

else

{

*x=S->elem[S->top];

S->top--;

return TRUE;

}

}

int PopOperand(SeqStackOperand*S, int *x) //运算数栈出栈函数

{

if(S->top==-1)

{

printf("运算数栈空!\n");

return FALSE;

}

else

{

*x=S->elem[S->top];

S->top--;

return TRUE;

}

}

char GetTop(SeqStack*S) //运算符栈取栈顶元素函数

{

if(S->top==-1)

{

printf("运算符栈空!\n");

return FALSE;

}

else

{

return (S->elem[S->top]);

}

}

int GetTopOperand(SeqStackOperand*S) //运算数栈取栈顶元素函数

{

if(S->top==-1)

{

printf("运算符栈空!\n");

return FALSE;

}

else

{

return (S->elem[S->top]);

}

}

int Isoperator(char ch) //判断输入字符是否为运算符函数,是返回TRUE,不是返回FALSE

{

int i;

for(i=0; i<7; i++)

{

if(ch==ops[i])

return TRUE;

}

return FALSE;

}

char Compare(char ch1, char ch2) //比

 

较运算符优先级函数

{

int i, m, n;

char pri;

int priority;

for(i=0; i<7; i++) //找到相比较的两个运算符在比较矩阵里的相对位置

{

if(ch1==ops[i])

m=i;

if(ch2==ops[i])

n=i;

}

priority=cmp[m][n];

switch(priority)

{

case 1:

pri='<';

break;

case 2:

pri='>';

break;

case 3:

pri='=';

break;

case 0:

pri='$';

printf("表达式错误!\n");

break;

}

return pri;

}

int Execute(int a, char op, int b) //运算函数

{

int result;

switch(op)

{

case '+':

result=a+b;

break;

case '-':

result=a-b;

break;

case '*':

result=a*b;

break;

case '/':

result=a/b;

break;

}

return result;

}

int ExpEvaluation(char *str) //读入一个简单算术表达式并计算其值,operator和operand分别为运算符栈和运算数栈,ops为运算符集合

{

int a, b, v, temp;

char ch, op;

int i=0;

SeqStack operatordata;

SeqStackOperand operand;

InitStack (&operatordata);

InitStacknOperand (&operand);

Push (&operatordata, '#');

ch=*str++;

while(ch!='#' || GetTop(&operatordata)!='#')

{

if(!Isoperator(ch))

{

temp=ch-'0'; //将字符转换为十进制数

ch=*str++;

i++;

while(!Isoperator(ch))

{

temp=temp*10+ch-'0'; //将逐个读入运算符的各位转化为十进制数

ch=*str++;

i++;

}

PushOperand(&operand, temp);

}

else

{

switch(Compare(GetTop(&operatordata), ch))

{

case '<':

Push(&operatordata, ch);

ch=*str++;

i++;

break;

case '=':

Pop(&operatordata, &op);

ch=*str++;

i++;

break;

case '>':

Pop(&operatordata, &op);

PopOperand(&operand, &b);

PopOperand(&operand, &a);

v=Execute(a, op, b);

PushOperand(&operand, v);

break;

}

}

}

v=GetTopOperand(&operand);

return v;

}

 

 

void MainFace()

{

int i, j, ch, n;

initgraph(500, 300);

bar(15, 15, 480, 70);

setcolor(WHITE);

rectangle(10, 10, 490, 290);

setcolor(WHITE);

for(j=0; j<2; j++)

for(i=0; i<7; i++)

{

if(i<3)

circle(55+65*i, 110+65*j, 20);

else

rectangle(55+65*i-20, 110+65*j-20, 55+65*i+20, 110+65*j+20);

}

for(i=0; i<7; i++)

{

if(i<4)

circle(55+65*i, 110+65*j, 20);

else

rectangle(55+65*i-20, 110+65*j-20, 55+65*i+20, 110+65*j+20);

}

 

outtextxy(50, 105, "7");

outtextxy(115, 105, "8");

outtextxy(180, 105, "9");

outtextxy(240, 105, "C");

outtextxy(310, 105, "+");

outtextxy(375, 105, "(");

outtextxy(440, 105, ")");

outtextxy(50, 170, "4");

outtextxy(115, 170, "5");

outtextxy(180, 170, "6");

outtextxy(240, 170, ".");

outtextxy(310, 170, "-");

outtextxy(370, 170, "sqrt");

outtextxy(440, 170, "<-");

outtextxy(50, 235, "3");

outtextxy(115, 235, "2");

outtextxy(180, 235, "1");

outtextxy(240, 235, "0");

outtextxy(310, 235, "*");

outtextxy(370, 235, "/");

outtextxy(440, 235, "=

 

");

}

 

 

void CalFace()

{

int i, j, ch, n;

char string[50]="", str1[50]="", str2[10]="";

MOUSEMSG m; //定义一个鼠标动作

MainFace();

m=GetMouseMsg(); //记录鼠标操作

i=0;

while(true)

{

m=GetMouseMsg(); //记录鼠标操作

if(m.uMsg==WM_LBUTTONDOWN)

{

setcolor(WHITE);

if(m.x>35 && m.x<=75 && m.y>90 && m.y<130)

{

strcat(string, "7");

outtextxy(25, 40, string);

}

if(m.x>100 && m.x<=140 && m.y>90 && m.y<130)

{

strcat(string, "8");

outtextxy(25, 40, string);

}

if(m.x>165 && m.x<=205 && m.y>90 && m.y<130)

{

strcat(string, "9");

outtextxy(25, 40, string);

}

if(m.x>225 && m.x<=265 && m.y>90 && m.y<130)

{

setcolor(WHITE);

bar(15, 15, 480, 70);

strcpy(string, "");

}

if(m.x>290 && m.x<=330 && m.y>90 && m.y<130)

{

strcat(string, "+");

outtextxy(25, 40, string);

}

if(m.x>355 && m.x<=395 && m.y>90 && m.y<130)

{

strcat(string, "(");

outtextxy(25, 40, string);

}

if(m.x>420 && m.x<=460 && m.y>90 && m.y<130)

{

strcat(string, ")");

outtextxy(25, 40, string);

}

if(m.x>35 && m.x<=75 && m.y>155 && m.y<195)

{

strcat(string, "4");

outtextxy(25, 40, string);

}

if(m.x>100 && m.x<=140 && m.y>155 && m.y<195)

{

strcat(string, "5");

outtextxy(25, 40, string);

}

if(m.x>165 && m.x<=205 && m.y>155 && m.y<195)

{

strcat(string, "6");

outtextxy(25, 40, string);

}

if(m.x>225 && m.x<=265 && m.y>155 && m.y<195)

{

strcat(string, ".");

outtextxy(25, 40, string);

}

if(m.x>290 && m.x<=330 && m.y>155 && m.y<195)

{

strcat(string, "-");

outtextxy(25, 40, string);

}

if(m.x>355 && m.x<=395 && m.y>155 && m.y<195)

{

n=strlen(string);

switch(n) //不超过位

{

case 5:

i=string[0]*10000+string[1]*1000+string[2]*100+string[3]*10+string[4];

break;

case 4:

i=string[0]*1000+string[1]*100+string[2]*10+string[3];

break;

case 3:

i=string[0]*100+string[1]*10+string[2];

break;

case 2:

i=string[0]*10+string[1];

break;

case 1:

i=string[0];

break;

}

 

itoa(sqrt(i), string, 10);

setcolor(BLACK);

bar(15, 15, 480, 70);

setcolor(WHITE);

outtextxy(25, 40, string);

}

if(m.x>420 && m.x<=460 && m.y>155 && m.y<195)

{

n=strlen(string);

printf("n=%d.", n);

string[n-1]='\0';

bar(15, 15, 480, 70);

setcolor(WHITE);

outtextxy(25, 40, string);

}

if(m.x>35 && m.x<=75 && m.y>215 && m.y<255)

{

strcat(string, "3");

outtextxy(25, 40, string);

}

if(m.x>100 && m.x<=140 && m.y>215 && m.y<255)

{

strcat(string, "2");

outtextxy(25, 40, string);

}

if(m.x>165 && m.x<=205 && m.y>215 && m.y<255)

{

strcat(string, "1");

outtextxy(25, 40, string);

}

if(m.x>225 && m.x<=265

 

&& m.y>215 && m.y<255)

{

strcat(string, "0");

outtextxy(25, 40, string);

}

if(m.x>290 && m.x<=330 && m.y>215 && m.y<255)

{

strcat(string, "*");

outtextxy(25, 40, string);

}

if(m.x>355 && m.x<=395 && m.y>215 && m.y<255)

{

strcat(string, "/");

outtextxy(25, 40, string);

}

if(m.x>420 && m.x<=460 && m.y>215 && m.y<255)

{

strcpy(str1, string);

strcat(string, "=");

outtextxy(25, 40, string);

strcat(str1, "#");

itoa(ExpEvaluation(str1), str2, 10);

strcat(string, str2);

outtextxy(25, 40, string);

}

}

}

getch(); //按任意键继续

closegraph(); //关闭图形界面

}

 

 

int main(void)

{

CalFace();

return 0;

}

转载于:https://www.cnblogs.com/qhj123456/p/7747918.html

你可能感兴趣的:(简易四则运算)