From 89eeeff54f0b3ce30be5b046fc3899fdeb5ebb40 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Sat, 17 Feb 2007 16:31:55 +0000 Subject: Tweaked the stream classes, added an example, and the begining of a formula parser. --- src/formula.cpp | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 src/formula.cpp (limited to 'src/formula.cpp') diff --git a/src/formula.cpp b/src/formula.cpp new file mode 100644 index 0000000..7cc1804 --- /dev/null +++ b/src/formula.cpp @@ -0,0 +1,157 @@ +#include "formula.h" + +subExceptionDef( ParseException ); + +Formula::Formula() +{ +} + +Formula::~Formula() +{ +} + +double Formula::run( const char *sFormula ) +{ + sBuf.write( sFormula, strlen( sFormula ) ); + sBuf.setPos( 0 ); + + nState = 0; + for(;;) + { + tLook = nextToken(); + if( tLook.nSym == symEOS ) + break; + state(); + } + printf("\n"); + return 0.0; +} + +void Formula::state() +{ + switch( nState ) + { + case 0: // initial expr + switch( tLook.nSym ) + { + case symNumber: + push(); + nState = 1; + break; + } + break; + + case 1: // binary operator + switch( tLook.nSym ) + { + case symAdd: + case symSubtract: + push(); + nState = 2; + break; + + case symMultiply: + case symDivide: + push(); + nState = 3; + break; + } + break; + + case 2: // add/subtract + break; + } +} + +void Formula::push() +{ + printToken( tLook ); + sToken.push( tLook ); +} + +Formula::Token Formula::nextToken() +{ + char cbuf; + for(;;) + { + if( sBuf.isEOS() ) + return Token( symEOS ); + + sBuf.read( &cbuf, 1 ); + switch( cbuf ) + { + case '+': + return Token( symAdd ); + + case '-': + return Token( symSubtract ); + + case '*': + return Token( symMultiply ); + + case '/': + return Token( symDivide ); + + case '(': + return Token( symOpenParen ); + + case ')': + return Token( symCloseParen ); + + case ' ': + case '\t': + case '\n': + case '\r': + break; + + default: + if( cbuf == '.' || (cbuf >= '0' && cbuf <= '9') ) + { + char num[50]; + int nPos = 0; + bool bDot = false; + + for(;;) + { + num[nPos++] = cbuf; + if( cbuf == '.' ) + { + if( bDot == false ) + bDot = true; + else + throw ParseException( + "Numbers cannot have more than one " + ". in them." + ); + } + sBuf.read( &cbuf, 1 ); + if( (cbuf != '.' && (cbuf < '0' || cbuf > '9')) || + sBuf.isEOS() ) + { + if( !sBuf.isEOS() ) sBuf.seek( -1 ); + num[nPos] = '\0'; + return Token( symNumber, strtod( num, NULL ) ); + } + } + } + break; + } + } +} + +void Formula::printToken( Token &tok ) +{ + switch( tok.nSym ) + { + case symEOS: printf("[EOS] "); break; + case symAdd: printf("+ "); break; + case symSubtract: printf("- "); break; + case symMultiply: printf("* "); break; + case symDivide: printf("/ "); break; + case symOpenParen: printf("( "); break; + case symCloseParen: printf(") "); break; + case symNumber: printf("%f ", tok.val.num ); break; + default: printf("??? "); break; + } +} + -- cgit v1.2.3