编译器中的表达式求值问题实验
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef char* ElementType;
typedef struct SNode* PtrToSNode;
struct SNode {
ElementType Data;
PtrToSNode Next;
};
typedef PtrToSNode Stack;
Stack CreateStack(void);
int IsEmpty_Stack(Stack);
void Push(Stack, ElementType);
ElementType Pop(Stack);
ElementType GetStackTop(Stack);
int Arith(char*);
ElementType* CreateExpS(char*);
int IsNumber(ElementType);
int Compare(ElementType, ElementType);
int ChToNum(ElementType);
ElementType NumToCh(int);
int Math(int, ElementType, int);
int FindValue(ElementType);
int main(void)
{
char* Expression;
int Ans;
Expression = (char*)malloc(sizeof(char)*100);
scanf("%s", Expression);
Ans = Arith(Expression);
printf("%d", Ans);
return 0;
}
int Arith(char* Expression)
{
ElementType* ExpS;
Stack OpS;
Stack NumS;
int Front;
int Rear;
int Ans;
ElementType Op;
int Index = 0;
OpS = CreateStack();
NumS = CreateStack();
ExpS = CreateExpS(Expression);
Push(OpS, ExpS[Index]);
Index++;
do {
if(IsNumber(ExpS[Index]))
Push(NumS,ExpS[Index++]);
else {
if (Compare(ExpS[Index], GetStackTop(OpS))==-1) {
Push(OpS, ExpS[Index]);
Index++;
}
else if (Compare(ExpS[Index], GetStackTop(OpS))==1) {
Rear = ChToNum(Pop(NumS));
Front = ChToNum(Pop(NumS));
Op = Pop(OpS);
Ans = Math(Front, Op, Rear);
Push(NumS, NumToCh(Ans));
}
if (Compare(ExpS[Index], GetStackTop(OpS))==0) {
Pop(OpS);
Index++;
}
}
} while (!IsEmpty_Stack(OpS));
return ChToNum(Pop(NumS));
}
ElementType* CreateExpS(char* Expression)
{
int index = 0;
int i;
int j;
char* Element;
i = 0;
j = 1;
ElementType* ExpS;
ExpS = (ElementType*)malloc(sizeof(ElementType) * 100);
Element = (char*)malloc(sizeof(char) * 2);
Element[0] = '#';
Element[1] = '\0';
ExpS[index++] = Element;
if (Expression[i] == '-') {
Element = (char*)malloc(sizeof(char) * 10);
Element[0] = '-';
i++;
for (; '0' <= Expression[i] && Expression[i] <= '9'; i++)
Element[j++] = Expression[i];
Element[j] = '\0';
ExpS[index++] = Element;
}
while (Expression[i] != '\0') {
if (Expression[i] == '(' && Expression[i + 1] == '-') {
Element = (char*)malloc(sizeof(char) * 10);
j = 1;
Element[0] = '-';
for (i += 2; '0' <= Expression[i] && Expression[i] <= '9'; i++)
Element[j++] = Expression[i];
i ++;
Element[j] = '\0';
ExpS[index++] = Element;
}
else if (Expression[i] <= '0' || '9' <= Expression[i]) {
Element = (char*)malloc(sizeof(char) * 2);
Element[0] = Expression[i];
Element[1] = '\0';
i++;
ExpS[index++] = Element;
}
else {
j = 0;
Element = (char*)malloc(sizeof(char) * 10);
for (; '0' <= Expression[i] && Expression[i] <= '9'; i++)
Element[j++] = Expression[i];
Element[j] = '\0';
ExpS[index++] = Element;
}
}
Element = (char*)malloc(sizeof(char) * 2);
Element[0] = '#';
Element[1] = '\0';
ExpS[index++] = Element;
return ExpS;
}
int IsNumber(ElementType Exp)
{
if (('0' <= Exp[1] && Exp[1] <= '9') || ('0' <= Exp[0] && Exp[0] <= '9'))
return 1;
else
return 0;
}
int Compare(ElementType ExpTop, ElementType OpTop)
{
int ExpN;
int OpN;
ExpN = FindValue(ExpTop);
OpN = FindValue(OpTop);
int Map[7][7] = {
{1,1,-1,-1,-1,1,1},
{1,1,-1,-1,-1,1,1},
{1,1,1,1,-1,1,1},
{1,1,1,1,-1,1,1},
{-1,-1,-1,-1,-1,0,0},
{1,1,1,1,0,1,1},
{-1,-1,-1,-1,-1,0,0} };
return Map[OpN][ExpN];
}
int ChToNum(ElementType Num)
{
int N = 0;
int i = 0;
int Op = 1;
if (Num[0] == '-') {
Op = -1;
i++;
}
for (; Num[i] != '\0'; i++)
N = N * 10 + Num[i] - '0';
return N * Op;
}
ElementType NumToCh(int Str)
{
ElementType N;
Stack S;
char* String;
ElementType Ch;
int i = 0;
String = (char*)malloc(sizeof(char) * 10);
if (Str < 0) {
Str = -Str;
String[i++] = '-';
}
S = CreateStack();
while (Str != 0) {
N = (char*)malloc(sizeof(char) * 2);
N[0] = '0'+ Str % 10;
N[1] = '\0';
Push(S, N);
Str /= 10;
}
while (!IsEmpty_Stack(S)) {
Ch = Pop(S);
String[i++] = Ch[0];
}
String[i] = '\0';
return String;
}
int Math(int Front, ElementType Op, int Rear)
{
switch (Op[0])
{
case '+': return Front + Rear;
case '-': return Front - Rear;
case '*': return Front * Rear;
case '/': return Front / Rear;
case '(': return -1;
case ')': return -1;
case '#': return -1;
default:
return -1;
}
}
int FindValue(ElementType Op)
{
switch (Op[0])
{
case '+': return 0;
case '-': return 1;
case '*': return 2;
case '/': return 3;
case '(': return 4;
case ')': return 5;
case '#': return 6;
default:
return -1;
}
}
Stack CreateStack(void)
{
Stack S = (Stack)malloc(sizeof(struct SNode));
S->Next = NULL;
return S;
}
int IsEmpty_Stack(Stack S)
{
return (S->Next == NULL);
}
void Push(Stack S, ElementType Sdata)
{
PtrToSNode P;
P = (PtrToSNode)malloc(sizeof(struct SNode));
P->Data = Sdata;
P->Next = S->Next;
S->Next = P;
}
ElementType Pop(Stack S)
{
if (IsEmpty_Stack(S)) {
printf("The Stack is Empty.");
return NULL;
}
else {
PtrToSNode P;
ElementType Sdata;
P = S->Next;
Sdata = P->Data;
S->Next = P->Next;
free(P);
return Sdata;
}
}
ElementType GetStackTop(Stack S)
{
if (IsEmpty_Stack(S)) {
printf("The Stack is empty.");
return NULL;
}
else
return S->Next->Data;
}