diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/parser.cpp | 110 | ||||
-rw-r--r-- | src/parser.h | 3 | ||||
-rw-r--r-- | src/scriptengine.cpp | 8 |
3 files changed, 74 insertions, 47 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 701c4bd..e9388c8 100644 --- a/src/parser.cpp +++ b/src/parser.cpp | |||
@@ -8,6 +8,13 @@ | |||
8 | #include <bu/sio.h> | 8 | #include <bu/sio.h> |
9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
10 | 10 | ||
11 | // #define DEBUG_MODE 1 | ||
12 | #ifdef DEBUG_MODE | ||
13 | #define DBG( x ) { x; } (void)0 | ||
14 | #else | ||
15 | #define DBG( x ) (void)0 | ||
16 | #endif | ||
17 | |||
11 | Parser::Parser( Lexer &lex ) : | 18 | Parser::Parser( Lexer &lex ) : |
12 | lex( lex ) | 19 | lex( lex ) |
13 | { | 20 | { |
@@ -21,10 +28,15 @@ Expression *Parser::parse() | |||
21 | { | 28 | { |
22 | pCurExp = new Expression(); | 29 | pCurExp = new Expression(); |
23 | statement(); | 30 | statement(); |
31 | while( !tsTerminal.isEmpty() ) | ||
32 | { | ||
33 | reduce(); | ||
34 | } | ||
24 | 35 | ||
25 | printState("Final"); | 36 | printState("Final"); |
26 | 37 | ||
27 | tsParse.clear(); | 38 | tsTerminal.clear(); |
39 | tsNonTerminal.clear(); | ||
28 | 40 | ||
29 | Expression *pTmp = pCurExp; | 41 | Expression *pTmp = pCurExp; |
30 | pCurExp = NULL; | 42 | pCurExp = NULL; |
@@ -34,12 +46,17 @@ Expression *Parser::parse() | |||
34 | void Parser::exprR() | 46 | void Parser::exprR() |
35 | { | 47 | { |
36 | exprP(); | 48 | exprP(); |
37 | expr(); | 49 | for(;;) |
50 | { | ||
51 | expr(); | ||
52 | if( !(lex[0].eType & Token::mMetaOperator) ) | ||
53 | break; | ||
54 | } | ||
38 | } | 55 | } |
39 | 56 | ||
40 | void Parser::expr() | 57 | void Parser::expr() |
41 | { | 58 | { |
42 | Bu::sio << "::expr " << lex[0] << Bu::sio.nl; | 59 | DBG( Bu::sio << "::expr " << lex[0] << Bu::sio.nl ); |
43 | if( lex[0].eType == Token::tEndOfInput ) | 60 | if( lex[0].eType == Token::tEndOfInput ) |
44 | return; | 61 | return; |
45 | 62 | ||
@@ -56,7 +73,7 @@ void Parser::expr() | |||
56 | case Token::tModulus: | 73 | case Token::tModulus: |
57 | Token t = lex[0]; | 74 | Token t = lex[0]; |
58 | lex.nextToken(); | 75 | lex.nextToken(); |
59 | Bu::sio << "->expr " << t << " " << lex[0] << Bu::sio.nl; | 76 | DBG( Bu::sio << "->expr " << t << " " << lex[0] << Bu::sio.nl ); |
60 | if( lex[0].eType == Token::tOpenParen ) | 77 | if( lex[0].eType == Token::tOpenParen ) |
61 | { | 78 | { |
62 | exprP(); | 79 | exprP(); |
@@ -69,40 +86,42 @@ void Parser::expr() | |||
69 | if( lex[0].eType == Token::tNumber || | 86 | if( lex[0].eType == Token::tNumber || |
70 | lex[0].eType == Token::tVariable ) | 87 | lex[0].eType == Token::tVariable ) |
71 | { | 88 | { |
72 | Bu::sio << "->expr " << t << | 89 | DBG( Bu::sio << "->expr " << t << |
73 | " " << lex[0] << | 90 | " " << lex[0] << |
74 | " " << lex[1] << | 91 | " " << lex[1] << |
75 | Bu::sio.nl; | 92 | Bu::sio.nl ); |
76 | shift( lex[0] ); | 93 | shift( lex[0] ); |
94 | shift( t ); | ||
77 | if( lex[1].eType&Token::mMetaOperator ) | 95 | if( lex[1].eType&Token::mMetaOperator ) |
78 | { | 96 | { |
79 | if( getPriority(lex[1].eType) <= | 97 | if( getPriority(lex[1].eType) < |
80 | getPriority(t.eType) ) | 98 | getPriority(t.eType) ) |
81 | { | 99 | { |
82 | shift( t ); | 100 | while( !tsTerminal.isEmpty() ) |
83 | reduce(); | 101 | { |
102 | reduce(); | ||
103 | } | ||
84 | printState("reduce"); | 104 | printState("reduce"); |
85 | lex.nextToken(); | 105 | lex.nextToken(); |
86 | expr(); | 106 | // expr(); |
87 | } | 107 | } |
88 | else | 108 | else |
89 | { | 109 | { |
90 | printState("no reduce"); | 110 | printState("no reduce"); |
91 | lex.nextToken(); | 111 | lex.nextToken(); |
92 | expr(); | 112 | // expr(); |
93 | if( !tsParse.isEmpty() && | 113 | /* |
114 | if( !tsNonTerminal.isEmpty() && | ||
94 | tsParse.peek().eType != Token::tComputedValue ) | 115 | tsParse.peek().eType != Token::tComputedValue ) |
95 | { | 116 | { |
96 | reduce(); | 117 | //reduce(); |
97 | printState("no reduce reduce"); | 118 | //printState("no reduce reduce"); |
98 | } | 119 | }*/ |
99 | shift( t ); | ||
100 | printState("post no reduce"); | 120 | printState("post no reduce"); |
101 | } | 121 | } |
102 | } | 122 | } |
103 | else | 123 | else |
104 | { | 124 | { |
105 | shift( t ); | ||
106 | lex.nextToken(); | 125 | lex.nextToken(); |
107 | printState("no next op"); | 126 | printState("no next op"); |
108 | } | 127 | } |
@@ -110,14 +129,14 @@ void Parser::expr() | |||
110 | else if( lex[0].eType == Token::tMinus ) | 129 | else if( lex[0].eType == Token::tMinus ) |
111 | { | 130 | { |
112 | // This is negation | 131 | // This is negation |
113 | Bu::sio << "next token: " << lex[0] << Bu::sio.nl; | 132 | DBG( Bu::sio << "next token: " << lex[0] << Bu::sio.nl ); |
114 | printState("inline-negate"); | 133 | printState("inline-negate"); |
115 | exprP(); | 134 | exprP(); |
116 | printState("inline-negate-post"); | 135 | printState("inline-negate-post"); |
117 | shift( t ); | 136 | shift( t ); |
118 | printState("inline-negate-post2"); | 137 | printState("inline-negate-post2"); |
119 | 138 | ||
120 | Bu::sio << "??? " << lex[0] << Bu::sio.nl; | 139 | DBG( Bu::sio << "??? " << lex[0] << Bu::sio.nl ); |
121 | } | 140 | } |
122 | } | 141 | } |
123 | break; | 142 | break; |
@@ -156,7 +175,7 @@ void Parser::exprP() | |||
156 | exprR(); | 175 | exprR(); |
157 | if( lex[0].eType != Token::tCloseParen ) | 176 | if( lex[0].eType != Token::tCloseParen ) |
158 | { | 177 | { |
159 | Bu::sio << "::exprP " << lex[0] << Bu::sio.nl; | 178 | DBG( Bu::sio << "::exprP " << lex[0] << Bu::sio.nl ); |
160 | throw Bu::ExceptionBase("Expected close paren"); | 179 | throw Bu::ExceptionBase("Expected close paren"); |
161 | } | 180 | } |
162 | shift( lex[0] ); | 181 | shift( lex[0] ); |
@@ -281,16 +300,20 @@ case Token::tCommand: | |||
281 | 300 | ||
282 | void Parser::shift( const Token &t ) | 301 | void Parser::shift( const Token &t ) |
283 | { | 302 | { |
284 | tsParse.push( t ); | 303 | if( (t.eType&(Token::mMetaOperator)) || t.eType==Token::tCloseParen ) |
304 | tsTerminal.push( t ); | ||
305 | else | ||
306 | tsNonTerminal.push( t ); | ||
285 | } | 307 | } |
286 | 308 | ||
287 | void Parser::reduce() | 309 | void Parser::reduce() |
288 | { | 310 | { |
289 | if( tsParse.isEmpty() || tsParse.peek().eType == Token::tOpenParen ) | 311 | if( tsTerminal.isEmpty() || tsNonTerminal.peek().eType == Token::tOpenParen ) |
290 | return; | 312 | return; |
291 | Token tOp = tsParse.peekPop(); | 313 | Token tOp = tsTerminal.peekPop(); |
292 | switch( tOp.eType ) | 314 | switch( tOp.eType ) |
293 | { | 315 | { |
316 | /* | ||
294 | case Token::tNumber: | 317 | case Token::tNumber: |
295 | case Token::tVariable: | 318 | case Token::tVariable: |
296 | output( tOp ); | 319 | output( tOp ); |
@@ -300,25 +323,18 @@ void Parser::reduce() | |||
300 | case Token::tComputedValue: | 323 | case Token::tComputedValue: |
301 | tsParse.push( Token( Token::tComputedValue ) ); | 324 | tsParse.push( Token( Token::tComputedValue ) ); |
302 | break; | 325 | break; |
303 | 326 | */ | |
304 | case Token::tPlus: | 327 | case Token::tPlus: |
305 | case Token::tMinus: | 328 | case Token::tMinus: |
306 | case Token::tDivide: | 329 | case Token::tDivide: |
307 | case Token::tMultiply: | 330 | case Token::tMultiply: |
308 | case Token::tModulus: | 331 | case Token::tModulus: |
309 | case Token::tEquals: | 332 | case Token::tEquals: |
310 | for(int j = 0; j < 2; j++ ) | ||
311 | { | 333 | { |
312 | Token t = tsParse.peekPop(); | 334 | Token a = tsNonTerminal.peekPop(); |
313 | if( t.eType == Token::tNumber || | 335 | Token b = tsNonTerminal.peekPop(); |
314 | t.eType == Token::tVariable ) | 336 | output( b ); |
315 | { | 337 | output( a ); |
316 | output( t ); | ||
317 | } | ||
318 | else if( t.eType == Token::tComputedValue ) | ||
319 | { | ||
320 | // Nope, we don't care | ||
321 | } | ||
322 | } | 338 | } |
323 | output( tOp ); | 339 | output( tOp ); |
324 | shift( Token( Token::tComputedValue ) ); | 340 | shift( Token( Token::tComputedValue ) ); |
@@ -326,7 +342,7 @@ void Parser::reduce() | |||
326 | 342 | ||
327 | case Token::tNegate: | 343 | case Token::tNegate: |
328 | { | 344 | { |
329 | Token t = tsParse.peekPop(); | 345 | Token t = tsNonTerminal.peekPop(); |
330 | if( t.eType != Token::tComputedValue ) | 346 | if( t.eType != Token::tComputedValue ) |
331 | output( t ); | 347 | output( t ); |
332 | output( tOp ); | 348 | output( tOp ); |
@@ -335,16 +351,16 @@ void Parser::reduce() | |||
335 | break; | 351 | break; |
336 | 352 | ||
337 | case Token::tCloseParen: | 353 | case Token::tCloseParen: |
338 | if( tsParse.peek().eType != Token::tComputedValue ) | 354 | if( tsNonTerminal.peek().eType != Token::tComputedValue ) |
339 | { | 355 | { |
340 | printState("paren-innerReduce-pre"); | 356 | printState("paren-innerReduce-pre"); |
341 | reduce(); | 357 | reduce(); |
342 | printState("paren-innerReduce-post"); | 358 | printState("paren-innerReduce-post"); |
343 | } | 359 | } |
344 | tsParse.pop(); | 360 | tsNonTerminal.pop(); |
345 | if( tsParse.peek().eType == Token::tOpenParen ) | 361 | if( tsNonTerminal.peek().eType == Token::tOpenParen ) |
346 | { | 362 | { |
347 | tsParse.pop(); | 363 | tsNonTerminal.pop(); |
348 | shift( Token( Token::tComputedValue ) ); | 364 | shift( Token( Token::tComputedValue ) ); |
349 | } | 365 | } |
350 | else | 366 | else |
@@ -357,6 +373,8 @@ void Parser::reduce() | |||
357 | 373 | ||
358 | void Parser::output( const Token &t ) | 374 | void Parser::output( const Token &t ) |
359 | { | 375 | { |
376 | if( t.eType == Token::tComputedValue ) | ||
377 | return; | ||
360 | pCurExp->append( t ); | 378 | pCurExp->append( t ); |
361 | } | 379 | } |
362 | 380 | ||
@@ -417,9 +435,16 @@ int Parser::getPriority( Token::Type eType ) | |||
417 | 435 | ||
418 | void Parser::printState( const Bu::String &sTag ) | 436 | void Parser::printState( const Bu::String &sTag ) |
419 | { | 437 | { |
438 | #ifdef DEBUG_MODE | ||
420 | Bu::sio << "----------------" << Bu::sio.nl; | 439 | Bu::sio << "----------------" << Bu::sio.nl; |
421 | Bu::sio << sTag << " stack:"; | 440 | Bu::sio << sTag << " non-terminals:"; |
422 | for( TokenStack::iterator i = tsParse.begin(); i; i++ ) | 441 | for( TokenStack::iterator i = tsNonTerminal.begin(); i; i++ ) |
442 | { | ||
443 | Bu::sio << " " << (*i); | ||
444 | } | ||
445 | Bu::sio << Bu::sio.nl; | ||
446 | Bu::sio << sTag << " terminal:"; | ||
447 | for( TokenStack::iterator i = tsTerminal.begin(); i; i++ ) | ||
423 | { | 448 | { |
424 | Bu::sio << " " << (*i); | 449 | Bu::sio << " " << (*i); |
425 | } | 450 | } |
@@ -431,5 +456,6 @@ void Parser::printState( const Bu::String &sTag ) | |||
431 | } | 456 | } |
432 | Bu::sio << Bu::sio.nl; | 457 | Bu::sio << Bu::sio.nl; |
433 | Bu::sio << "----------------" << Bu::sio.nl; | 458 | Bu::sio << "----------------" << Bu::sio.nl; |
459 | #endif | ||
434 | } | 460 | } |
435 | 461 | ||
diff --git a/src/parser.h b/src/parser.h index 60dd8e1..cc97222 100644 --- a/src/parser.h +++ b/src/parser.h | |||
@@ -69,7 +69,8 @@ private: | |||
69 | private: | 69 | private: |
70 | Lexer &lex; | 70 | Lexer &lex; |
71 | typedef Bu::List<Token> TokenStack; | 71 | typedef Bu::List<Token> TokenStack; |
72 | TokenStack tsParse; | 72 | TokenStack tsTerminal; |
73 | TokenStack tsNonTerminal; | ||
73 | Expression *pCurExp; | 74 | Expression *pCurExp; |
74 | }; | 75 | }; |
75 | 76 | ||
diff --git a/src/scriptengine.cpp b/src/scriptengine.cpp index b828409..65b6ec2 100644 --- a/src/scriptengine.cpp +++ b/src/scriptengine.cpp | |||
@@ -57,32 +57,32 @@ Number ScriptEngine::exec( Expression *pExpr ) | |||
57 | 57 | ||
58 | case Token::tPlus: | 58 | case Token::tPlus: |
59 | { | 59 | { |
60 | Number a = sNums.peekPop(); | ||
61 | Number b = sNums.peekPop(); | 60 | Number b = sNums.peekPop(); |
61 | Number a = sNums.peekPop(); | ||
62 | sNums.push( a + b ); | 62 | sNums.push( a + b ); |
63 | } | 63 | } |
64 | break; | 64 | break; |
65 | 65 | ||
66 | case Token::tMinus: | 66 | case Token::tMinus: |
67 | { | 67 | { |
68 | Number a = sNums.peekPop(); | ||
69 | Number b = sNums.peekPop(); | 68 | Number b = sNums.peekPop(); |
69 | Number a = sNums.peekPop(); | ||
70 | sNums.push( a - b ); | 70 | sNums.push( a - b ); |
71 | } | 71 | } |
72 | break; | 72 | break; |
73 | 73 | ||
74 | case Token::tDivide: | 74 | case Token::tDivide: |
75 | { | 75 | { |
76 | Number a = sNums.peekPop(); | ||
77 | Number b = sNums.peekPop(); | 76 | Number b = sNums.peekPop(); |
77 | Number a = sNums.peekPop(); | ||
78 | sNums.push( a / b ); | 78 | sNums.push( a / b ); |
79 | } | 79 | } |
80 | break; | 80 | break; |
81 | 81 | ||
82 | case Token::tMultiply: | 82 | case Token::tMultiply: |
83 | { | 83 | { |
84 | Number a = sNums.peekPop(); | ||
85 | Number b = sNums.peekPop(); | 84 | Number b = sNums.peekPop(); |
85 | Number a = sNums.peekPop(); | ||
86 | sNums.push( a * b ); | 86 | sNums.push( a * b ); |
87 | } | 87 | } |
88 | break; | 88 | break; |