0

I am coding an engineering calculator in C and in in-fix to post-fix conversion which I coded an state-machine for it, I am using shunting-yard algorithm. In order to handle floating point numbers, I decided to use a stack with double blocks for the output. But data crashes and I don't know what's the problem with my conversions.

Can anyone spot the problem with that or suggest a better way to handle floating point numbers?

here's that part of the code (I really tried to narrate down the problem as much as I could):

unsigned short int infixToPostfix (void)
{
    /* automata 2:
       [states: 0 = home-point, 1 = rational number, 2 = point, 3 = decimal number, 4 = x,
            5 = unary operater, 6 = binary operator, 7 = opened-paranthesis, 8 = closed-paranthesis, 9 = goal-point.]
       [events: 0 = number, 1 = point, 2 = x, 3 = unary operator, 4 = binary operator, 5 = opened-paranthesis, 6 = closed-paranthesis, 7 = empty stack.] */
    short int CURRENT_STATE_2 = 0, MAX_STATE_2 = 8;
    void (*P_2[10])(void);
    P_2[0] = state_2_0;
    P_2[1] = state_2_1;
    P_2[2] = state_2_2;
    P_2[3] = state_2_3;
    P_2[4] = state_2_4;
    P_2[5] = state_2_5;
    P_2[6] = state_2_6;
    P_2[7] = state_2_7;
    P_2[8] = state_2_8;
    P_2[9] = state_2_9;
    short int PT_2[9][8] = {{ 1,  2,  4,  5, -1,  7, -1, 9},
                            { 1,  2,  4, -1,  6, -1,  8, 9},
                            { 3, -1, -1, -1, -1, -1, -1, 9},
                            { 3, -1, -1, -1,  6, -1,  8, 9},
                            {-1, -1, -1, -1,  6, -1,  8, 9},
                            { 1,  2,  4, -1, -1,  7, -1, 9},
                            { 1,  2,  4,  5, -1,  7, -1, 9},
                            { 1,  2,  4,  5, -1,  7, -1, 9},
                            {-1, -1, -1, -1,  6, -1,  8, 9}};
    ERROR = 0;

    while(0 <= CURRENT_STATE_2 && CURRENT_STATE_2 <= MAX_STATE_2)
    {
        short int EVENT = getEvent_2();
        CURRENT_STATE_2 = PT_2[CURRENT_STATE_2][EVENT];
        if(CURRENT_STATE_2 >=0) P_2[CURRENT_STATE_2]();
    }

    //checking the correctness of the queue
    if(CURRENT_STATE_2 < 0 || ERROR)
    {
        char *NOTE = "SYNTAX ERROR.";
        for(int j = 0; j < 13; j++)
            SCREEN.setData(4, j + 18, *(NOTE + j), 0, 0, 7, 0);
        getch();
        showStack();
    }
    else
        return 1;
}

void state_2_0 (void){}
void state_2_1 (void)
{
    if(RATIONAL == 1)
    {
        OUTPUT.push((double)TOKEN);
        RATIONAL = RATIONAL * 10;
    }
    else
    {
        OUTPUT.character[OUTPUT.top] = OUTPUT.character[OUTPUT.top] * RATIONAL + (double) TOKEN;
        RATIONAL = RATIONAL * 10;
    }
}
void state_2_2 (void){}
void state_2_3 (void)
{
    if(RATIONAL == 1 && DECIMAL == 1)
    {
        DECIMAL = DECIMAL / 10;
        OUTPUT.push((double)TOKEN * DECIMAL);
    }
    else
    {
        DECIMAL = DECIMAL / 10;
        OUTPUT.character[OUTPUT.top] += (double)TOKEN * DECIMAL;
    }
}
void state_2_4 (void)
{
    RATIONAL = 1.0; DECIMAL = 1.0;
    OUTPUT.push((double)TOKEN);
}
void state_2_5 (void)
{
    RATIONAL = 1.0; DECIMAL = 1.0;
    OPERATOR.push(TOKEN);
}
void state_2_6 (void)
{
    RATIONAL = 1.0; DECIMAL = 1.0;
    unsigned short int PROCEDURE_TOKEN = 0, ASSOCIATIVITY_TOKEN = 0;
    switch(TOKEN)
    {
        case '+':
        case '-':
            PROCEDURE_TOKEN = 0; //lower.
            ASSOCIATIVITY_TOKEN = 0; //left to right.
            break;
        case '*':
        case '/':
        case '%':
            PROCEDURE_TOKEN = 1; //normal.
            ASSOCIATIVITY_TOKEN = 0; //left to right.
            break;
        case '^':
            PROCEDURE_TOKEN = 2; //higher.
            ASSOCIATIVITY_TOKEN = 1; //right to left.
            break;
    }

    unsigned short int FLAG;
    do
    {
        FLAG = 0;
        if(!OPERATOR.isEmpty())
        {
            unsigned short int PROCEDURE_QUEUE = 0;
            switch(OPERATOR.character[OPERATOR.top])
            {
                case '+':
                case '-':
                    PROCEDURE_QUEUE = 0; //lower.
                    break;
                case '*':
                case '/':
                case '%':
                    PROCEDURE_QUEUE = 1; //normal.
                    break;
                case '^':
                    PROCEDURE_QUEUE = 2; //higher.
                    break;
            }
            if(PROCEDURE_TOKEN < PROCEDURE_QUEUE || ((PROCEDURE_TOKEN == PROCEDURE_QUEUE) && (!ASSOCIATIVITY_TOKEN)))
            {
                OUTPUT.push((double)OPERATOR.pop());
                FLAG = 1;
            }
        }
    }
    while(FLAG);

    OPERATOR.push(TOKEN);
}
void state_2_7 (void)
{
    RATIONAL = 1.0; DECIMAL = 1.0;
    OPERATOR.push(TOKEN);
}
void state_2_8 (void)
{
    RATIONAL = 1.0; DECIMAL = 1.0;

    unsigned short int FLAG = 0;
    while(OPERATOR.character[OPERATOR.top] != '(')
    {
        OUTPUT.push(OPERATOR.pop());
        FLAG = 1;
    }

    //discarding paranthesis
    OPERATOR.pop();

    if(FLAG)
    {
        switch(OPERATOR.character[OPERATOR.top])
        {
            case 's':
            case 'c':
            case 't':
            case 'o':
            case 'l':
            case 'r':
            case 'p':
            case 'n':
                OUTPUT.push(OPERATOR.pop());
        }
    }
    else
        ERROR = 1;
}
void state_2_9 (void)
{
    while(!OPERATOR.isEmpty())
    {
        if(OPERATOR.character[OPERATOR.top] == ')' || OPERATOR.character[OPERATOR.top] == '(')
            ERROR = 1;
        else
            OUTPUT.push(OPERATOR.pop());
    }
}

short int getEvent_2 (void)
{
    short int EVENT;
    if(!R.isEmpty())
    {
        TOKEN = R.pop();
        if((TOKEN == '+' || TOKEN == '-') && !(48 <= R.character[R.top] && R.character[R.top] <= 57))
        {
            if(TOKEN == '+')
                TOKEN = 'p';
            else
                TOKEN = 'n';
        }
        switch(TOKEN)
        {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                EVENT = 0;
                break;
            case '.':
                EVENT = 1;
                break;
            case 'x':
                EVENT = 2;
                break;
            case 's':
            case 'c':
            case 't':
            case 'o':
            case 'l':
            case 'r':
            case 'p':
            case 'n':
                EVENT = 3;
                break;
            case '+':
            case '-':
            case '*':
            case '/':
            case '%':
                EVENT = 4;
                break;
            case '(':
                EVENT = 5;
                break;
            case ')':
                EVENT = 6;
                break;
        }
    }
    else
        EVENT = 7;
    return EVENT;
}
Melika Barzegaran
  • 429
  • 2
  • 9
  • 25
  • So have you debugged it enough to narrow it down to a function or section of code? – ChiefTwoPencils Feb 14 '14 at 09:16
  • yeah. I also have got through this section of code. and I've understood, data crashes while conversion `char` to `double` and I don't understand why. I think the problem is with that. and I think which I coded is correct. that's why I asked for other ways to handle that if anyone can suggest. – Melika Barzegaran Feb 14 '14 at 09:18
  • The operator? Why are you casting the operator to a double? – ChiefTwoPencils Feb 14 '14 at 09:23
  • coz I have floating point numbers and I need my `output stack` to hold them both. both numbers and operators. – Melika Barzegaran Feb 14 '14 at 09:25
  • I think you'd be better off with a token `struct` and tokenize the input. That way you'll know if it is a operand, operator, function, etc. *and* you can store them in the same data structure w/o the funny business. What you end up with is a postfix equation of tokens. As you pop 'em off, check if they're operators. – ChiefTwoPencils Feb 14 '14 at 09:35
  • In that way, how can I have the output stack? you know in shunting-yard algorithm there is a output stack which should hold both operand and operators. On that way which you suggest how I can know the procedure of operands and operators in output stack? – Melika Barzegaran Feb 14 '14 at 09:38
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/47489/discussion-between-bobbydigital-and-melika-barzegaran-hosseini) – ChiefTwoPencils Feb 14 '14 at 09:39

0 Answers0