From 00ecd458ced768b3b8752cdd421a22244b7adc01 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Sun, 17 Oct 2010 05:50:57 +0000 Subject: 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 = :) --- src/tools/parser.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 80 insertions(+), 9 deletions(-) (limited to 'src/tools') 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: void redAdd( Bu::Parser &p ) { + Lexer::Token *a = p.popToken(); + Lexer::Token *b = p.popToken(); + + sio << "Add! " << b->vExtra.get() << " + " + << a->vExtra.get() << sio.nl; + + Lexer::Token *c = new Lexer::Token( tokNumber, + b->vExtra.get() + a->vExtra.get() + ); + p.pushToken( c ); + + delete a; + delete b; +} + +void redSubtract( Bu::Parser &p ) +{ + Lexer::Token *a = p.popToken(); + Lexer::Token *b = p.popToken(); + + sio << "Subtract! " << b->vExtra.get() << " - " + << a->vExtra.get() << sio.nl; + + Lexer::Token *c = new Lexer::Token( tokNumber, + b->vExtra.get() - a->vExtra.get() + ); + p.pushToken( c ); + + delete a; + delete b; } void redPrint( Bu::Parser &p ) { + Lexer::Token *a = p.popToken(); + sio << "Print! = " << a->vExtra.get() << sio.nl; + delete a; } /* Basic grammer example: @@ -170,14 +203,15 @@ void redPrint( Bu::Parser &p ) * The problem is, that we can't actually make something left hand recursive, * so we break it into two exprs: * - * expr': '(' expr ')' + * expr-sub1: '(' expr ')' * | NUMBER * ; * - * expr: expr' expr'' + * expr: expr-sub1 expr-sub2 * ; * - * expr'': '+' expr + * expr-sub2: '+' expr + * | '-' expr * | * ; * @@ -191,8 +225,8 @@ int main( int argc, char *argv[] ) Parser p; p.addNonTerminal("expr"); - p.addNonTerminal("expr'"); - p.addNonTerminal("expr''"); + p.addNonTerminal("expr-sub1"); + p.addNonTerminal("expr-sub2"); { Parser::NonTerminal nt; nt.addProduction( @@ -213,12 +247,30 @@ int main( int argc, char *argv[] ) ) ) ); + nt.addProduction( + Parser::Production( + Parser::State( + Parser::State::typeTerminal, + tokMinus + ) + ).append( + Parser::State( + Parser::State::typeNonTerminal, + p.getNonTerminalId("expr") + ) + ).append( + Parser::State( + Parser::State::typeReduction, + p.addReduction("subtract") + ) + ) + ); nt.addProduction( Parser::Production( ) ); nt.setCanSkip(); - p.setNonTerminal("expr''", nt ); + p.setNonTerminal("expr-sub2", nt ); } { Parser::NonTerminal nt; @@ -230,7 +282,25 @@ int main( int argc, char *argv[] ) ) ) ); - p.setNonTerminal("expr'", nt ); + nt.addProduction( + Parser::Production( + Parser::State( + Parser::State::typeTerminal, + tokOpenParen + ) + ).append( + Parser::State( + Parser::State::typeNonTerminal, + p.getNonTerminalId("expr") + ) + ).append( + Parser::State( + Parser::State::typeTerminal, + tokCloseParen + ) + ) + ); + p.setNonTerminal("expr-sub1", nt ); } { Parser::NonTerminal nt; @@ -238,12 +308,12 @@ int main( int argc, char *argv[] ) Parser::Production( Parser::State( Parser::State::typeNonTerminal, - p.getNonTerminalId("expr'") + p.getNonTerminalId("expr-sub1") ) ).append( Parser::State( Parser::State::typeNonTerminal, - p.getNonTerminalId("expr''") + p.getNonTerminalId("expr-sub2") ) ) ); @@ -275,6 +345,7 @@ int main( int argc, char *argv[] ) p.setRootNonTerminal("input"); p.setReduction("add", Bu::slot( &redAdd ) ); + p.setReduction("subtract", Bu::slot( &redSubtract ) ); p.setReduction("print", Bu::slot( &redPrint ) ); p.pushLexer( new MathLexer( fIn ) ); -- cgit v1.2.3