home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
CPROG
/
CGAZV5N3.ZIP
/
TOPDOWN3.C
< prev
Wrap
C/C++ Source or Header
|
1991-02-27
|
5KB
|
190 lines
/* Listing 6. TOPDOWN3.C - Expression Evaluator */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "lex.h"
int statement ( void );
int expression_and_predicate ( void );
int mult_expr_and_predicate ( void );
int factor ( void );
void error (char *fmt,...);
#ifdef PTRACE
static int Rdepth = 0;
int rdepth(void) {return( Rdepth * 8 );}
# define trace(name) printf("%*s%s\n", Rdepth++ * 8, "", name)
# define untrace(name) (--Rdepth)
#else
# define trace(name) /* empty */
# define untrace(name) /* empty */
#endif
/*----------------------------------------------------------------------*/
int statement( void )
{
/* statement->expression SEMI LP SEMI NUMBER
*/
int value;
trace("statement");
if( match(LP) || match(SEMI) || match(NUMBER) )
{
value = expression_and_predicate();
if( match(SEMI) ) advance();
else error("Inserting missing semicolon.");
return value;
}
else
{
error("Illegal expression\n");
return 0;
}
untrace("statement");
}
/*----------------------------------------------------------------------*/
int expression_and_predicate( void )
{
/* expression->mult_expr predicate LP NUMBER
* expression->(epsilon) RP SEMI
*
* Modified to incorporate the predicate productions and also
* to eliminate the tail recursion in the original predicate();
*/
int value; /* accumulated value of subexpression */
trace("expression_and_predicate");
if( match(RP) || match(SEMI) )
; /* epsilon */
else if( !(match(LP) || match(NUMBER)) )
error( "expression expected\n" );
else
{
value = mult_expr_and_predicate();
/* predicate->PLUS mult_expr predicate PLUS
* predicate->MINUS mult_expr predicate MINUS
* predicate->(epsilon) RP SEMI
*/
while( 1 )
{
if( match(RP) || match(SEMI) )
break; /* epsilon */
else if( match(PLUS) ){ advance();
value += mult_expr_and_predicate();
}
else if( match(MINUS)){ advance();
value -= mult_expr_and_predicate();
}
else
{
error("operator or statement-terminator expected\n");
break;
}
}
}
untrace("expression_and_predicate");
return value;
}
/*----------------------------------------------------------------------*/
int mult_expr_and_predicate( void )
{
/* mult_expr->factor mult_predicate LP NUMBER
*
* Modified to eliminate chain to mult_predicate() and also
* eliminate tail recursion in mult_predicate();
*/
static int value; /* value of subexpression */
trace("mult_expr_and_predicate");
if( !(match(LP) || match(NUMBER)) )
error( "Expected number identifier or open parenthesis\n" );
else
{
value = factor();
/* mult_predicate->STAR factor mult_predicate STAR
* mult_predicate->SLASH factor mult_predicate SLASH
* mult_predicate->(epsilon) RP PLUS MINUS SEMI
*/
while( 1 )
{
if( match(RP) || match(PLUS) || match(MINUS) || match(SEMI) )
break; /* epsilon */
else if( match(STAR) ) { advance(); value *= factor() ; }
else if( match(SLASH)) { advance(); value /= factor() ; }
else
{
error("operator expected\n");
break;
}
}
}
return value;
untrace("mult_expr_and_predicate");
}
/*----------------------------------------------------------------------*/
int factor( void )
{
/* factor->NUMBER NUMBER
* factor->LP expression RP LP
*
* Returns value of NUMBER or subexpression
*/
int value;
trace( "factor" );
if( match(NUMBER) )
{
value = atoi(yytext);
advance();
}
else if( match(LP) )
{
advance();
value = expression_and_predicate();
if( match(RP) ) advance();
else error("Inserting missing right parenthesis.");
}
else
error("Number or parenthesized subexpression expected\n");
untrace( "factor" );
return value;
}
/*----------------------------------------------------------------------*/
void error( char *fmt, ... )
{
va_list args;
va_start( args, fmt );
vfprintf( stderr, fmt, args );
va_end( args );
}
/*----------------------------------------------------------------------*/
int main()
{
printf("Enter Expression: ");
printf("= %d\n", statement() );
return 0;
}