Sie sind auf Seite 1von 12

# Mathematical _Expression Parser

This evaluates an _Expression that makes addition, subtraction, multiplication, division, modulus
and this will work for sin, cos and tan functions. This can calculate for inner most brace values also.
This program checks for errors and this shows the error position. This allows spaces in the
_expression. This allows 1000 characters of maximum. This program uses two stacks

double stack[MAX];
char oper[MAX];

stack[MAX] is to store the values and the pointer is top, this shows the top most element in the
stack. second is to store the operators and braces are in the _expression and the pointer is to do,
this shows the top most operator in the operator stack.

The logic makes here is first it accepts a _expression as string. Then it removes all
leading blank spaces and stores in an array, and the base address of the array is assigned to a
pointer variable.

## s = ch1 ; /* s is a character pointer variable ( char *s )

then checks it for first element is a number or character. That is a character, it checks for validity of
the first character ( '+' , '-',' ( ','s', 'c', 't' ), is valid then it makes its functionality ,is not valid then this
shows an error. The first element is a number then it converts the character into number using
"counto( )" function.

Then this will enter into a loop, this loop will work until the element will come as '\0'.

while ( *s )
{
}

This loop having a function "whilecheck( )".This function checks for every element validity and it will
do the functionality of the element. While the cursor comes out of the loop, then it checks for the
number of braces.

if ( brace >= 1 )
{
printf ( "\n\n Enclosing brace/s missing" ) ;
errfunc ( 0 ) ;
}

if "brace != 0" there is an error else. There is no error and that will calculate the values of stack using
pop function, after calculating the values then it prints the Result.

while ( topo != -1 )
pop( ) ;
printf ( "%lf", stack[0] ) ;

## What the functions are doing?

1. firstcheck( )

This function checks for a element after first element is valid or not.

2. whilecheck( )
This will check whether a element is valid or not. if valid what functionality of that element that will
do.

Ex : The character is 's', 'c' or 't' then that will check first whether the element before this in this
_expression is valid or not, and that is valid it makes a call to "ofunc( )".

3. minuscheck( )

This will be work in two ways, when the first element of a string is '-' and second, when the
element in the string having a negative symbol after opening brace program gets invoke this
function, because the value after this '-' will become negative. This calculate the value after minus,
then makes that value as negative and pushes in to the stack.

4. minuscheck( )

This will be invoked by minuscheck( ) function, when minuscheck function founds a element {,s',
'c' or 't' } after '-' .This calculates the value of function by invoking the function "ofunc( )" and make
that value as negative and push in to stack.

5. pusho( )

This function first checks for validity of that operator, there is no value of that operator this shows
an error, then that is valid it checks for the operator stack is empty or not. If that having any
operator then it checks for priority, this having highest priority pushes into operator stack,
otherwise it invokes the function "pop( )".This will push after completion of pop operation.

6. pop( )

Simply this function invokes a operator from operator stack and invokes two values from stack
and make the appropriate operation. Push a operator into the operator stack.

7. priority( )

## if ( ch == '*' || ch == '/' || ch == '%' )

pri = 2 ;
else
if ( ch == '+' || ch == '-' )
pri = 1 ;
else
pri = 0 ;

8. ofunc( )

This function gets invoked when the element of the string has a value 's', 'c' or 't'. This function
invokes trigfunc( ) to get the validity of sin, cos or tan functions, they are valid trigfunc( ) returns
an integer to identify which function is that. Then it calculates the value of that function.

9. trigfunc( )

This function checks the validity of sin, cos or tan functions, if they are valid returns an integer to
identify which function is that.

10.counto( )
This function converts the string ( char ) elements in to number type and this counts the value
until the string element is a character, then it returns that value.

11.checkbefaft( )

In this function the syntactical check will be done before and after the element is valid. That is not
valid it shows an error.

12.brace( )

## This is a function to push a openbrace( '(' ) in to operator stack.

13.errfunc( )

This function gives an error where it located. This displays the error and location number also,
then it will wait for pressing any key if the user press any key it will be exit from the program.

A simple Example :

sin45+cos90*(90-25(tan(-cos67+34(sin45/76)%65))

/* Global definitions */
#define MAX 1000
#define deg 0.01744

#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<string.h>

/* Global variables */
char *s, oper[MAX], er[MAX] ;
double stack[MAX] ;
int top = -1, topo = -1, i = 0, brace = 0 ;

int priority( ) ;

## /* Main program starts here */

void main( )
{
char ch[MAX], ch1[MAX] ;
int c = 0, j, k, l, n ;
double temp ;
clrscr( ) ;

## puts ( "\n Example: sin45 + cos ( 34 + cos90 - ( 23 + 45 ) /2 ) " ) ;

puts ( "\n\n\nEnter a _Expression to evaluate: " ) ;

gets ( ch ) ;
s = ch ;

## while ( *s ) /* This Loop parses Leading spaces in _Expression. */

{
if ( *s == ' ' || *s == '\t' )
{
s++ ;
continue ;
}
else
{
ch1[c++] = *s ;
s++;
}
}

## ch1[c] = '\0' ; /* String termination */

clrscr( ) ; /* clearing the screen */

puts ( ch1 ) ;

## s = ch1; /* Assignment of string to a pointer variable */

n = strlen ( ch1 ) ; /* calculating String length */

for ( k = 0 ; k <= n ; k++ ) /* Entering string into another array to show errors */
{
er[k] = ch1[k] ;
}

## /* Checking first character for validation */

if ( ! ( isdigit ( *s ) ) )
{
++i ;
if ( ! ( *s == 's' || *s == 'c' || *s == 't' || *s == '+' || *s == '-' || *s == '(' ) )
{
errfunc ( 11 ) ;
}

## /* This switch checks for every valid character */

switch ( *s )
{
case 's':
case 'c':
case 't':
{
ofunc( ) ;
}
break ;

case '+':
{
firstcheck( ) ;
s++ ; i++ ;
}
break ;

case '-':
{
firstcheck( ) ;
minuscheck( ) ;
}
break ;
case '(':
{
oper[++topo] = *s ;
s++ ; i++ ;
brace++ ;
}
}
}
else /*This else function pushes a valid number in to stack */
{
stack[++top] = counto( ) ;
}

## /* This loop evaluates entire _expression until *s='\0' */

while ( *s )
{
whilecheck( ) ;
}

if ( *s == '\0' )
{
if ( brace >= 1 )
{
printf ( "\n\n Enclosing brace/s missing" ) ;
errfunc ( 0 ) ;
getch( ) ;
exit ( 0 ) ;
}

## printf ( "\n\n Result of this _Expression is :" ) ;

while ( topo != -1 )
pop( ) ;

## printf ( "\n\n\n press any key to continue......." ) ;

getch( ) ;
exit ( 0 ) ;
}
}

/* This function checks for a valid character after the present character */
firstcheck( )
{
if ( * ( s + 1 ) == '+' || * ( s + 1 ) == '*' || * ( s + 1 ) == '/' || * ( s + 1 ) == '%' || * ( s + 1 ) == '-' || * ( s +
1 ) == ')' || * ( s + 1 ) == '\0' )
errfunc ( 9 ) ;
return ;
}

/* This function checks and performs the operation of the character using valid function */
whilecheck( )
{
if ( ! ( isdigit (*s ) ) )
{
if ( ! ( *s == 's' || *s == 'c' || *s == 't' || *s == '+' || *s == '-' || *s == '*' || *s == '/' || *s == '%' || *s == '('
|| *s == ')' || *s == '\0' ) )
{
errfunc ( 1 ) ;
}

switch ( *s )
{
case 's':
case 'c':
case 't':
{
if ( * ( s - 1 ) == '+' || * ( s - 1 ) == '-' || * ( s - 1 ) == '(' || * ( s - 1 ) == ')' || * ( s - 1 ) == '*' || * (
s - 1) == '/' || * ( s - 1 ) == '%' )
ofunc( ) ;
else
errfunc ( 2 ) ;
}
break ;

case '+':
{
if ( * ( s - 1 ) == '(' )
{
s++ ; i++ ;
}

checkbefaft( ) ;
pusho( ) ;
}
break ;

case '-':
{
checkbefaft( ) ;

if ( * ( s - 1 ) == '(' )
minuscheck( ) ;
else
pusho( ) ;
}
break ;
case '*':
{
checkbefaft( ) ;
pusho( ) ;
}
break ;

case '/':
{
checkbefaft( ) ;
pusho( ) ;
}
break ;

case '%':
{
checkbefaft( ) ;
pusho( ) ;
}
break ;

case '(':
{
if ( * ( s - 1 ) != '(' && * ( s - 1 ) != '+' && * ( s - 1 ) != '-' && * ( s - 1 ) != '/' && * ( s
- 1 ) != '%' && * ( s - 1 ) != '*' )
{
*s = '*' ;
pusho( ) ;
s-- ; i-- ;
}

oper[++topo] = '(' ;
*s = '(' ;
s++ ; i++ ; brace++ ;

if ( *s == '*' )
s++ ; i++ ;
}
break ;

case ')':
{
if ( * ( s - 1 ) == '(' )
{
printf ( "\n value expected in between braces" ) ;
errfunc ( 24 ) ;
}

if ( brace <= 0 )
{
printf ("open brace missing " ) ;
errfunc ( 18 ) ;
}
else
{
while(oper[topo] != '(' )
{
pop( ) ;
}

s++ ; i++ ;
topo-- ;
brace-- ;

## if ( ! ( * ( s ) == '+' || * ( s ) == '-' || * ( s ) == '*' || * ( s ) == '/' || * s == ')' || * ( s ) == '(' || * ( s

) == '%' || * ( s ) == '\0' ) )
oper[++topo] = '*' ;
}
}
}
}

else
{
stack[++top] = counto( ) ;
}

return ;
}

/* This function calculates negative values and push into stack with negative symbol */

minuscheck( )
{
double temp ;
if ( isdigit ( * ( s + 1 ) ) )
{
s++ ; i++ ;
stack[++top] = counto( ) ;
temp = - ( stack[top--] ) ;
stack[++top] = temp ;
}
else
switch ( * ( s + 1 ) )
{
case 's':
minuscheckfunc( ) ;
break ;
case 'c':
minuscheckfunc( ) ;
break ;
case 't':
minuscheckfunc( ) ;
break ;
}
return ;
}

minuscheckfunc( )
{
double temp ;
s++ ; i++ ;
ofunc( ) ;
temp = - ( stack[top--] ) ;
stack[++top] = temp ;
return ;
}

## /* function push for operators */

pusho( )
{
double a ;
char ch ;

if ( * ( s + 1 ) == '\0' )
errfunc ( 5 ) ;
else
if ( topo == -1 )
{
oper[++topo] = *s ;
s++ ; i++ ;
}
else
{
while ( priority ( oper[topo] ) >= priority ( *s ) )
{
while ( topo != -1 && oper[topo] != '(' )
pop( ) ;
}
oper[++topo] = *s ;
s++ ; i++ ;
}
return ;
}

pop( )
{
double a, b, c ;
int a1, b1, c1 ;
char ch ;
ch = oper[topo--] ;

if ( ch == '%' )
{
b1 = stack[top--] ;
a1 = stack[top--] ;
c1 = fmod ( a1, b1 ) ;
stack[++top] = c1 ;
}
else
{
b = stack[top--] ;
a = stack[top--] ;

if ( ch == '+' )
c=a+b;
else
if ( ch == '-' )
c=a-b;
else
if ( ch == '*' )
c=a*b;
else
if ( ch == '/' )
c=a/b;
stack[++top] = c ;
}
return ;
}
/* Priority checking */
int priority ( char ch )
{
int pri ;

## if ( ch == '*' || ch == '/' || ch == '%' )

pri = 2 ;
else
if ( ch == '+' || ch == '-' )
pri = 1 ;
else
pri = 0 ;
return pri ;
}

ofunc( )
{
int v, m = 0, b = 0, ch ;
double p, k = 0 ;
ch = trigfunc( ) ;

if ( *s == '(' )
{
i++ ; brace++ ;
oper[++topo] = *s++ ;

while ( * ( s - 1 ) != ')' )
{
whilecheck( ) ;
}
}
else
{
stack[++top] = counto( ) ;
}

k = stack[top--] ;
k = k*deg ;

switch ( ch )
{
case 0:
p = sin ( k ) ;
break ;

case 1:
p = cos ( k ) ;
break ;

case 2:
p = tan ( k ) ;
break ;

default:
errfunc ( 23 ) ;
break ;
}
stack[++top] = p ;
return ;
}

trigfunc( )
{
int t, ch, y ;
char cha[3], cha1[ ][5] = {
{ "sin" },
{"cos"},
{"tan"}
};
for ( t = 0 ; t < 3 ; t++ )
{
cha[t] = *s++ ;
i++ ;
}

cha[t] = '\0' ;
for ( t = 0 ; t < 3 ; t++ )
{
y = strcmpi ( cha, cha1[t] ) ;

if ( y == 0 )
{
ch = t ;
return ch ;
}
}
return 0 ;
}

counto( )
{
double k = 0, v ;
while ( isdigit ( *s ) )
{
switch ( *s )
{
case '0': v = 0 ;
break ;
case '1': v = 1 ;
break ;
case '2': v = 2 ;
break ;
case '3': v = 3 ;
break ;
case '4': v = 4 ;
break ;
case '5': v = 5 ;
break ;
case '6': v = 6 ;
break ;
case '7': v = 7 ;
break ;
case '8': v = 8 ;
break ;
case '9': v = 9 ;
break ;
}
k = k * 10 + v ;
s++ ; ++i ;
}

## if ( ! ( * ( s ) == '+' || * ( s ) == '-' || * ( s ) == '(' || * ( s ) == ')' || * ( s ) == '*' || * ( s ) == '/' || * ( s ) ==

'%' || * ( s ) == '\0' ) )
errfunc ( 10 ) ;
return k ;
}
checkbefaft( )
{
if ( * ( s - 1 ) == '+' || * ( s - 1) == '-' || * ( s - 1 ) == '*' || * ( s - 1 ) == '/' || * ( s - 1 ) == '%' )
errfunc ( 12 ) ;
else
if ( * ( s + 1 ) == '-' || * ( s + 1 ) == '+' || * ( s + 1 ) == ')' || * ( s + 1 ) == '*' || * ( s + 1 ) ==
'/' || * ( s + 1 ) == '%' || * ( s - 1 ) == '\0' )
errfunc ( 13 ) ;
return ;
}

bracee( )
{
oper[++topo] = '(' ;
s++ ; i++ ; brace++ ;
return ;
}
errfunc ( int e )
{
int f ;

## printf ( "\n\nerror at : %d in _Expression %d", i, e ) ;

printf ( "\n string has error at " ) ;
printf ( "%c%c%c", er[i-2], er[i-1], er[i] ) ;
printf ( "\n\n\npress any key to continue.........." ) ;

getch( ) ;
exit ( 0 ) ;
return ;
}