summaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp213
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
39void Parser::exprR()
40{
41 exprP();
42 expr();
43}
44
54void Parser::expr() 45void 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
85void Parser::exprP() 129void 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
207void Parser::reduce() 273void 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
211int Parser::reqTokens( Token::Type eType ) 334int Parser::reqTokens( Token::Type eType )
@@ -263,3 +386,21 @@ int Parser::getPriority( Token::Type eType )
263 } 386 }
264} 387}
265 388
389void 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