From 0321e6e39b8cf24718cf853c28f0f35443753264 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Wed, 30 Nov 2016 13:57:04 -0700 Subject: Working on the parser, some issues. --- src/lexer.cpp | 42 +++++++++++++++++++++++++++++++++++++---- src/lexer.h | 8 +++++++- src/options.cpp | 2 +- src/parser.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/parser.h | 37 ++++++++++++++++++++++++++++++++++-- src/token.cpp | 6 ++++++ src/token.h | 6 +++++- src/unitparser.cpp | 7 +++++++ src/unitparser.h | 1 + 9 files changed, 155 insertions(+), 9 deletions(-) diff --git a/src/lexer.cpp b/src/lexer.cpp index b0d0fd1..fbcaafb 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp @@ -11,27 +11,55 @@ Lexer::Lexer( Bu::Stream &rIn ) : iRadix( 10 ), numRangeTop('9'), ascRangeTop('a'-1), - eMode( modeNormal ) + eMode( modeNormal ), + iLookAheadSize( 2 ), + iLookAheadUsed( 0 ), + iLookAheadStart( 0 ), + aLookAhead( 0 ) { + aLookAhead = new Token[iLookAheadSize]; } Lexer::~Lexer() { } -Token Lexer::nextToken() +void Lexer::nextToken() +{ + if( iLookAheadSize <= 1 ) + { + iLookAheadSize = 0; + iLookAheadStart = 0; + } + else + { + iLookAheadStart = (iLookAheadStart+1)%iLookAheadSize; + iLookAheadSize--; + } +} + +void Lexer::fillToken() { switch( eMode ) { case modeNormal: - return nextTokenNormal(); + aLookAhead[(iLookAheadUsed+iLookAheadStart)%iLookAheadSize] = + nextTokenNormal(); + break; case modeCommand: - return nextTokenCommand(); + aLookAhead[(iLookAheadUsed+iLookAheadStart)%iLookAheadSize] = + nextTokenCommand(); + break; default: throw Bu::ExceptionBase("Invalid mode."); } + + Bu::sio << "read[" + << ((iLookAheadUsed+iLookAheadStart)%iLookAheadSize) + << "]: " + << aLookAhead[(iLookAheadUsed+iLookAheadStart)%iLookAheadSize].eType; } Token Lexer::nextTokenNormal() @@ -235,5 +263,11 @@ void Lexer::setRadix( int i ) Token &Lexer::operator[]( int iIdx ) { + while( iIdx >= iLookAheadUsed ) + { + fillToken(); + iLookAheadUsed++; + } + return aLookAhead[(iLookAheadStart+iIdx)%iLookAheadSize]; } diff --git a/src/lexer.h b/src/lexer.h index d5631d4..193a22b 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -20,7 +20,7 @@ public: void setMode( Mode e ) { eMode = e; } Mode getMode() const { return eMode; } - Token nextToken(); + void nextToken(); int getScale() const { return iScale; } void setScale( int i ) { iScale = i; } @@ -31,6 +31,7 @@ public: Token &operator[]( int iIdx ); private: + void fillToken(); Token nextTokenNormal(); Token nextTokenCommand(); @@ -43,6 +44,11 @@ private: char numRangeTop; char ascRangeTop; Mode eMode; + + int iLookAheadSize; + int iLookAheadUsed; + int iLookAheadStart; + Token *aLookAhead; }; #endif diff --git a/src/options.cpp b/src/options.cpp index c127022..3c016a6 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -191,7 +191,7 @@ int Options::execute( Bu::StringArray aArgs ) mbIn.write(" "); mbIn.write( aArgs[j] ); } -// Bu::println("eq: '''%1'''").arg( mbIn.getString() ); + Bu::println("eq: '''%1'''").arg( mbIn.getString() ); mbIn.setPos( 0 ); Bu::MemBuf mbOut; Lexer lex( mbIn ); diff --git a/src/parser.cpp b/src/parser.cpp index 153b6fe..1f9a193 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -20,6 +20,58 @@ Parser::~Parser() void Parser::parse() { + for(;;) + { + lex.nextToken(); + expr(); + + for( TokenStack::iterator i = tsStack.begin(); i; i++ ) + { + Bu::sio << *i << " "; + } + } +} + +void Parser::expr() +{ + if( lex[0].eType == Token::tVariable && + lex[1].eType == Token::tEquals ) + { + // Assignment! + expr(); + return; + } + exprP(); +} + +void Parser::exprP() +{ + switch( lex[0].eType ) + { + case Token::tNumber: + case Token::tVariable: + tsStack.push( lex[0] ); + lex.nextToken(); + break; + + case Token::tOpenParen: + lex.nextToken(); + expr(); + if( lex[0].eType != Token::tCloseParen ) + { + throw Bu::ExceptionBase("Expected close paren"); + } + lex.nextToken(); + break; + + case Token::tMinus: + lex.nextToken(); + exprP(); + tsStack.push( Token( Token::tNegate ) ); + break; + } +} +/* for(;;) { Token t = lex.nextToken(); @@ -158,6 +210,7 @@ void Parser::parse() } } } +*/ Number Parser::getVariable( const Bu::String &sName ) { @@ -171,6 +224,7 @@ void Parser::setVariable( const Bu::String &sName, const Number &rValue ) void Parser::unwind() { + /* for(;;) { DBS_START( PARSE ); @@ -312,6 +366,7 @@ void Parser::unwind() getPriority( t.eType ) ) return; } + */ } int Parser::reqTokens( Token::Type eType ) diff --git a/src/parser.h b/src/parser.h index e163212..d50951b 100644 --- a/src/parser.h +++ b/src/parser.h @@ -13,6 +13,35 @@ namespace Bu class Lexer; +/** + * + * expr: literal + * | variable + * | expr '+' expr + * | expr '-' expr + * | expr '*' expr + * | expr '/' expr + * | '(' expr ')' + * | '-' expr + * | variable '=' expr + * ; + * + * ----- + * + * expr': literal + * | variable + * | '(' expr ')' + * | '-' expr' + * ; + * + * expr: expr' '+' expr + * | expr' '-' expr + * | expr' '*' expr + * | expr' '/' expr + * | expr' + * | variable '=' expr + * ; + */ class Parser { public: @@ -23,6 +52,10 @@ public: Number getVariable( const Bu::String &sName ); void setVariable( const Bu::String &sName, const Number &rValue ); +private: + void expr(); + void exprP(); + private: void unwind(); int reqTokens( Token::Type eType ); @@ -34,8 +67,8 @@ private: Bu::Stream &rOut; typedef Bu::List TokenStack; typedef Bu::Hash VarHash; - TokenStack tsTerminal; - TokenStack tsNonTerminal; + TokenStack tsStack; +// TokenStack tsNonTerminal; Number nZero; VarHash hVars; }; diff --git a/src/token.cpp b/src/token.cpp index a03c821..30f3566 100644 --- a/src/token.cpp +++ b/src/token.cpp @@ -4,6 +4,12 @@ #include #include +Token::Token() : + eType( tUninitialized ), + sVal( 0 ) +{ +} + Token::Token( Type eType ) : eType( eType ), sVal( 0 ) diff --git a/src/token.h b/src/token.h index 92a7bcc..12a4904 100644 --- a/src/token.h +++ b/src/token.h @@ -26,11 +26,15 @@ public: tEquals, tString, + tNegate, tEndOfLine, - tEndOfInput + tEndOfInput, + + tUninitialized }; + Token(); Token( Type eType ); Token( Type eType, Bu::String *s ); Token( Type eType, Number *n ); diff --git a/src/unitparser.cpp b/src/unitparser.cpp index f518fdc..09b5982 100644 --- a/src/unitparser.cpp +++ b/src/unitparser.cpp @@ -13,6 +13,8 @@ UnitParser::UnitParser() "order1", Bu::UnitSuite::expectPass ); add( static_cast(&UnitParser::assignment), "assignment", Bu::UnitSuite::expectPass ); + add( static_cast(&UnitParser::parse1), + "parse1", Bu::UnitSuite::expectPass ); } UnitParser::~UnitParser() @@ -55,3 +57,8 @@ void UnitParser::assignment() unitTest( mbOut.getString().trimWhitespace() == parser.getVariable("test").toString() ); } +void UnitParser::parse1() +{ + unitTest(parse("-5") == "-5"); +} + diff --git a/src/unitparser.h b/src/unitparser.h index 744deef..c3b3687 100644 --- a/src/unitparser.h +++ b/src/unitparser.h @@ -11,6 +11,7 @@ public: void order1(); void assignment(); + void parse1(); }; #endif -- cgit v1.2.3