home *** CD-ROM | disk | FTP | other *** search
-
- #ifndef PARSER_C
- #define PARSER_C
-
- // Short: Command line parser for mathematical expressions.
- // Version: $VER: Parser.c 1.0 (16.01.96)
- // Copyright: Copyright © 1996 Constantin Rack. All rights reserved.
-
-
- // ========================================================= INCLUDES
-
- #include <ctype.h> // Needed for isdigit()
- #include <iostream.h> // Needed for standard I/O
- #include <string.h> // Needed for string functions
-
-
- // ========================================================== DEFINES
-
- enum Consts // Some constant values
- {
- FALSE = 0,
- TRUE = 1,
- Op_Num = 5, // Number of operators
- };
-
- enum OperatorTypes
- {
- Op_Err = -1, // Bad operator
- Op_Add = 0, // +
- Op_Sub = 1, // -
- Op_Mul = 2, // *
- Op_Div = 3, // /
- };
-
- struct Operator
- {
- int op_Type; // Type of operator (see above)
- char* op_Name; // Operator as a string
- };
-
-
- // ======================================================== VARIABLES
-
- const char* Version = "$VER: Parser 1.0 (16.01.96)";
- char* ActPtr = 0; // Actual text pointer
- int Error = FALSE; // Error indicator
-
- struct Operator operators[Op_Num] =
- {
- {
- Op_Add, "+"
- },
-
- {
- Op_Sub, "-"
- },
-
- {
- Op_Mul, "*"
- },
-
- {
- Op_Div, "/"
- },
- };
-
-
- // ======================================================= PROTOTYPES
-
- long Expression();
- long Factor();
- long Constant();
- long Operater();
-
-
- // ======================================================== FUNCTIONS
-
-
- // --------------------------------------------------------- FUNCTION
- // Operater()
- //
- // Short: Reads an operator and returns its value.
- // Needs: ctype.h, string.h
-
- long Operater()
- {
- long result = 0;
- long i = 0;
- char* string = 0;
-
- string = new char [80];
- result = Op_Err;
-
- if( string == 0 )
- {
- return result;
- }
-
- while( *ActPtr != ' ' && i < 79 )
- {
- string[i++] = tolower( *ActPtr++ );
- }
-
- ActPtr++;
-
- string[i] = '\0';
-
- for(i=0;i<Op_Num;i++)
- {
- if( strcmp(operators[i].op_Name,string) == 0 )
- {
- result = operators[i].op_Type;
- }
- }
-
- delete [] string;
-
- return result;
- }
-
-
- // --------------------------------------------------------- FUNCTION
- // Constant()
- //
- // Short: Reads a constant number ("C-Tools", ISBN 3-89090-190-5)
- // Needs: ctype.h
-
- long Constant()
- {
- long result = 0;
-
- while( *ActPtr != 0 && isdigit(*ActPtr) != 0 )
- {
- result = (result * 10) + (*ActPtr++ - '0');
- }
-
- return result;
- }
-
- // --------------------------------------------------------- FUNCTION
- // Factor()
- //
- // Short: Evaluates an expression. This function is recursive.
- // Needs: ctype.h
-
- long Factor()
- {
- long result = 0;
- long sign = 1;
-
- if( *ActPtr == 0 )
- {
- return result;
- }
-
-
- if( *ActPtr == '-' )
- {
- sign = -1;
- ActPtr++;
- }
-
- if( isdigit( *ActPtr ) != 0 )
- {
- result = Constant();
- }
- else
- {
- if( *ActPtr == '(' )
- {
- result = Expression();
- }
- }
-
- result *= sign;
-
- return result;
- }
-
- // --------------------------------------------------------- FUNCTION
- // Expression()
- //
- // Short: Evaluates a bracket expression.
- // Needs: stream.h
-
- long Expression()
- {
- long result = 0;
- long op = 0;
-
- if( *ActPtr == '(' )
- {
- ActPtr++;
-
- op = Operater();
- result = Factor();
-
- switch( op )
- {
- case Op_Add:
- {
- while( *ActPtr++ != ')' )
- {
- result += Factor();
- }
- }
- break;
-
- case Op_Sub:
- {
- while( *ActPtr++ != ')' )
- {
- result -= Factor();
- }
- }
- break;
-
- case Op_Mul:
- {
- while( *ActPtr++ != ')' )
- {
- result *= Factor();
- }
- }
- break;
-
- case Op_Div:
- {
- long temp = 0;
-
- while( *ActPtr++ != ')' )
- {
- temp = Factor();
-
- if( temp != 0 )
- {
- result /= temp;
- }
- else
- {
- cerr << "** Division by zero\n";
- Error = TRUE;
- }
- }
- }
- break;
-
- case Op_Err:
- default:
- {
- cerr << "** Bad operator\n";
- Error = TRUE;
- }
- break;
- }
- }
- else
- {
- if( *ActPtr == '?' )
- {
- cerr << "This parser uses a simple praefix notation. Example:\n"
- << "\t(+ 1 (* 2 (/ 10 5)))\n"
- << "would have the result 5. So always write the operator "
- << "first. Parser knows the following operators by now:\n";
-
- {
- int i = 0;
-
- for(i=0;i<Op_Num;i++)
- {
- cerr << operators[i].op_Name
- << ", ";
- }
-
- cerr << "\n";
- }
-
- cerr << "\nCopyright © 1996 Constantin Rack. All rights reserved.\n";
-
- Error = TRUE;
- }
- else
- {
- cerr << "** Bad command line\n";
- Error = TRUE;
- }
- }
-
- return result;
- }
-
- // --------------------------------------------------------- FUNCTION
- // main()
- //
- // Short: Main function of the parser.
- // Needs: stream.h, string.h
-
- int main()
- {
- int okay = TRUE;
- long result = 0;
- char* input = 0;
-
- input = new char [256];
-
- if( input == 0 )
- {
- cerr << "** Memory problem\n";
- return 5;
- }
-
- cout << "Parser 1.0 (16.01.96)\n"
- << "Short: Command line parser for mathematical expressions\n"
- << "Usage: Press '?' for more information\n\n";
-
- while( okay )
- {
- cout << "Expression: ";
- cin.getline(input,255);
-
- okay = strlen(input);
-
- if( okay > 0 )
- {
- ActPtr = &input[0];
- result = Expression();
-
- if( Error == 0 )
- {
- cout << "Result: "
- << result
- << "\n";
- }
- else
- {
- Error = FALSE;
- }
- }
- else
- {
- cout << "** Parser ended\n";
- }
- }
-
- delete [] input;
-
- return 0;
- }
-
- #endif // PARSER_C
-