diff options
| author | Mike Buland <eichlan@xagasoft.com> | 2010-10-12 18:10:47 +0000 |
|---|---|---|
| committer | Mike Buland <eichlan@xagasoft.com> | 2010-10-12 18:10:47 +0000 |
| commit | fc16fc104a038146c8ab6c2e9fad38e18663a09f (patch) | |
| tree | b8b50c7349ebd2869ee8599be89c82705235fd2a /src/parser.cpp | |
| parent | 0981b9d6a12bd7aadbf9286459e033ac1a2ba910 (diff) | |
| download | libbu++-fc16fc104a038146c8ab6c2e9fad38e18663a09f.tar.gz libbu++-fc16fc104a038146c8ab6c2e9fad38e18663a09f.tar.bz2 libbu++-fc16fc104a038146c8ab6c2e9fad38e18663a09f.tar.xz libbu++-fc16fc104a038146c8ab6c2e9fad38e18663a09f.zip | |
It's getting close. I'm not 100% sure abouth this method yet...
Diffstat (limited to '')
| -rw-r--r-- | src/parser.cpp | 160 |
1 files changed, 149 insertions, 11 deletions
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() | |||
| 24 | 24 | ||
| 25 | void Bu::Parser::parse() | 25 | void Bu::Parser::parse() |
| 26 | { | 26 | { |
| 27 | for(;;) | 27 | int iCurNt = iRootNonTerminal; |
| 28 | Lexer::Token *ptCur = sLexer.peek()->nextToken(); | ||
| 29 | //Lexer::Token *ptNext = sLexer.peek()->nextToken(); | ||
| 30 | selectProduction( iCurNt, ptCur ); | ||
| 31 | sio << "Token: " << *ptCur << sio.nl; | ||
| 32 | |||
| 33 | while( !sState.isEmpty() ) | ||
| 28 | { | 34 | { |
| 29 | Bu::Lexer::Token *pToken = sLexer.peek()->nextToken(); | 35 | sio << "Currently: " << *sState.peek() << sio.nl; |
| 30 | sio << sLexer.peek()->tokenToString( *pToken ) << sio.nl; | 36 | switch( (*sState.peek()).eType ) |
| 31 | if( pToken->iToken < 0 ) | ||
| 32 | { | 37 | { |
| 33 | delete sLexer.peekPop(); | 38 | case State::typeTerminal: |
| 34 | if( sLexer.isEmpty() ) | 39 | sio << "terminal: " << ptCur->iToken << " == " |
| 40 | << (*sState.peek()).iIndex << sio.nl; | ||
| 41 | if( ptCur->iToken == (*sState.peek()).iIndex ) | ||
| 42 | { | ||
| 43 | advanceState(); | ||
| 44 | delete ptCur; | ||
| 45 | ptCur = sLexer.peek()->nextToken(); | ||
| 46 | sio << "Token: " << *ptCur << sio.nl; | ||
| 47 | } | ||
| 48 | else | ||
| 49 | { | ||
| 50 | throw Bu::ExceptionBase("Error parsing code."); | ||
| 51 | } | ||
| 52 | break; | ||
| 53 | |||
| 54 | case State::typeTerminalPush: | ||
| 55 | sio << "terminalpush: " << ptCur->iToken << " == " | ||
| 56 | << (*sState.peek()).iIndex << sio.nl; | ||
| 57 | if( ptCur->iToken == (*sState.peek()).iIndex ) | ||
| 58 | { | ||
| 59 | advanceState(); | ||
| 60 | sToken.push( ptCur ); | ||
| 61 | |||
| 62 | ptCur = sLexer.peek()->nextToken(); | ||
| 63 | sio << "Token: " << *ptCur << sio.nl; | ||
| 64 | } | ||
| 65 | else | ||
| 66 | { | ||
| 67 | throw Bu::ExceptionBase("Error parsing code."); | ||
| 68 | } | ||
| 69 | break; | ||
| 70 | |||
| 71 | case State::typeNonTerminal: | ||
| 72 | sio << "nonterminal: " << ptCur->iToken << " --> " | ||
| 73 | << (*sState.peek()).iIndex << sio.nl; | ||
| 74 | { | ||
| 75 | int iNt = (*sState.peek()).iIndex; | ||
| 76 | advanceState(); | ||
| 77 | if( !selectProduction( iNt, ptCur ) ) | ||
| 78 | { | ||
| 79 | throw Bu::ExceptionBase("Error parsing code."); | ||
| 80 | } | ||
| 81 | } | ||
| 82 | break; | ||
| 83 | |||
| 84 | case State::typeReduction: | ||
| 85 | sio << "reduction" << sio.nl; | ||
| 86 | aReduction[(*sState.peek()).iIndex]( *this ); | ||
| 87 | advanceState(); | ||
| 88 | break; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | bool Bu::Parser::selectProduction( int iNt, Lexer::Token *ptCur ) | ||
| 94 | { | ||
| 95 | NonTerminal &nt = aNonTerminal[iNt]; | ||
| 96 | int j = 0; | ||
| 97 | for( NonTerminal::ProductionList::iterator i = nt.lProduction.begin(); | ||
| 98 | i; i++,j++ ) | ||
| 99 | { | ||
| 100 | if( (*i).isEmpty() ) | ||
| 101 | continue; | ||
| 102 | if( (*i).first().eType == State::typeTerminal || | ||
| 103 | (*i).first().eType == State::typeTerminalPush ) | ||
| 104 | { | ||
| 105 | if( (*i).first().iIndex == ptCur->iToken ) | ||
| 35 | { | 106 | { |
| 36 | delete pToken; | 107 | sState.push( (*i).begin() ); |
| 37 | return; | 108 | sio << "Pushing production " << j << " from nt " << iNt |
| 109 | << sio.nl; | ||
| 110 | return true; | ||
| 38 | } | 111 | } |
| 39 | } | 112 | } |
| 40 | delete pToken; | 113 | else if( (*i).first().eType == State::typeNonTerminal ) |
| 41 | } | 114 | { |
| 115 | sState.push( (*i).begin() ); | ||
| 116 | sio << "Pushing production " << j << " from nt " << iNt | ||
| 117 | << " as test." << sio.nl; | ||
| 118 | if( !selectProduction( (*i).first().iIndex, ptCur ) ) | ||
| 119 | { | ||
| 120 | sState.pop(); | ||
| 121 | sio << "Production " << j << " from nt " << iNt | ||
| 122 | << " didn't work out." << sio.nl; | ||
| 123 | } | ||
| 124 | else | ||
| 125 | { | ||
| 126 | return true; | ||
| 127 | } | ||
| 128 | } | ||
| 129 | } | ||
| 130 | if( nt.bCanSkip ) | ||
| 131 | return true; | ||
| 132 | return false; | ||
| 133 | } | ||
| 134 | |||
| 135 | void Bu::Parser::advanceState() | ||
| 136 | { | ||
| 137 | if( sState.isEmpty() ) | ||
| 138 | return; | ||
| 139 | |||
| 140 | sState.peek()++; | ||
| 141 | if( !sState.peek() ) | ||
| 142 | { | ||
| 143 | sState.pop(); | ||
| 144 | sio << "State advanced, End of production." << sio.nl; | ||
| 145 | return; | ||
| 146 | } | ||
| 147 | sio << "State advanced, now: " << *(sState.peek()) << sio.nl; | ||
| 42 | } | 148 | } |
| 43 | 149 | ||
| 44 | void Bu::Parser::setRootNonTerminal( int iRoot ) | 150 | void Bu::Parser::setRootNonTerminal( int iRoot ) |
| @@ -56,6 +162,7 @@ int Bu::Parser::addNonTerminal( const Bu::FString &sName, NonTerminal &nt ) | |||
| 56 | int iId = aNonTerminal.getSize(); | 162 | int iId = aNonTerminal.getSize(); |
| 57 | aNonTerminal.append( nt ); | 163 | aNonTerminal.append( nt ); |
| 58 | hNonTerminalName.insert( sName, iId ); | 164 | hNonTerminalName.insert( sName, iId ); |
| 165 | sio << "nt '" << sName << "' = " << iId << sio.nl; | ||
| 59 | return iId; | 166 | return iId; |
| 60 | } | 167 | } |
| 61 | 168 | ||
| @@ -64,6 +171,7 @@ int Bu::Parser::addNonTerminal( const Bu::FString &sName ) | |||
| 64 | int iId = aNonTerminal.getSize(); | 171 | int iId = aNonTerminal.getSize(); |
| 65 | aNonTerminal.append( NonTerminal() ); | 172 | aNonTerminal.append( NonTerminal() ); |
| 66 | hNonTerminalName.insert( sName, iId ); | 173 | hNonTerminalName.insert( sName, iId ); |
| 174 | sio << "nt '" << sName << "' = " << iId << sio.nl; | ||
| 67 | return iId; | 175 | return iId; |
| 68 | } | 176 | } |
| 69 | 177 | ||
| @@ -121,7 +229,8 @@ Bu::Parser::State::~State() | |||
| 121 | // Bu::Parser::NonTerminal | 229 | // Bu::Parser::NonTerminal |
| 122 | // | 230 | // |
| 123 | 231 | ||
| 124 | Bu::Parser::NonTerminal::NonTerminal() | 232 | Bu::Parser::NonTerminal::NonTerminal() : |
| 233 | bCanSkip( false ) | ||
| 125 | { | 234 | { |
| 126 | } | 235 | } |
| 127 | 236 | ||
| @@ -134,3 +243,32 @@ void Bu::Parser::NonTerminal::addProduction( Production p ) | |||
| 134 | lProduction.append( p ); | 243 | lProduction.append( p ); |
| 135 | } | 244 | } |
| 136 | 245 | ||
| 246 | void Bu::Parser::NonTerminal::setCanSkip() | ||
| 247 | { | ||
| 248 | bCanSkip = true; | ||
| 249 | } | ||
| 250 | |||
| 251 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, Bu::Parser::State::Type t ) | ||
| 252 | { | ||
| 253 | switch( t ) | ||
| 254 | { | ||
| 255 | case Bu::Parser::State::typeTerminal: | ||
| 256 | return f << "typeTerminal"; | ||
| 257 | |||
| 258 | case Bu::Parser::State::typeTerminalPush: | ||
| 259 | return f << "typeTerminalPush"; | ||
| 260 | |||
| 261 | case Bu::Parser::State::typeNonTerminal: | ||
| 262 | return f << "typeNonTerminal"; | ||
| 263 | |||
| 264 | case Bu::Parser::State::typeReduction: | ||
| 265 | return f << "typeReduction"; | ||
| 266 | } | ||
| 267 | return f << "***error***"; | ||
| 268 | } | ||
| 269 | |||
| 270 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, const Bu::Parser::State &s ) | ||
| 271 | { | ||
| 272 | return f << "{" << s.eType << ": " << s.iIndex << "}"; | ||
| 273 | } | ||
| 274 | |||
