aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2010-10-17 05:50:57 +0000
committerMike Buland <eichlan@xagasoft.com>2010-10-17 05:50:57 +0000
commit00ecd458ced768b3b8752cdd421a22244b7adc01 (patch)
treea0b2ad00db46b61b269be6090a386cb88e6bf7f2 /src
parent9031e2af7dd4e65ec70890ee78a7cf600d1b2cc5 (diff)
downloadlibbu++-00ecd458ced768b3b8752cdd421a22244b7adc01.tar.gz
libbu++-00ecd458ced768b3b8752cdd421a22244b7adc01.tar.bz2
libbu++-00ecd458ced768b3b8752cdd421a22244b7adc01.tar.xz
libbu++-00ecd458ced768b3b8752cdd421a22244b7adc01.zip
Hey! The parser parses now! It's actually a little stupid, I didn't implement
lookahead or precedence, but I should be able to do that easily with the next version. I'm treating this more as a proof of concept than a real working model. Although it can handle +, -, (), and = :)
Diffstat (limited to '')
-rw-r--r--src/parser.cpp24
-rw-r--r--src/parser.h3
-rw-r--r--src/tools/parser.cpp89
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
25Lexer::Token *Bu::Parser::popToken()
26{
27 return sToken.peekPop();
28}
29
30void Bu::Parser::pushToken( Lexer::Token *pTok )
31{
32 sToken.push( pTok );
33}
34
25void Bu::Parser::parse() 35void 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
152void redAdd( Bu::Parser &p ) 152void 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
169void 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
156void redPrint( Bu::Parser &p ) 186void 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 ) );