diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/parser.cpp | 24 | ||||
| -rw-r--r-- | src/parser.h | 3 | ||||
| -rw-r--r-- | src/tools/parser.cpp | 89 |
3 files changed, 102 insertions, 14 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index e4e8ae5..3ce73b6 100644 --- a/src/parser.cpp +++ b/src/parser.cpp | |||
| @@ -22,16 +22,25 @@ void Bu::Parser::popLexer() | |||
| 22 | delete sLexer.peekPop(); | 22 | delete sLexer.peekPop(); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | Lexer::Token *Bu::Parser::popToken() | ||
| 26 | { | ||
| 27 | return sToken.peekPop(); | ||
| 28 | } | ||
| 29 | |||
| 30 | void Bu::Parser::pushToken( Lexer::Token *pTok ) | ||
| 31 | { | ||
| 32 | sToken.push( pTok ); | ||
| 33 | } | ||
| 34 | |||
| 25 | void Bu::Parser::parse() | 35 | void Bu::Parser::parse() |
| 26 | { | 36 | { |
| 27 | int iCurNt = iRootNonTerminal; | 37 | int iCurNt = iRootNonTerminal; |
| 28 | Lexer::Token *ptCur = sLexer.peek()->nextToken(); | 38 | Lexer::Token *ptCur = sLexer.peek()->nextToken(); |
| 29 | sio << "Token: " << sLexer.peek()->tokenToString( *ptCur ) << sio.nl; | 39 | sio << "Token(a): " << sLexer.peek()->tokenToString( *ptCur ) << sio.nl; |
| 30 | selectProduction( iCurNt, ptCur ); | 40 | selectProduction( iCurNt, ptCur ); |
| 31 | 41 | ||
| 32 | while( !sState.isEmpty() ) | 42 | while( !sState.isEmpty() ) |
| 33 | { | 43 | { |
| 34 | sio << "Currently: " << *sState.peek() << sio.nl; | ||
| 35 | switch( (*sState.peek()).eType ) | 44 | switch( (*sState.peek()).eType ) |
| 36 | { | 45 | { |
| 37 | case State::typeTerminal: | 46 | case State::typeTerminal: |
| @@ -42,7 +51,7 @@ void Bu::Parser::parse() | |||
| 42 | advanceState(); | 51 | advanceState(); |
| 43 | delete ptCur; | 52 | delete ptCur; |
| 44 | ptCur = sLexer.peek()->nextToken(); | 53 | ptCur = sLexer.peek()->nextToken(); |
| 45 | sio << "Token: " << sLexer.peek()->tokenToString( *ptCur ) << sio.nl; | 54 | sio << "Token(b): " << sLexer.peek()->tokenToString( *ptCur ) << sio.nl; |
| 46 | } | 55 | } |
| 47 | else | 56 | else |
| 48 | { | 57 | { |
| @@ -59,7 +68,7 @@ void Bu::Parser::parse() | |||
| 59 | sToken.push( ptCur ); | 68 | sToken.push( ptCur ); |
| 60 | 69 | ||
| 61 | ptCur = sLexer.peek()->nextToken(); | 70 | ptCur = sLexer.peek()->nextToken(); |
| 62 | sio << "Token: " << sLexer.peek()->tokenToString( *ptCur ) << sio.nl; | 71 | sio << "Token(c): " << sLexer.peek()->tokenToString( *ptCur ) << sio.nl; |
| 63 | } | 72 | } |
| 64 | else | 73 | else |
| 65 | { | 74 | { |
| @@ -72,7 +81,7 @@ void Bu::Parser::parse() | |||
| 72 | << (*sState.peek()).iIndex << sio.nl; | 81 | << (*sState.peek()).iIndex << sio.nl; |
| 73 | { | 82 | { |
| 74 | int iNt = (*sState.peek()).iIndex; | 83 | int iNt = (*sState.peek()).iIndex; |
| 75 | advanceState(); | 84 | sio << "Current state: " << *sState.peek() << sio.nl; |
| 76 | if( !selectProduction( iNt, ptCur ) ) | 85 | if( !selectProduction( iNt, ptCur ) ) |
| 77 | { | 86 | { |
| 78 | throw Bu::ExceptionBase("Error parsing code."); | 87 | throw Bu::ExceptionBase("Error parsing code."); |
| @@ -132,7 +141,11 @@ bool Bu::Parser::selectProduction( int iNt, Lexer::Token *ptCur ) | |||
| 132 | } | 141 | } |
| 133 | } | 142 | } |
| 134 | if( nt.bCanSkip ) | 143 | if( nt.bCanSkip ) |
| 144 | { | ||
| 145 | sio << "Nothing matches, skipping non-terminal." << sio.nl; | ||
| 146 | advanceState(); | ||
| 135 | return true; | 147 | return true; |
| 148 | } | ||
| 136 | sio << "-->(Found nothing)" << sio.nl; | 149 | sio << "-->(Found nothing)" << sio.nl; |
| 137 | return false; | 150 | return false; |
| 138 | } | 151 | } |
| @@ -148,6 +161,7 @@ void Bu::Parser::advanceState() | |||
| 148 | sio.decIndent(); | 161 | sio.decIndent(); |
| 149 | sState.pop(); | 162 | sState.pop(); |
| 150 | sio << "State advanced, End of production." << sio.nl; | 163 | sio << "State advanced, End of production." << sio.nl; |
| 164 | advanceState(); | ||
| 151 | return; | 165 | return; |
| 152 | } | 166 | } |
| 153 | sio << "State advanced, now: " << *(sState.peek()) << sio.nl; | 167 | sio << "State advanced, now: " << *(sState.peek()) << sio.nl; |
diff --git a/src/parser.h b/src/parser.h index 5b5d4a8..1679c7f 100644 --- a/src/parser.h +++ b/src/parser.h | |||
| @@ -34,6 +34,9 @@ namespace Bu | |||
| 34 | */ | 34 | */ |
| 35 | void popLexer(); | 35 | void popLexer(); |
| 36 | 36 | ||
| 37 | Lexer::Token *popToken(); | ||
| 38 | void pushToken( Lexer::Token *pTok ); | ||
| 39 | |||
| 37 | /** | 40 | /** |
| 38 | * Execute a parse. | 41 | * Execute a parse. |
| 39 | */ | 42 | */ |
diff --git a/src/tools/parser.cpp b/src/tools/parser.cpp index 76d4a72..7933f31 100644 --- a/src/tools/parser.cpp +++ b/src/tools/parser.cpp | |||
| @@ -151,10 +151,43 @@ private: | |||
| 151 | 151 | ||
| 152 | void redAdd( Bu::Parser &p ) | 152 | void redAdd( Bu::Parser &p ) |
| 153 | { | 153 | { |
| 154 | Lexer::Token *a = p.popToken(); | ||
| 155 | Lexer::Token *b = p.popToken(); | ||
| 156 | |||
| 157 | sio << "Add! " << b->vExtra.get<double>() << " + " | ||
| 158 | << a->vExtra.get<double>() << sio.nl; | ||
| 159 | |||
| 160 | Lexer::Token *c = new Lexer::Token( tokNumber, | ||
| 161 | b->vExtra.get<double>() + a->vExtra.get<double>() | ||
| 162 | ); | ||
| 163 | p.pushToken( c ); | ||
| 164 | |||
| 165 | delete a; | ||
| 166 | delete b; | ||
| 167 | } | ||
| 168 | |||
| 169 | void redSubtract( Bu::Parser &p ) | ||
| 170 | { | ||
| 171 | Lexer::Token *a = p.popToken(); | ||
| 172 | Lexer::Token *b = p.popToken(); | ||
| 173 | |||
| 174 | sio << "Subtract! " << b->vExtra.get<double>() << " - " | ||
| 175 | << a->vExtra.get<double>() << sio.nl; | ||
| 176 | |||
| 177 | Lexer::Token *c = new Lexer::Token( tokNumber, | ||
| 178 | b->vExtra.get<double>() - a->vExtra.get<double>() | ||
| 179 | ); | ||
| 180 | p.pushToken( c ); | ||
| 181 | |||
| 182 | delete a; | ||
| 183 | delete b; | ||
| 154 | } | 184 | } |
| 155 | 185 | ||
| 156 | void redPrint( Bu::Parser &p ) | 186 | void redPrint( Bu::Parser &p ) |
| 157 | { | 187 | { |
| 188 | Lexer::Token *a = p.popToken(); | ||
| 189 | sio << "Print! = " << a->vExtra.get<double>() << sio.nl; | ||
| 190 | delete a; | ||
| 158 | } | 191 | } |
| 159 | 192 | ||
| 160 | /* Basic grammer example: | 193 | /* Basic grammer example: |
| @@ -170,14 +203,15 @@ void redPrint( Bu::Parser &p ) | |||
| 170 | * The problem is, that we can't actually make something left hand recursive, | 203 | * The problem is, that we can't actually make something left hand recursive, |
| 171 | * so we break it into two exprs: | 204 | * so we break it into two exprs: |
| 172 | * | 205 | * |
| 173 | * expr': '(' expr ')' | 206 | * expr-sub1: '(' expr ')' |
| 174 | * | NUMBER | 207 | * | NUMBER |
| 175 | * ; | 208 | * ; |
| 176 | * | 209 | * |
| 177 | * expr: expr' expr'' | 210 | * expr: expr-sub1 expr-sub2 |
| 178 | * ; | 211 | * ; |
| 179 | * | 212 | * |
| 180 | * expr'': '+' expr | 213 | * expr-sub2: '+' expr |
| 214 | * | '-' expr | ||
| 181 | * | | 215 | * | |
| 182 | * ; | 216 | * ; |
| 183 | * | 217 | * |
| @@ -191,8 +225,8 @@ int main( int argc, char *argv[] ) | |||
| 191 | Parser p; | 225 | Parser p; |
| 192 | 226 | ||
| 193 | p.addNonTerminal("expr"); | 227 | p.addNonTerminal("expr"); |
| 194 | p.addNonTerminal("expr'"); | 228 | p.addNonTerminal("expr-sub1"); |
| 195 | p.addNonTerminal("expr''"); | 229 | p.addNonTerminal("expr-sub2"); |
| 196 | { | 230 | { |
| 197 | Parser::NonTerminal nt; | 231 | Parser::NonTerminal nt; |
| 198 | nt.addProduction( | 232 | nt.addProduction( |
| @@ -215,10 +249,28 @@ int main( int argc, char *argv[] ) | |||
| 215 | ); | 249 | ); |
| 216 | nt.addProduction( | 250 | nt.addProduction( |
| 217 | Parser::Production( | 251 | Parser::Production( |
| 252 | Parser::State( | ||
| 253 | Parser::State::typeTerminal, | ||
| 254 | tokMinus | ||
| 255 | ) | ||
| 256 | ).append( | ||
| 257 | Parser::State( | ||
| 258 | Parser::State::typeNonTerminal, | ||
| 259 | p.getNonTerminalId("expr") | ||
| 260 | ) | ||
| 261 | ).append( | ||
| 262 | Parser::State( | ||
| 263 | Parser::State::typeReduction, | ||
| 264 | p.addReduction("subtract") | ||
| 265 | ) | ||
| 266 | ) | ||
| 267 | ); | ||
| 268 | nt.addProduction( | ||
| 269 | Parser::Production( | ||
| 218 | ) | 270 | ) |
| 219 | ); | 271 | ); |
| 220 | nt.setCanSkip(); | 272 | nt.setCanSkip(); |
| 221 | p.setNonTerminal("expr''", nt ); | 273 | p.setNonTerminal("expr-sub2", nt ); |
| 222 | } | 274 | } |
| 223 | { | 275 | { |
| 224 | Parser::NonTerminal nt; | 276 | Parser::NonTerminal nt; |
| @@ -230,7 +282,25 @@ int main( int argc, char *argv[] ) | |||
| 230 | ) | 282 | ) |
| 231 | ) | 283 | ) |
| 232 | ); | 284 | ); |
| 233 | p.setNonTerminal("expr'", nt ); | 285 | nt.addProduction( |
| 286 | Parser::Production( | ||
| 287 | Parser::State( | ||
| 288 | Parser::State::typeTerminal, | ||
| 289 | tokOpenParen | ||
| 290 | ) | ||
| 291 | ).append( | ||
| 292 | Parser::State( | ||
| 293 | Parser::State::typeNonTerminal, | ||
| 294 | p.getNonTerminalId("expr") | ||
| 295 | ) | ||
| 296 | ).append( | ||
| 297 | Parser::State( | ||
| 298 | Parser::State::typeTerminal, | ||
| 299 | tokCloseParen | ||
| 300 | ) | ||
| 301 | ) | ||
| 302 | ); | ||
| 303 | p.setNonTerminal("expr-sub1", nt ); | ||
| 234 | } | 304 | } |
| 235 | { | 305 | { |
| 236 | Parser::NonTerminal nt; | 306 | Parser::NonTerminal nt; |
| @@ -238,12 +308,12 @@ int main( int argc, char *argv[] ) | |||
| 238 | Parser::Production( | 308 | Parser::Production( |
| 239 | Parser::State( | 309 | Parser::State( |
| 240 | Parser::State::typeNonTerminal, | 310 | Parser::State::typeNonTerminal, |
| 241 | p.getNonTerminalId("expr'") | 311 | p.getNonTerminalId("expr-sub1") |
| 242 | ) | 312 | ) |
| 243 | ).append( | 313 | ).append( |
| 244 | Parser::State( | 314 | Parser::State( |
| 245 | Parser::State::typeNonTerminal, | 315 | Parser::State::typeNonTerminal, |
| 246 | p.getNonTerminalId("expr''") | 316 | p.getNonTerminalId("expr-sub2") |
| 247 | ) | 317 | ) |
| 248 | ) | 318 | ) |
| 249 | ); | 319 | ); |
| @@ -275,6 +345,7 @@ int main( int argc, char *argv[] ) | |||
| 275 | p.setRootNonTerminal("input"); | 345 | p.setRootNonTerminal("input"); |
| 276 | 346 | ||
| 277 | p.setReduction("add", Bu::slot( &redAdd ) ); | 347 | p.setReduction("add", Bu::slot( &redAdd ) ); |
| 348 | p.setReduction("subtract", Bu::slot( &redSubtract ) ); | ||
| 278 | p.setReduction("print", Bu::slot( &redPrint ) ); | 349 | p.setReduction("print", Bu::slot( &redPrint ) ); |
| 279 | 350 | ||
| 280 | p.pushLexer( new MathLexer( fIn ) ); | 351 | p.pushLexer( new MathLexer( fIn ) ); |
