summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2016-12-01 11:54:52 -0700
committerMike Buland <eichlan@xagasoft.com>2016-12-01 11:54:52 -0700
commit17a39c19e5bff97c3b3d2bc888a3bb5ded7c1b96 (patch)
tree77ed32bfbcfc84ae5ebf2da468d6cca47796dc55 /src
parent32b48aeb75db4ad40fe0173614e585f9bee72257 (diff)
downloadclic-17a39c19e5bff97c3b3d2bc888a3bb5ded7c1b96.tar.gz
clic-17a39c19e5bff97c3b3d2bc888a3bb5ded7c1b96.tar.bz2
clic-17a39c19e5bff97c3b3d2bc888a3bb5ded7c1b96.tar.xz
clic-17a39c19e5bff97c3b3d2bc888a3bb5ded7c1b96.zip
Terrible parsing issues are behind us now.
At least...those issues are behind us. We'll see what happens next. Also, added some macros to make debugging easily optional.
Diffstat (limited to 'src')
-rw-r--r--src/parser.cpp110
-rw-r--r--src/parser.h3
-rw-r--r--src/scriptengine.cpp8
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
11Parser::Parser( Lexer &lex ) : 18Parser::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()
34void Parser::exprR() 46void 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
40void Parser::expr() 57void 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
282void Parser::shift( const Token &t ) 301void 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
287void Parser::reduce() 309void 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
358void Parser::output( const Token &t ) 374void 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
418void Parser::printState( const Bu::String &sTag ) 436void 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:
69private: 69private:
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;