您的位置:首页 > 其它

使用栈的表达式计算程序.arith_expr.c

2006-11-14 11:38 309 查看
#include<stdio.h>

#include "arith_expr.h"

#include<assert.h>
#include<ctype.h>
#include<stdlib.h>
#ifndef True
#define True 1
#define False 0
#endif
#define NS_LEN 100
#define OS_LEN 100

struct ns
{
    struct NUM nums[NS_LEN];
    int top;
};

struct os
{
    char  ops[OS_LEN];
    int top ;
};

struct os opstack;
struct ns numstack;

FILE * listing;
char * str ;
int pos;

void setNum(struct NUM * pn1,struct NUM * pn2)
{
    pn1->type = pn2->type;
    if (pn1->type == 0)
        pn1->value.ivalue = pn2->value.ivalue;
    else if (pn1->type == 1)
        pn1->value.fvalue = pn2->value.fvalue;
};

int nspush(struct NUM *num)
{
    int rel = False;
    (numstack.top)++;

    if (numstack.top == NS_LEN)
        fprintf(listing,"push error:the number stack is full/n");
    else
    {
        (numstack.nums[numstack.top]).type = num->type;
        (numstack.nums[numstack.top]).value = num->value;   // 
        rel =True;
    }
    return(rel);
};

int nspop(struct NUM *num)
{
    int rel = False;
    if (numstack.top <0)
        fprintf(listing,"error:the number stack is empty to pop/n");
    else
    {
        num->type = numstack.nums[numstack.top].type;
        num->value = numstack.nums[numstack.top].value;
        rel = True;
    }

    return(rel);
};

char getNextChar()
{
    return(str[pos++]);
};

void ungetNextChar()
{ pos--;
};   

void getNum(char c)
{
    char strvalue[50];
    int i,pointnum=0;
    struct NUM num;
   
    i = 0;
    while (isdigit(c)&&i<=49)
    {   
        strvalue[i++] = c;
        c = getNextChar();
    }   
    if (c=='.'&&pointnum==0)
    {
        pointnum++;
        strvalue[i++] = c;
        c = getNextChar();
        if (!isdigit(c))
        {   
            fprintf(listing,"error.this num has a point .it may be a float,but after the point there is no digit/n ");
            return;
        }   
        while(isdigit(c))   
        {

            strvalue[i++] = c;
            c = getNextChar();
        }
    }   
    else if (c=='.'&&pointnum==1)
    {
        fprintf(listing,"error:tow points/n");
        return;
    }   
    ungetNextChar();
    strvalue[i] = '/0';
   

    if (pointnum==0)
    {   
        num.type = 0;  // integer
        num.value.ivalue = strtol(strvalue,(char **)NULL,10);
    }   
    else
    {   
        num.type = 1;  // float
        num.value.fvalue = strtof(strvalue,(char**)NULL);

    }   
   
    nspush(&num);
};          

int ospush(char op)
{
    opstack.top++;
    if (opstack.top == OS_LEN)
    {
        fprintf(listing,"sorry,the operation statc is full,can not push/n");
        return(False);
    }
    opstack.ops[opstack.top] = op;
    return(1);
};
int ospop(char *op)
{
    if (opstack.top<0)
    {
        fprintf(listing,"The operation stack is empty.can  not pop/n");
        return(False);
    }
    *op = opstack.ops[opstack.top--];
    return(1);
};

void displayns()   // to  debug
{
    int i = 0 ;
    while (i <=numstack.top)
    {
        if (numstack.nums[i].type == 1)
            fprintf(listing,"%4.2f/n",numstack.nums[i].value.fvalue);
        else
           
            fprintf(listing,"%4d/n",numstack.nums[i].value.ivalue);
        i++;
    }   
};
void displayos()  // to debug
{
    int i=0;
           while(i<=opstack.top)
    {
        printf("%c  top = %-3d/n",opstack.ops[i],opstack.top);
        i++;
    }
};   

int getPriority(char c)
{
    if (c =='+'||c=='-')
        return(0);
    else if (c=='*'||c=='/')
        return(1);
    else if (c=='('||c==')')
        return(2);
    else
        return(-1);
};

int IsHigh(char src,char des)
{
    int s_prio,d_prio;

    s_prio = getPriority(src);
    d_prio = getPriority(des);   
   
    if (s_prio < d_prio)
        return(-1);
    else if (s_prio == d_prio)
        return(0);
    else
        return(1);
};
void operate_int(int x1,int x2,char c)
{
    switch (c)
    {
        case '+':
            numstack.nums[numstack.top].value.ivalue = x1+x2;
            return;
        case '-':   
            numstack.nums[numstack.top].value.ivalue = x1-x2;
            return;
        case '*':
            numstack.nums[numstack.top].value.ivalue = x1*x2;
            return;
        case '/':
            numstack.nums[numstack.top].value.ivalue = x1/x2;
            return;
    }   

};

void operate_float(float y1,float y2,char c)
{
    switch(c)
    {
        case '+':
            numstack.nums[numstack.top].value.fvalue = y1+y2;
            return;
        case '-':   
            numstack.nums[numstack.top].value.fvalue = y1-y2;
            return;
        case '*':
            numstack.nums[numstack.top].value.fvalue = y1*y2;
            return;
        case '/':
            numstack.nums[numstack.top].value.fvalue = y1/y2 ;
            return;
    }    
};

void operate()   // pop tow from number stack
{
    int x1,x2;
    float y1,y2;
    char c;
   
    ospop(&c);  
    if (numstack.nums[numstack.top].type==0 && numstack.nums[numstack.top-1].type==0)  //integers
    {
        x2 = numstack.nums[numstack.top--].value.ivalue;
        x1 = numstack.nums[numstack.top].value.ivalue;
        operate_int(x1,x2,c);
    }   
    else
    {          
        if (numstack.nums[numstack.top].type==0)
            y2 = (float)(numstack.nums[numstack.top--].value.ivalue);
        else
            y2 =numstack.nums[numstack.top--].value.fvalue;
        if (numstack.nums[numstack.top].type==0)
            y1 = (float)(numstack.nums[numstack.top].value.ivalue);
        else
            y1 = numstack.nums[numstack.top].value.fvalue;
        numstack.nums[numstack.top].type = 1;
        operate_float(y1,y2,c);
    }//is    
   
};

void getOp(char c)
{
    int temp;
    char ch;

    if (c=='/0')
    {
        while (opstack.top>-1)
            operate();
        return;   
    }
   
   
    if (c=='(')
        ospush(c);
    else if (c==')')
    {
        operate();
        ospop(&c);// pop the '('
        if (opstack.top<0)  // empty stack
            return;
    }
    else
    {
        if (opstack.top<0)  // empty stack
        {
            ospush(c);
            return;
        }   
   
        temp = getPriority(opstack.ops[opstack.top]); 
        if (temp == 2)
        {
            ospush(c);
            return;
        }
       
        temp = IsHigh(opstack.ops[opstack.top],c);
   
        while(temp>=0)
        {   
   
            operate();    // has poped one item
            if (opstack.top<0)  // empty stack
            {
                ospush(c);
                return;
            }   
            temp = IsHigh(opstack.ops[opstack.top],c);
       
        }
        if (temp<0)
            ospush(c);
    }
};   

void init(FILE * fp,char * expr_str)
{
    listing = fp;
    str = expr_str;
    pos = 0;
    numstack.top = -1;
    opstack.top = -1;
};

struct NUM * compute()  
{
    char c;
    struct NUM * result = NULL;

    c= getNextChar();
    if (!(isdigit(c)|| c=='('||c==')'))
    {   
        printf("error:the first character is not a digit/n");
        return(result);
    }   

    while (c!='/0')
    {   
        if (isdigit(c))
            getNum(c);
        else if (c=='+'||c=='-'||c=='*'||c=='('||c==')')
            getOp(c);
        c = getNextChar();
    }
    getOp(c);

    result = (struct NUM * )malloc(sizeof(struct NUM  ));
    assert(result != NULL);
    setNum(result,numstack.nums+numstack.top);

    return(result);   
};

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐