From 17a39c19e5bff97c3b3d2bc888a3bb5ded7c1b96 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Thu, 1 Dec 2016 11:54:52 -0700 Subject: 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. --- src/parser.cpp | 110 +++++++++++++++++++++++++++++++-------------------- src/parser.h | 3 +- src/scriptengine.cpp | 8 ++-- 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 @@ #include #include +// #define DEBUG_MODE 1 +#ifdef DEBUG_MODE +#define DBG( x ) { x; } (void)0 +#else +#define DBG( x ) (void)0 +#endif + Parser::Parser( Lexer &lex ) : lex( lex ) { @@ -21,10 +28,15 @@ Expression *Parser::parse() { pCurExp = new Expression(); statement(); + while( !tsTerminal.isEmpty() ) + { + reduce(); + } printState("Final"); - tsParse.clear(); + tsTerminal.clear(); + tsNonTerminal.clear(); Expression *pTmp = pCurExp; pCurExp = NULL; @@ -34,12 +46,17 @@ Expression *Parser::parse() void Parser::exprR() { exprP(); - expr(); + for(;;) + { + expr(); + if( !(lex[0].eType & Token::mMetaOperator) ) + break; + } } void Parser::expr() { - Bu::sio << "::expr " << lex[0] << Bu::sio.nl; + DBG( Bu::sio << "::expr " << lex[0] << Bu::sio.nl ); if( lex[0].eType == Token::tEndOfInput ) return; @@ -56,7 +73,7 @@ void Parser::expr() case Token::tModulus: Token t = lex[0]; lex.nextToken(); - Bu::sio << "->expr " << t << " " << lex[0] << Bu::sio.nl; + DBG( Bu::sio << "->expr " << t << " " << lex[0] << Bu::sio.nl ); if( lex[0].eType == Token::tOpenParen ) { exprP(); @@ -69,40 +86,42 @@ void Parser::expr() if( lex[0].eType == Token::tNumber || lex[0].eType == Token::tVariable ) { - Bu::sio << "->expr " << t << + DBG( Bu::sio << "->expr " << t << " " << lex[0] << " " << lex[1] << - Bu::sio.nl; + Bu::sio.nl ); shift( lex[0] ); + shift( t ); if( lex[1].eType&Token::mMetaOperator ) { - if( getPriority(lex[1].eType) <= + if( getPriority(lex[1].eType) < getPriority(t.eType) ) { - shift( t ); - reduce(); + while( !tsTerminal.isEmpty() ) + { + reduce(); + } printState("reduce"); lex.nextToken(); - expr(); +// expr(); } else { printState("no reduce"); lex.nextToken(); - expr(); - if( !tsParse.isEmpty() && +// expr(); + /* + if( !tsNonTerminal.isEmpty() && tsParse.peek().eType != Token::tComputedValue ) { - reduce(); - printState("no reduce reduce"); - } - shift( t ); + //reduce(); + //printState("no reduce reduce"); + }*/ printState("post no reduce"); } } else { - shift( t ); lex.nextToken(); printState("no next op"); } @@ -110,14 +129,14 @@ void Parser::expr() else if( lex[0].eType == Token::tMinus ) { // This is negation - Bu::sio << "next token: " << lex[0] << Bu::sio.nl; + DBG( Bu::sio << "next token: " << lex[0] << Bu::sio.nl ); printState("inline-negate"); exprP(); printState("inline-negate-post"); shift( t ); printState("inline-negate-post2"); - Bu::sio << "??? " << lex[0] << Bu::sio.nl; + DBG( Bu::sio << "??? " << lex[0] << Bu::sio.nl ); } } break; @@ -156,7 +175,7 @@ void Parser::exprP() exprR(); if( lex[0].eType != Token::tCloseParen ) { - Bu::sio << "::exprP " << lex[0] << Bu::sio.nl; + DBG( Bu::sio << "::exprP " << lex[0] << Bu::sio.nl ); throw Bu::ExceptionBase("Expected close paren"); } shift( lex[0] ); @@ -281,16 +300,20 @@ case Token::tCommand: void Parser::shift( const Token &t ) { - tsParse.push( t ); + if( (t.eType&(Token::mMetaOperator)) || t.eType==Token::tCloseParen ) + tsTerminal.push( t ); + else + tsNonTerminal.push( t ); } void Parser::reduce() { - if( tsParse.isEmpty() || tsParse.peek().eType == Token::tOpenParen ) + if( tsTerminal.isEmpty() || tsNonTerminal.peek().eType == Token::tOpenParen ) return; - Token tOp = tsParse.peekPop(); + Token tOp = tsTerminal.peekPop(); switch( tOp.eType ) { + /* case Token::tNumber: case Token::tVariable: output( tOp ); @@ -300,25 +323,18 @@ void Parser::reduce() case Token::tComputedValue: tsParse.push( Token( Token::tComputedValue ) ); break; - +*/ case Token::tPlus: case Token::tMinus: case Token::tDivide: case Token::tMultiply: case Token::tModulus: case Token::tEquals: - for(int j = 0; j < 2; j++ ) { - Token t = tsParse.peekPop(); - if( t.eType == Token::tNumber || - t.eType == Token::tVariable ) - { - output( t ); - } - else if( t.eType == Token::tComputedValue ) - { - // Nope, we don't care - } + Token a = tsNonTerminal.peekPop(); + Token b = tsNonTerminal.peekPop(); + output( b ); + output( a ); } output( tOp ); shift( Token( Token::tComputedValue ) ); @@ -326,7 +342,7 @@ void Parser::reduce() case Token::tNegate: { - Token t = tsParse.peekPop(); + Token t = tsNonTerminal.peekPop(); if( t.eType != Token::tComputedValue ) output( t ); output( tOp ); @@ -335,16 +351,16 @@ void Parser::reduce() break; case Token::tCloseParen: - if( tsParse.peek().eType != Token::tComputedValue ) + if( tsNonTerminal.peek().eType != Token::tComputedValue ) { printState("paren-innerReduce-pre"); reduce(); printState("paren-innerReduce-post"); } - tsParse.pop(); - if( tsParse.peek().eType == Token::tOpenParen ) + tsNonTerminal.pop(); + if( tsNonTerminal.peek().eType == Token::tOpenParen ) { - tsParse.pop(); + tsNonTerminal.pop(); shift( Token( Token::tComputedValue ) ); } else @@ -357,6 +373,8 @@ void Parser::reduce() void Parser::output( const Token &t ) { + if( t.eType == Token::tComputedValue ) + return; pCurExp->append( t ); } @@ -417,9 +435,16 @@ int Parser::getPriority( Token::Type eType ) void Parser::printState( const Bu::String &sTag ) { +#ifdef DEBUG_MODE Bu::sio << "----------------" << Bu::sio.nl; - Bu::sio << sTag << " stack:"; - for( TokenStack::iterator i = tsParse.begin(); i; i++ ) + Bu::sio << sTag << " non-terminals:"; + for( TokenStack::iterator i = tsNonTerminal.begin(); i; i++ ) + { + Bu::sio << " " << (*i); + } + Bu::sio << Bu::sio.nl; + Bu::sio << sTag << " terminal:"; + for( TokenStack::iterator i = tsTerminal.begin(); i; i++ ) { Bu::sio << " " << (*i); } @@ -431,5 +456,6 @@ void Parser::printState( const Bu::String &sTag ) } Bu::sio << Bu::sio.nl; Bu::sio << "----------------" << Bu::sio.nl; +#endif } 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: private: Lexer &lex; typedef Bu::List TokenStack; - TokenStack tsParse; + TokenStack tsTerminal; + TokenStack tsNonTerminal; Expression *pCurExp; }; 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 ) case Token::tPlus: { - Number a = sNums.peekPop(); Number b = sNums.peekPop(); + Number a = sNums.peekPop(); sNums.push( a + b ); } break; case Token::tMinus: { - Number a = sNums.peekPop(); Number b = sNums.peekPop(); + Number a = sNums.peekPop(); sNums.push( a - b ); } break; case Token::tDivide: { - Number a = sNums.peekPop(); Number b = sNums.peekPop(); + Number a = sNums.peekPop(); sNums.push( a / b ); } break; case Token::tMultiply: { - Number a = sNums.peekPop(); Number b = sNums.peekPop(); + Number a = sNums.peekPop(); sNums.push( a * b ); } break; -- cgit v1.2.3