From fc16fc104a038146c8ab6c2e9fad38e18663a09f Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 12 Oct 2010 18:10:47 +0000 Subject: It's getting close. I'm not 100% sure abouth this method yet... --- src/parser.cpp | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 149 insertions(+), 11 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/parser.cpp b/src/parser.cpp index e8e8ff2..b563691 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -24,21 +24,127 @@ void Bu::Parser::popLexer() void Bu::Parser::parse() { - for(;;) + int iCurNt = iRootNonTerminal; + Lexer::Token *ptCur = sLexer.peek()->nextToken(); + //Lexer::Token *ptNext = sLexer.peek()->nextToken(); + selectProduction( iCurNt, ptCur ); + sio << "Token: " << *ptCur << sio.nl; + + while( !sState.isEmpty() ) { - Bu::Lexer::Token *pToken = sLexer.peek()->nextToken(); - sio << sLexer.peek()->tokenToString( *pToken ) << sio.nl; - if( pToken->iToken < 0 ) + sio << "Currently: " << *sState.peek() << sio.nl; + switch( (*sState.peek()).eType ) { - delete sLexer.peekPop(); - if( sLexer.isEmpty() ) + case State::typeTerminal: + sio << "terminal: " << ptCur->iToken << " == " + << (*sState.peek()).iIndex << sio.nl; + if( ptCur->iToken == (*sState.peek()).iIndex ) + { + advanceState(); + delete ptCur; + ptCur = sLexer.peek()->nextToken(); + sio << "Token: " << *ptCur << sio.nl; + } + else + { + throw Bu::ExceptionBase("Error parsing code."); + } + break; + + case State::typeTerminalPush: + sio << "terminalpush: " << ptCur->iToken << " == " + << (*sState.peek()).iIndex << sio.nl; + if( ptCur->iToken == (*sState.peek()).iIndex ) + { + advanceState(); + sToken.push( ptCur ); + + ptCur = sLexer.peek()->nextToken(); + sio << "Token: " << *ptCur << sio.nl; + } + else + { + throw Bu::ExceptionBase("Error parsing code."); + } + break; + + case State::typeNonTerminal: + sio << "nonterminal: " << ptCur->iToken << " --> " + << (*sState.peek()).iIndex << sio.nl; + { + int iNt = (*sState.peek()).iIndex; + advanceState(); + if( !selectProduction( iNt, ptCur ) ) + { + throw Bu::ExceptionBase("Error parsing code."); + } + } + break; + + case State::typeReduction: + sio << "reduction" << sio.nl; + aReduction[(*sState.peek()).iIndex]( *this ); + advanceState(); + break; + } + } +} + +bool Bu::Parser::selectProduction( int iNt, Lexer::Token *ptCur ) +{ + NonTerminal &nt = aNonTerminal[iNt]; + int j = 0; + for( NonTerminal::ProductionList::iterator i = nt.lProduction.begin(); + i; i++,j++ ) + { + if( (*i).isEmpty() ) + continue; + if( (*i).first().eType == State::typeTerminal || + (*i).first().eType == State::typeTerminalPush ) + { + if( (*i).first().iIndex == ptCur->iToken ) { - delete pToken; - return; + sState.push( (*i).begin() ); + sio << "Pushing production " << j << " from nt " << iNt + << sio.nl; + return true; } } - delete pToken; - } + else if( (*i).first().eType == State::typeNonTerminal ) + { + sState.push( (*i).begin() ); + sio << "Pushing production " << j << " from nt " << iNt + << " as test." << sio.nl; + if( !selectProduction( (*i).first().iIndex, ptCur ) ) + { + sState.pop(); + sio << "Production " << j << " from nt " << iNt + << " didn't work out." << sio.nl; + } + else + { + return true; + } + } + } + if( nt.bCanSkip ) + return true; + return false; +} + +void Bu::Parser::advanceState() +{ + if( sState.isEmpty() ) + return; + + sState.peek()++; + if( !sState.peek() ) + { + sState.pop(); + sio << "State advanced, End of production." << sio.nl; + return; + } + sio << "State advanced, now: " << *(sState.peek()) << sio.nl; } void Bu::Parser::setRootNonTerminal( int iRoot ) @@ -56,6 +162,7 @@ int Bu::Parser::addNonTerminal( const Bu::FString &sName, NonTerminal &nt ) int iId = aNonTerminal.getSize(); aNonTerminal.append( nt ); hNonTerminalName.insert( sName, iId ); + sio << "nt '" << sName << "' = " << iId << sio.nl; return iId; } @@ -64,6 +171,7 @@ int Bu::Parser::addNonTerminal( const Bu::FString &sName ) int iId = aNonTerminal.getSize(); aNonTerminal.append( NonTerminal() ); hNonTerminalName.insert( sName, iId ); + sio << "nt '" << sName << "' = " << iId << sio.nl; return iId; } @@ -121,7 +229,8 @@ Bu::Parser::State::~State() // Bu::Parser::NonTerminal // -Bu::Parser::NonTerminal::NonTerminal() +Bu::Parser::NonTerminal::NonTerminal() : + bCanSkip( false ) { } @@ -134,3 +243,32 @@ void Bu::Parser::NonTerminal::addProduction( Production p ) lProduction.append( p ); } +void Bu::Parser::NonTerminal::setCanSkip() +{ + bCanSkip = true; +} + +Bu::Formatter &Bu::operator<<( Bu::Formatter &f, Bu::Parser::State::Type t ) +{ + switch( t ) + { + case Bu::Parser::State::typeTerminal: + return f << "typeTerminal"; + + case Bu::Parser::State::typeTerminalPush: + return f << "typeTerminalPush"; + + case Bu::Parser::State::typeNonTerminal: + return f << "typeNonTerminal"; + + case Bu::Parser::State::typeReduction: + return f << "typeReduction"; + } + return f << "***error***"; +} + +Bu::Formatter &Bu::operator<<( Bu::Formatter &f, const Bu::Parser::State &s ) +{ + return f << "{" << s.eType << ": " << s.iIndex << "}"; +} + -- cgit v1.2.3