From 2909f50d008920568f0e50da760b266388ccc124 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 22 Apr 2013 13:05:22 -0600 Subject: There is now a parser & calculator interface. --- src/lexer.cpp | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 src/lexer.cpp (limited to 'src/lexer.cpp') diff --git a/src/lexer.cpp b/src/lexer.cpp new file mode 100644 index 0000000..834d3bc --- /dev/null +++ b/src/lexer.cpp @@ -0,0 +1,163 @@ +#include "lexer.h" +#include "token.h" +#include "number.h" + +#include + +Lexer::Lexer( Bu::Stream &rIn ) : + rIn( rIn ), + iBufPos( 0 ), + iScale( 0 ), + iRadix( 10 ), + numRangeTop('9'), + ascRangeTop(0) +{ +} + +Lexer::~Lexer() +{ +} + +Token Lexer::nextToken() +{ + for(;;) + { + if( iBufPos >= sBuf.getSize() ) + { + iBufPos = -1; + return Token( Token::tEndOfLine ); + } + + if( iBufPos < 0 ) + { + if( rIn.isEos() ) + return Token( Token::tEndOfInput ); + + sBuf = rIn.readLine(); + if( sBuf.getSize() == 0 ) + { + iBufPos = -1; + continue; + } + iBufPos = 0; + } + + //Bu::println("Testing char '%1' at %2").arg( sBuf[iBufPos] ).arg( iBufPos ); + switch( sBuf[iBufPos] ) + { + case ' ': + case '\t': + iBufPos++; + break; + + case '\\': + { + Bu::String *sTmp = new Bu::String(); + for( iBufPos++; iBufPos < sBuf.getSize() && + sBuf[iBufPos] != ' ' && sBuf[iBufPos] != '\t'; + iBufPos++ ) + { + sTmp->append( sBuf[iBufPos] ); + } + return Token( Token::tCommand, sTmp ); + } + break; + + case '+': + iBufPos++; + return Token( Token::tPlus ); + + case '-': + iBufPos++; + return Token( Token::tMinus ); + + case '*': + iBufPos++; + return Token( Token::tMultiply ); + + case '/': + iBufPos++; + return Token( Token::tDivide ); + + case '(': + iBufPos++; + return Token( Token::tOpenParen ); + + case ')': + iBufPos++; + return Token( Token::tCloseParen ); + + default: + { + Bu::String *sTmp = new Bu::String(); + if( (sBuf[iBufPos] >= '0' && + sBuf[iBufPos] <= numRangeTop) || + (sBuf[iBufPos] >= 'a' && + sBuf[iBufPos] <= ascRangeTop) || + sBuf[iBufPos] == '.' ) + { + for( ; iBufPos < sBuf.getSize() ; iBufPos++ ) + { + if( (sBuf[iBufPos] >= '0' && + sBuf[iBufPos] <= numRangeTop) || + (sBuf[iBufPos] >= 'a' && + sBuf[iBufPos] <= ascRangeTop) || + sBuf[iBufPos] == '.' ) + { + sTmp->append( sBuf[iBufPos] ); + } + else + { + break; + } + } + Number *n = new Number( *sTmp, iScale, iRadix ); + delete sTmp; + return Token( Token::tNumber, n ); + } + else if( (sBuf[iBufPos]>=(ascRangeTop+1) && sBuf[iBufPos]<='z') || + (sBuf[iBufPos]>='A' && sBuf[iBufPos]<='Z') || + sBuf[iBufPos] == '_' ) + { + for( ; iBufPos < sBuf.getSize(); iBufPos++ ) + { + if( (sBuf[iBufPos]>='a' && sBuf[iBufPos]<='z') || + (sBuf[iBufPos]>='A' && sBuf[iBufPos]<='Z') || + (sBuf[iBufPos]>='0' && sBuf[iBufPos]<='9') || + sBuf[iBufPos] == '_' ) + { + sTmp->append( sBuf[iBufPos] ); + } + else + { + break; + } + } + return Token( Token::tString, sTmp ); + } + else + { + sBuf.clear(); + Bu::println("Invalid character discovered!"); + } + } + break; + } + } +} + +void Lexer::setRadix( int i ) +{ + iRadix = i; + if( iRadix <= 10 ) + { + numRangeTop = '0'+iRadix-1; + ascRangeTop = 0; + } + else + { + numRangeTop = '9'; + ascRangeTop = 'a'+iRadix-11; + } +} + -- cgit v1.2.3