Connect with us

infix to postfix negation

Discussion in 'Microcontrollers, Programming and IoT' started by lady_krizzie, Sep 18, 2012.

  1. lady_krizzie

    lady_krizzie

    30
    0
    Aug 2, 2012
    I am trying to make a calculator program. But I have a problem with the negative sign. I fixed the program to do expression of (0-5)+12 if I want 5 to be negative. But I want and I am expecting it to do -5+12 Please help...Thank you in advance.

    Code:
    #define MAX_CHAR 64
    
    #define LP 10
    #define RP 20
    #define OPERATOR 30
    #define OPERAND 40
    #define UNARY 50
    
    #define LPP 0
    //#define LPP 1// Left parentheses precedence. Minimum of all
    #define RPP 1
    #define AP 2// Addition Subtraction precedence. Minimum among all operator precedence
    #define SP AP
    #define MP 4// Multiplication divisor precedence.
    #define DP MP
    #define REMP 2// Remainder precedence.
    #define NONE 9
    
    char input_string[MAX_CHAR] = {};
    char out_string[MAX_CHAR*2]= {}; //input_string
    char bufer_string[MAX_CHAR] = {};
    double stack_string[MAX_CHAR] = {};
    char *next;
    int input_index = 0;
    int bufer_index = 0;
    int stack_index = 0;
    
    int foo = 0;
    int isanumber = 0;
    
    int num = 0;
    //int num = 0;
    int error = 0;	
    	
    void infixtopostfix(void);     /** POSTFIX CONVERSION FUNCTION **/
    int gettype(char);             /** TYPE OF EXPRESSION GENERATOR **/
    void push1(char);               /** PUSH FUNCTION **/
    void push2 (int);
    char pop1(void);                /** POP FUNCTION **/
    int pop2 (void);
    int getprec(char);             /** PRECEDENCE CHECKER FUNCTION **/
    int getValue(void);
    /************************************************************************/
    /*                                                                                        */
    /************************************************************************/
    void infixtopostfix(void)
    {
    	int i,p,l,type,prec;
    	//char next;
    	i=p=0;
    	l=strlen(input_string);
    	while(i<l)
    	{
    		type=gettype(input_string[i]);
    		switch(type)
    		{
    		case LP:
    			push1(input_string[i]);
    			break;
    		case RP:
    				//while((next=pop1())!='(')
    				//out_string[p++]=next;
    				out_string [p++]= ' ';
    				out_string [p++]= pop1();
    				pop1() != '(';
    			break;
    		case OPERAND:
    			out_string[p++]=input_string[i];
    			break;
    		case UNARY:
    			push1(input_string[i]);
    			break;	
    		case OPERATOR:
    		default:
    			out_string[p++] = ' ';
    			prec=getprec(input_string[i]);
    			while(stack_index>-1 && prec <= getprec(stack_string[stack_index]))
    			{
    				//out_string[p++] = ' ';
    				out_string[p++]=pop1();
    				out_string [p++] = ' ';
    			}			
    
    			push1(input_string[i]);
    			break;
    		}
    		i++;
    	}
    	while(stack_index>-1)
    	{
    		out_string[p++] = ' ';
    		out_string[p++]=pop1();
    	}	
    	out_string[p]='\0';
    }
    
    
    int gettype(char num)
    {
    	int i,p;
    	i= 0;		
    	switch(num)
    	{
    		case '(':
    			return(LP);
    		case ')':
    			return(RP);
    		case '*':
    		case '/':
    		case '+':
    		case '-':
    			if ((input_string == OPERATOR) || (input_string == '\0') && (input_string== '-'))	//a minus sign followed by a  or null is a unary
    				{
    				return (UNARY);
    				} 
    				
    			else
    				{
    				return (OPERATOR);
    				}			
    				
    		case '%':
    		case '\t':
    			return(OPERATOR);
    		/*case '-':
    			return(UNARY);*/
    		default :
    			return(OPERAND);
    	}
    }
    
    /***************************************************/
    void push1(char num)
    {
    	if(stack_index > MAX_CHAR)
    	{
    		printf("\nStack is full\n");
    		exit(0);
    	}
    	else
    	stack_string[++stack_index]=num;
    }
    
    char pop1(void)
    {
    	if(stack_index<=-1)
    	{
    		printf("\nStack is empty\n");
    		exit(0);
    	}
    	else
    	return(stack_string[stack_index--]);
    }
    
    
    void push2(int num)
    {
    	 if (stack_index > MAX_CHAR)
        {
            printf("error: push to full stack\n");
            error = 1;
        }
        else
        {
            stack_string[stack_index++] = num;
        }
    }
    
    
    int pop2(void)
    {
        int retval = 0;
    
        if (--stack_index < 0)
    	//if (stack_index<=-1)
        {
            error = 1;
            printf("error: pop empty stack\n");
    		//exit(0);
        }
        else
        {
            retval = stack_string[stack_index];
            stack_string[stack_index] = '\0';
        }
    
        return retval;
    }
    
    /******************************************************/
    int getprec(char num)
    {
    	switch(num)
    	{
    		case '(':
    			return(LPP);
    		case ')':
    			return (RPP);
    		case '*':
    			return(MP);
    		case '/':
    			return(DP);
    		case '+':
    			return(AP);
    		case '-':
    			return(SP);
    			//return(UNARY);
    		case '%':
    			return(REMP);
    		default :
    			return(NONE);
    	}
    }
    
    
    int getValue(void)//return an integer input.  next points to first digit
    {					//allows a negative answer, second digit or operand is lesser than the first operand
    	int value = 0;
    
    	while(isdigit(*next))
    	{
    		value = 10 * value + *next - '0';
    		++next;
    	}
    
    	return value;
    }
    
    
    /************************************************************************/
    /*                                                                                        */
    /************************************************************************/
    
    int main (void)
    {
    	USART_Init(51);
    	stdout = &uart_output;
    	stdin  = &uart_input;
    	char choice;
    	int r; // repeat
    	char garbage;
    	int bar;
    	int ch;
    	do
    	{
    		stack_index=-1;
    		printf("\nEnter an infix expression\n");
    		scanf("%[^\t]s", input_string);
    		infixtopostfix();
    		printf("\ninfix = %s\npost fix =%s\n",input_string,out_string);
    	
    		bar = 0;
    		while(bar < strlen(stack_string))
    		{
    			stack_string[bar++] = '\0';
    		}
    		stack_index = 0;
    
    		input_index = 0;
    		while (input_index < strlen(out_string)) //while operand is not reach
    		{
    			bufer_index = 0;
    			if (isdigit(out_string[input_index]))
    			{
    				isanumber = 1;			//a digit is found
    				
    				for (foo=input_index; foo<strlen(out_string); foo++)
    				{
    					if (isdigit(out_string[foo]))
    					bufer_string[bufer_index++] = out_string[foo];
    					else
    					break;
    				}
    				input_index = foo + 1;
    			}
    			else
    			{
    				isanumber = 0;
    				bufer_string[bufer_index++] = out_string[input_index++];
    			}
    			bufer_string[bufer_index] = '\0';
    
    			if (isanumber)
    			{
    				// if element is a number, push to stack
    				//push(bufer_string);
    				push2(atol(bufer_string));
    				asm volatile ("nop"::);
    			}
    			else
    			{
    				// if not a number, check if valid operator
    				switch (bufer_string[--bufer_index])
    				{
    					case '+':
    						push2(pop2() + pop2());
    						break;
    					case '-':
    						if (isdigit(*(next + 1)))
    							{
    								++next;
    								push2(-getValue());
    							}
    						else if ('-' == UNARY) // unary operator
    							{
    								push2(pop2() * 1);
    							}
    						else
    							num = pop2();
    							push2(pop2() - num);
    							break;
    					case '*':
    						push2(pop2() * pop2());
    						break;
    					case '/':
    						if (num != 0)
    							{
    								num = pop2();
    								push2(pop2()/num);
    								printf(" ");
    							}	
    						else if ('-' == UNARY) // unary operator
    							{
    								push2(pop2() * -1);
    							}
    						else
    							{
    								num=0;
    								printf("MATH ERROR \n");
    							}							
    						break;
    					case '%':
    						num = pop2();
    						push2(pop2() % num);
    						break;
    					default:
    						break;
    				}
    				bufer_index++;
    			}
    
    			// check for error
    			if (error == 1)
    			break;
    		}
    
    		if (error == 0)
    			printf("\nAnswer: %d", pop2());	
    		
    	printf("\nNew Operand [y/n]");
    	if(choice=='y'||choice=='Y')
    	scanf("%d" , &r);
    	}
    	while( (getchar()!='n') && (getchar()!='N') );
    		return 0;
    }
    
     
  2. dahhal

    dahhal

    58
    0
    Jul 17, 2012
    would a quick hack would be to detect that the first character is an - and to add 0 in front of it.

    this wouldn't work well for when you + and - number like 5+-2. though this could be solved by another routine that looks for double operators ++, +-, -- and to change it to + -, and + respectively. This could all occur before your current code.
     
  3. lady_krizzie

    lady_krizzie

    30
    0
    Aug 2, 2012
    Thank you.. Im going to think of it...
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Similar Threads
There are no similar threads yet.
Loading...
Electronics Point Logo
Continue to site
Quote of the day

-