2020-09-30 18:04:51 +03:00
|
|
|
/**
|
2020-10-01 08:12:41 +03:00
|
|
|
* @file
|
2020-10-21 12:09:08 +03:00
|
|
|
* @brief [Infix to
|
|
|
|
* Postfix](https://condor.depaul.edu/ichu/csc415/notes/notes9/Infix.htm)
|
|
|
|
* Expression Conversion
|
2020-09-30 18:04:51 +03:00
|
|
|
* @details Convert Infixed expressions to Postfix expression.
|
|
|
|
* @author [Harsh Karande](https://github.com/harshcut)
|
|
|
|
*/
|
|
|
|
|
2020-10-02 10:17:20 +03:00
|
|
|
// include header files
|
2020-10-20 07:26:59 +03:00
|
|
|
#include <stdio.h> /// for printf() and scanf()
|
2020-09-30 18:04:51 +03:00
|
|
|
|
2020-10-21 12:09:08 +03:00
|
|
|
/**
|
|
|
|
* @brief a globally declared structure with an array and an variable that
|
|
|
|
* points to the topmost index of the array
|
|
|
|
*/
|
2020-09-30 18:04:51 +03:00
|
|
|
struct Stack
|
|
|
|
{
|
2020-10-21 07:47:00 +03:00
|
|
|
char arr[10]; ///> static array of integers
|
|
|
|
int tos; ///> stores index on topmost element in stack
|
2020-09-30 18:04:51 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
// function headers
|
|
|
|
void push(struct Stack *p, char ch); // pust element in stack
|
|
|
|
char pop(struct Stack *p); // pop topmost element from the stack
|
2020-10-01 08:12:41 +03:00
|
|
|
int isOprnd(char ch); // check if element is operand or not
|
2020-09-30 18:04:51 +03:00
|
|
|
int isEmpty(struct Stack s); // check if stack is empty
|
2021-02-11 07:59:16 +03:00
|
|
|
int getPrecedence (char op1, char op2); // check operator precedence
|
2020-09-30 18:04:51 +03:00
|
|
|
void convert(char infix[],
|
|
|
|
char postfix[]); // convert infix to postfix expression
|
|
|
|
|
|
|
|
/**
|
2020-10-01 08:12:41 +03:00
|
|
|
* @brief main function
|
2020-09-30 18:04:51 +03:00
|
|
|
* @returns 0 on exit
|
|
|
|
*/
|
|
|
|
int main()
|
|
|
|
{
|
2020-10-01 08:12:41 +03:00
|
|
|
char infix[20], postfix[20]; // initialize empty infix and postfix array
|
2020-09-30 18:04:51 +03:00
|
|
|
|
2020-10-01 08:12:41 +03:00
|
|
|
printf("Enter infix expression: "); // example : A+B-C*D/E$F
|
|
|
|
scanf("%s", infix); // get values for infix array
|
2020-09-30 18:04:51 +03:00
|
|
|
|
|
|
|
convert(infix, postfix);
|
2020-10-01 08:12:41 +03:00
|
|
|
printf("Postfix expression is %s", postfix); // output : AB+CD*EF$/-
|
2020-09-30 18:04:51 +03:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief push function
|
2020-10-01 08:12:41 +03:00
|
|
|
* @param *p : used as a pointer variable of stack
|
|
|
|
* @param x : char to be pushed in stack
|
2020-09-30 18:04:51 +03:00
|
|
|
* @returns void
|
|
|
|
*/
|
|
|
|
void push(struct Stack *p, char x)
|
|
|
|
{
|
2020-10-01 08:12:41 +03:00
|
|
|
if (p->tos == 9) // check if stack has reached its max limit
|
2020-09-30 18:04:51 +03:00
|
|
|
{
|
|
|
|
printf("Stack Overflow!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-10-01 08:12:41 +03:00
|
|
|
p->tos += 1; // increment tos
|
|
|
|
p->arr[p->tos] = x; // assign char x to index of stack pointed by tos
|
2020-09-30 18:04:51 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief pop function
|
2020-10-01 08:12:41 +03:00
|
|
|
* @param *p : used as a pointer variable of stack
|
2020-09-30 18:04:51 +03:00
|
|
|
* @returns x or \0 on exit
|
|
|
|
*/
|
|
|
|
char pop(struct Stack *p)
|
|
|
|
{
|
|
|
|
char x;
|
|
|
|
|
|
|
|
if (p->tos == -1)
|
|
|
|
{
|
|
|
|
printf("Stack Underflow!");
|
|
|
|
return '\0';
|
|
|
|
}
|
|
|
|
|
2020-10-01 08:12:41 +03:00
|
|
|
x = p->arr[p->tos]; // assign the value of stack at index tos to x
|
|
|
|
p->tos -= 1; // decrement tos
|
2020-09-30 18:04:51 +03:00
|
|
|
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief isOprnd function
|
2020-10-01 08:12:41 +03:00
|
|
|
* @param ch : this is the element from the infix array
|
2020-09-30 18:04:51 +03:00
|
|
|
* @returns 1 or 0 on exit
|
|
|
|
*/
|
|
|
|
int isOprnd(char ch)
|
|
|
|
{
|
2020-10-01 08:12:41 +03:00
|
|
|
if ((ch >= 65 && ch <= 90) ||
|
|
|
|
(ch >= 97 && ch <= 122) || // check if ch is an operator or
|
|
|
|
(ch >= 48 && ch <= 57)) // operand using ASCII values
|
2020-09-30 18:04:51 +03:00
|
|
|
{
|
2020-10-01 08:12:41 +03:00
|
|
|
return 1; // return for true result
|
2020-09-30 18:04:51 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-10-01 08:12:41 +03:00
|
|
|
return 0; // return for false result
|
2020-09-30 18:04:51 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief isEmpty function
|
2020-10-01 08:12:41 +03:00
|
|
|
* @param s : it is the object reference of stack
|
2020-09-30 18:04:51 +03:00
|
|
|
* @returns 1 or 0 on exit
|
|
|
|
*/
|
|
|
|
int isEmpty(struct Stack s)
|
|
|
|
{
|
2020-10-01 08:12:41 +03:00
|
|
|
if (s.tos == -1) // check if stack is empty
|
2020-09-30 18:04:51 +03:00
|
|
|
{
|
2020-10-01 08:12:41 +03:00
|
|
|
return 1; // return for true result
|
2020-09-30 18:04:51 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-10-01 08:12:41 +03:00
|
|
|
return 0; // return for false result
|
2020-09-30 18:04:51 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief convert function
|
2020-10-01 08:12:41 +03:00
|
|
|
* @param infix[] : infix array provided by user
|
|
|
|
* @param postfix[] : empty array to be given to convert()
|
2020-09-30 18:04:51 +03:00
|
|
|
* @returns postfixed expresion or \0 on exit
|
|
|
|
*/
|
|
|
|
void convert(char infix[], char postfix[])
|
|
|
|
{
|
2020-10-01 08:12:41 +03:00
|
|
|
struct Stack s; // initialze object reference of stack
|
|
|
|
s.tos = -1; // initalize the tos
|
2020-09-30 18:04:51 +03:00
|
|
|
|
|
|
|
int i, j = 0, pr;
|
2020-10-19 07:59:02 +03:00
|
|
|
char ch, temp;
|
2020-09-30 18:04:51 +03:00
|
|
|
|
|
|
|
for (i = 0; infix[i] != '\0'; i++)
|
|
|
|
{
|
|
|
|
ch = infix[i];
|
|
|
|
|
2020-10-01 08:12:41 +03:00
|
|
|
if (isOprnd(ch) == 1) // check if char is operand or operator
|
2020-09-30 18:04:51 +03:00
|
|
|
{
|
2020-10-01 08:12:41 +03:00
|
|
|
postfix[j] = ch; // assign ch to postfix array with index j
|
|
|
|
j++; // incement j
|
2020-09-30 18:04:51 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-10-19 07:59:02 +03:00
|
|
|
if (ch == '(')
|
2020-09-30 18:04:51 +03:00
|
|
|
{
|
2020-10-19 07:59:02 +03:00
|
|
|
push(&s, ch);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (ch == ')')
|
2020-09-30 18:04:51 +03:00
|
|
|
{
|
2020-10-19 07:59:02 +03:00
|
|
|
while ((temp = pop(&s)) != '(')
|
|
|
|
{
|
|
|
|
postfix[j] = temp;
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (isEmpty(s) == 0) // check if stack is empty
|
|
|
|
{
|
2021-02-11 07:59:16 +03:00
|
|
|
pr = getPrecedence (ch,
|
2020-10-19 07:59:02 +03:00
|
|
|
s.arr[s.tos]); // check operator precedence
|
|
|
|
|
|
|
|
if (pr == 1)
|
|
|
|
{
|
|
|
|
break; // if ch has a greater precedence than
|
|
|
|
// s.arr[s.top]
|
|
|
|
}
|
|
|
|
|
|
|
|
postfix[j] = pop(&s);
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
|
|
|
|
push(&s, ch); // push ch to stack
|
2020-09-30 18:04:51 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-01 08:12:41 +03:00
|
|
|
while (isEmpty(s) == 0) // check if stack is empty
|
2020-09-30 18:04:51 +03:00
|
|
|
{
|
|
|
|
postfix[j] = pop(&s);
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
|
|
|
|
postfix[j] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-02-11 07:59:16 +03:00
|
|
|
* @brief getPrecedence function returns the precedence after comparing two operators passed as parameter.
|
2020-10-01 08:12:41 +03:00
|
|
|
* @param op1 : first operator
|
|
|
|
* @param op2 : second operator
|
2020-09-30 18:04:51 +03:00
|
|
|
* @returns 1 or 0 on exit
|
|
|
|
*/
|
2021-02-11 07:59:16 +03:00
|
|
|
int getPrecedence (char op1, char op2)
|
2020-09-30 18:04:51 +03:00
|
|
|
{
|
|
|
|
if (op2 == '$')
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (op1 == '$')
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else if (op2 == '*' || op2 == '/' || op2 == '%')
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (op1 == '*' || op1 == '/' || op1 == '%')
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else if (op2 == '+' || op2 == '-')
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|