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;
}