diff options
Diffstat (limited to '')
| -rw-r--r-- | src/parser.cpp | 213 |
1 files changed, 177 insertions, 36 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 510b471..f88ffe7 100644 --- a/src/parser.cpp +++ b/src/parser.cpp | |||
| @@ -26,49 +26,34 @@ void Parser::parse() | |||
| 26 | if( lex[0].eType == Token::tEndOfInput ) | 26 | if( lex[0].eType == Token::tEndOfInput ) |
| 27 | break; | 27 | break; |
| 28 | 28 | ||
| 29 | expr(); | 29 | exprR(); |
| 30 | reduce(); | ||
| 30 | 31 | ||
| 31 | Bu::sio << "Final stack:"; | 32 | printState("Final"); |
| 32 | for( TokenStack::iterator i = tsParse.begin(); i; i++ ) | 33 | |
| 33 | { | 34 | tsParse.clear(); |
| 34 | Bu::sio << " " << (*i).eType; | 35 | tsScript.clear(); |
| 35 | if( (*i).eType == Token::tNumber ) | ||
| 36 | { | ||
| 37 | Bu::sio << "(" << (*i).nVal->toString() << ")"; | ||
| 38 | } | ||
| 39 | } | ||
| 40 | Bu::sio << Bu::sio.nl; | ||
| 41 | Bu::sio << "Script:"; | ||
| 42 | for( TokenStack::iterator i = tsScript.begin(); i; i++ ) | ||
| 43 | { | ||
| 44 | Bu::sio << " " << (*i).eType; | ||
| 45 | if( (*i).eType == Token::tNumber ) | ||
| 46 | { | ||
| 47 | Bu::sio << "(" << (*i).nVal->toString() << ")"; | ||
| 48 | } | ||
| 49 | } | ||
| 50 | Bu::sio << Bu::sio.nl; | ||
| 51 | } | 36 | } |
| 52 | } | 37 | } |
| 53 | 38 | ||
| 39 | void Parser::exprR() | ||
| 40 | { | ||
| 41 | exprP(); | ||
| 42 | expr(); | ||
| 43 | } | ||
| 44 | |||
| 54 | void Parser::expr() | 45 | void Parser::expr() |
| 55 | { | 46 | { |
| 47 | Bu::sio << "::expr " << lex[0] << Bu::sio.nl; | ||
| 56 | if( lex[0].eType == Token::tEndOfInput ) | 48 | if( lex[0].eType == Token::tEndOfInput ) |
| 57 | return; | 49 | return; |
| 58 | if( lex[0].eType == Token::tVariable && | ||
| 59 | lex[1].eType == Token::tEquals ) | ||
| 60 | { | ||
| 61 | Token t = lex[0]; | ||
| 62 | lex.nextToken(); | ||
| 63 | lex.nextToken(); | ||
| 64 | expr(); | ||
| 65 | |||
| 66 | return; | ||
| 67 | } | ||
| 68 | exprP(); | ||
| 69 | 50 | ||
| 70 | switch( lex[0].eType ) | 51 | switch( lex[0].eType ) |
| 71 | { | 52 | { |
| 53 | case Token::tEquals: | ||
| 54 | throw Bu::ExceptionBase("misplaced equals."); | ||
| 55 | break; | ||
| 56 | |||
| 72 | case Token::tPlus: | 57 | case Token::tPlus: |
| 73 | case Token::tMinus: | 58 | case Token::tMinus: |
| 74 | case Token::tMultiply: | 59 | case Token::tMultiply: |
| @@ -76,30 +61,111 @@ void Parser::expr() | |||
| 76 | case Token::tModulus: | 61 | case Token::tModulus: |
| 77 | Token t = lex[0]; | 62 | Token t = lex[0]; |
| 78 | lex.nextToken(); | 63 | lex.nextToken(); |
| 79 | expr(); | 64 | Bu::sio << "->expr " << t << " " << lex[0] << Bu::sio.nl; |
| 80 | shift( t ); | 65 | if( lex[0].eType == Token::tOpenParen ) |
| 66 | { | ||
| 67 | exprP(); | ||
| 68 | shift( t ); | ||
| 69 | reduce(); | ||
| 70 | expr(); | ||
| 71 | } | ||
| 72 | else | ||
| 73 | { | ||
| 74 | if( lex[0].eType == Token::tNumber || | ||
| 75 | lex[0].eType == Token::tVariable ) | ||
| 76 | { | ||
| 77 | Bu::sio << "->expr " << t << | ||
| 78 | " " << lex[0] << | ||
| 79 | " " << lex[1] << | ||
| 80 | Bu::sio.nl; | ||
| 81 | shift( lex[0] ); | ||
| 82 | if( lex[1].eType == Token::tPlus || | ||
| 83 | lex[1].eType == Token::tMinus || | ||
| 84 | lex[1].eType == Token::tDivide || | ||
| 85 | lex[1].eType == Token::tMultiply || | ||
| 86 | lex[1].eType == Token::tModulus || | ||
| 87 | lex[1].eType == Token::tEquals ) | ||
| 88 | { | ||
| 89 | if( getPriority(lex[1].eType) <= | ||
| 90 | getPriority(t.eType) ) | ||
| 91 | { | ||
| 92 | shift( t ); | ||
| 93 | reduce(); | ||
| 94 | printState("reduce"); | ||
| 95 | lex.nextToken(); | ||
| 96 | expr(); | ||
| 97 | } | ||
| 98 | else | ||
| 99 | { | ||
| 100 | printState("no reduce"); | ||
| 101 | lex.nextToken(); | ||
| 102 | expr(); | ||
| 103 | if( !tsParse.isEmpty() && | ||
| 104 | tsParse.peek().eType != Token::tComputedValue ) | ||
| 105 | { | ||
| 106 | reduce(); | ||
| 107 | printState("no reduce reduce"); | ||
| 108 | } | ||
| 109 | shift( t ); | ||
| 110 | printState("post no reduce"); | ||
| 111 | } | ||
| 112 | } | ||
| 113 | else | ||
| 114 | { | ||
| 115 | shift( t ); | ||
| 116 | lex.nextToken(); | ||
| 117 | printState("no next op"); | ||
| 118 | } | ||
| 119 | } | ||
| 120 | else | ||
| 121 | { | ||
| 122 | Bu::println("???"); | ||
| 123 | } | ||
| 124 | } | ||
| 81 | break; | 125 | break; |
| 82 | } | 126 | } |
| 83 | } | 127 | } |
| 84 | 128 | ||
| 85 | void Parser::exprP() | 129 | void Parser::exprP() |
| 86 | { | 130 | { |
| 131 | if( lex[0].eType == Token::tVariable && | ||
| 132 | lex[1].eType == Token::tEquals ) | ||
| 133 | { | ||
| 134 | Token t = lex[0]; | ||
| 135 | lex.nextToken( 2 ); | ||
| 136 | exprR(); | ||
| 137 | reduce(); | ||
| 138 | printState("pre-equals"); | ||
| 139 | shift( t ); | ||
| 140 | shift( Token( Token::tEquals ) ); | ||
| 141 | printState("post-equals"); | ||
| 142 | reduce(); | ||
| 143 | printState("post-equals-reduce"); | ||
| 144 | return; | ||
| 145 | } | ||
| 146 | |||
| 87 | switch( lex[0].eType ) | 147 | switch( lex[0].eType ) |
| 88 | { | 148 | { |
| 89 | case Token::tNumber: | 149 | case Token::tNumber: |
| 90 | case Token::tVariable: | 150 | case Token::tVariable: |
| 91 | shift( lex[0] ); | 151 | shift( lex[0] ); |
| 92 | lex.nextToken(); | 152 | lex.nextToken(); |
| 93 | break; | 153 | break; |
| 94 | 154 | ||
| 95 | case Token::tOpenParen: | 155 | case Token::tOpenParen: |
| 156 | shift( lex[0] ); | ||
| 96 | lex.nextToken(); | 157 | lex.nextToken(); |
| 97 | expr(); | 158 | exprR(); |
| 98 | if( lex[0].eType != Token::tCloseParen ) | 159 | if( lex[0].eType != Token::tCloseParen ) |
| 99 | { | 160 | { |
| 161 | Bu::sio << "::exprP " << lex[0] << Bu::sio.nl; | ||
| 100 | throw Bu::ExceptionBase("Expected close paren"); | 162 | throw Bu::ExceptionBase("Expected close paren"); |
| 101 | } | 163 | } |
| 164 | shift( lex[0] ); | ||
| 165 | printState("closeParen"); | ||
| 166 | reduce(); | ||
| 102 | lex.nextToken(); | 167 | lex.nextToken(); |
| 168 | printState("post closeParen"); | ||
| 103 | break; | 169 | break; |
| 104 | 170 | ||
| 105 | case Token::tMinus: | 171 | case Token::tMinus: |
| @@ -206,6 +272,63 @@ void Parser::shift( const Token &t ) | |||
| 206 | 272 | ||
| 207 | void Parser::reduce() | 273 | void Parser::reduce() |
| 208 | { | 274 | { |
| 275 | if( tsParse.isEmpty() || tsParse.peek().eType == Token::tOpenParen ) | ||
| 276 | return; | ||
| 277 | Token tOp = tsParse.peekPop(); | ||
| 278 | switch( tOp.eType ) | ||
| 279 | { | ||
| 280 | case Token::tNumber: | ||
| 281 | case Token::tVariable: | ||
| 282 | tsScript.append( tOp ); | ||
| 283 | tsParse.push( Token( Token::tComputedValue ) ); | ||
| 284 | break; | ||
| 285 | |||
| 286 | case Token::tComputedValue: | ||
| 287 | tsParse.push( Token( Token::tComputedValue ) ); | ||
| 288 | break; | ||
| 289 | |||
| 290 | case Token::tPlus: | ||
| 291 | case Token::tMinus: | ||
| 292 | case Token::tDivide: | ||
| 293 | case Token::tMultiply: | ||
| 294 | case Token::tModulus: | ||
| 295 | case Token::tEquals: | ||
| 296 | for(int j = 0; j < 2; j++ ) | ||
| 297 | { | ||
| 298 | Token t = tsParse.peekPop(); | ||
| 299 | if( t.eType == Token::tNumber || | ||
| 300 | t.eType == Token::tVariable ) | ||
| 301 | { | ||
| 302 | tsScript.append( t ); | ||
| 303 | } | ||
| 304 | else if( t.eType == Token::tComputedValue ) | ||
| 305 | { | ||
| 306 | // Nope, we don't care | ||
| 307 | } | ||
| 308 | } | ||
| 309 | tsScript.append( tOp ); | ||
| 310 | shift( Token( Token::tComputedValue ) ); | ||
| 311 | break; | ||
| 312 | |||
| 313 | case Token::tCloseParen: | ||
| 314 | if( tsParse.peek().eType != Token::tComputedValue ) | ||
| 315 | { | ||
| 316 | printState("paren-innerReduce-pre"); | ||
| 317 | reduce(); | ||
| 318 | printState("paren-innerReduce-post"); | ||
| 319 | } | ||
| 320 | tsParse.pop(); | ||
| 321 | if( tsParse.peek().eType == Token::tOpenParen ) | ||
| 322 | { | ||
| 323 | tsParse.pop(); | ||
| 324 | shift( Token( Token::tComputedValue ) ); | ||
| 325 | } | ||
| 326 | else | ||
| 327 | { | ||
| 328 | throw Bu::ExceptionBase("Error?"); | ||
| 329 | } | ||
| 330 | break; | ||
| 331 | } | ||
| 209 | } | 332 | } |
| 210 | 333 | ||
| 211 | int Parser::reqTokens( Token::Type eType ) | 334 | int Parser::reqTokens( Token::Type eType ) |
| @@ -263,3 +386,21 @@ int Parser::getPriority( Token::Type eType ) | |||
| 263 | } | 386 | } |
| 264 | } | 387 | } |
| 265 | 388 | ||
| 389 | void Parser::printState( const Bu::String &sTag ) | ||
| 390 | { | ||
| 391 | Bu::sio << "----------------" << Bu::sio.nl; | ||
| 392 | Bu::sio << sTag << " stack:"; | ||
| 393 | for( TokenStack::iterator i = tsParse.begin(); i; i++ ) | ||
| 394 | { | ||
| 395 | Bu::sio << " " << (*i); | ||
| 396 | } | ||
| 397 | Bu::sio << Bu::sio.nl; | ||
| 398 | Bu::sio << sTag << " script:"; | ||
| 399 | for( TokenStack::iterator i = tsScript.begin(); i; i++ ) | ||
| 400 | { | ||
| 401 | Bu::sio << " " << (*i); | ||
| 402 | } | ||
| 403 | Bu::sio << Bu::sio.nl; | ||
| 404 | Bu::sio << "----------------" << Bu::sio.nl; | ||
| 405 | } | ||
| 406 | |||
