diff options
author | Mike Buland <eichlan@xagasoft.com> | 2010-10-17 05:50:57 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2010-10-17 05:50:57 +0000 |
commit | 00ecd458ced768b3b8752cdd421a22244b7adc01 (patch) | |
tree | a0b2ad00db46b61b269be6090a386cb88e6bf7f2 /src/tools/parser.cpp | |
parent | 9031e2af7dd4e65ec70890ee78a7cf600d1b2cc5 (diff) | |
download | libbu++-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/tools/parser.cpp | 89 |
1 files changed, 80 insertions, 9 deletions
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 | ||
152 | void redAdd( Bu::Parser &p ) | 152 | void 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 | |||
169 | void 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 | ||
156 | void redPrint( Bu::Parser &p ) | 186 | void 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 ) ); |