From af7b502a6eb46e0df2d9de5cd31fff50ea77fed3 Mon Sep 17 00:00:00 2001 From: hama Date: Sat, 12 Jul 2014 01:44:31 +0200 Subject: [PATCH] day's work --- rplexpr/rplasclasses.cpp | 10 ++- rplexpr/rpllexer.cpp | 22 ++---- rplexpr/rplmfparser.cpp | 118 ++++++++++++++++++--------------- test/rplmfparser/list1.txt | 8 +++ test/rplmfparser/list2.txt | 11 +++ unittests/rplmfparser_test.cpp | 7 +- 6 files changed, 102 insertions(+), 74 deletions(-) create mode 100644 test/rplmfparser/list1.txt create mode 100644 test/rplmfparser/list2.txt diff --git a/rplexpr/rplasclasses.cpp b/rplexpr/rplasclasses.cpp index 9362ce5..e780bd0 100644 --- a/rplexpr/rplasclasses.cpp +++ b/rplexpr/rplasclasses.cpp @@ -788,7 +788,7 @@ RplASFormula::RplASFormula() : * @param formula ignored * @return */ -void*RplASFormula::newValueInstance(void* expr) const +void* RplASFormula::newValueInstance(void* expr) const { return expr; } @@ -821,7 +821,11 @@ bool RplASFormula::boolValueOf(void*) const * @param maxLength ignored * @return the empty string */ -QString RplASFormula::toString(void*, int) const +QString RplASFormula::toString(void* object, int) const { - return QString(""); + RplASExprStatement* expr = static_cast(object); + + QString rc; + rc.sprintf("", expr->id()); + return rc; } diff --git a/rplexpr/rpllexer.cpp b/rplexpr/rpllexer.cpp index ef5c7c9..414e394 100644 --- a/rplexpr/rpllexer.cpp +++ b/rplexpr/rpllexer.cpp @@ -869,18 +869,9 @@ RplToken* RplLexer::nextToken() if (reader == NULL) m_currentToken->m_tokenType = TOKEN_END_OF_SOURCE; else { - if (waitingPosition == NULL){ - m_waitingPosition2 = m_currentPosition; - m_currentPosition = m_source->newPosition(m_currentCol); - } else { - m_currentPosition = m_waitingPosition1; - m_waitingPosition1 = m_waitingPosition2; - m_waitingPosition2 = NULL; - ((RplSourcePosition*)waitingPosition)->setSourceUnit( - m_source->currentReader()->currentSourceUnit()); - ((RplSourcePosition*)waitingPosition)->setColumn(m_currentCol); - waitingPosition = NULL; - } + m_waitingPosition2 = m_waitingPosition1; + m_waitingPosition1 = m_currentPosition; + m_currentPosition = m_source->newPosition(m_currentCol); if (! fillInput()){ m_currentToken->m_tokenType = TOKEN_END_OF_SOURCE; } else { @@ -983,8 +974,8 @@ void RplLexer::undoLastToken() */ void RplLexer::undoLastToken2() { - m_waitingToken = m_currentToken; - m_waitingToken2 = m_currentToken == &m_token1 ? &m_token2 : &m_token1; + m_waitingToken2 = m_currentToken; + m_waitingToken = m_currentToken == &m_token1 ? &m_token2 : &m_token1; m_waitingPosition2 = m_waitingPosition1; m_waitingPosition1 = m_currentPosition; } @@ -1002,7 +993,8 @@ void RplLexer::undoLastToken2() */ void RplLexer::saveLastToken() { - m_currentToken = m_currentToken == &m_token1 ? &m_token2 : &m_token1; + if (m_waitingToken == NULL) + m_currentToken = m_currentToken == &m_token1 ? &m_token2 : &m_token1; } /** diff --git a/rplexpr/rplmfparser.cpp b/rplexpr/rplmfparser.cpp index ca93d7c..202dffa 100644 --- a/rplexpr/rplmfparser.cpp +++ b/rplexpr/rplmfparser.cpp @@ -255,7 +255,7 @@ RplASItem* RplMFParser::parseList() RplToken* token2; while(again){ token = m_lexer.nextNonSpaceToken(); - if (token->isOperator(O_LBRACKET)) + if (token->isOperator(O_RBRACKET)) again = false; else{ variant = NULL; @@ -298,23 +298,26 @@ RplASItem* RplMFParser::parseList() break; } } - if (variant == NULL){ + if (variant == NULL && ! token->isOperator(O_RBRACKET)){ m_lexer.undoLastToken2(); RplASExprStatement* expr = dynamic_cast (parseExprStatement()); + if (expr != NULL){ // chaining per m_successor is for freeing in destruction: expr->setSuccessor(rc->child()); rc->setChild(expr); + // freed in the destructor of varList (~RplASVariant()): + variant = new RplASVariant(); variant->setObject(expr, &RplASFormula::m_instance); token = m_lexer.currentToken(); if (token->isOperator(O_RBRACKET)) again = false; - else if (token->isOperator(O_COMMA)) - m_lexer.undoLastToken(); - else + else if (! token->isOperator(O_COMMA)) syntaxError(L_PARSE_LIST_NO_COMMA, "',' or ']' expected"); + } } - list->append(variant); + if (variant != NULL) + list->append(variant); } } return rc; @@ -437,6 +440,8 @@ RplASItem* RplMFParser::parseOperand(int level) } break; } + case TOKEN_END_OF_SOURCE: + break; default: // this call never comes back (exception!) syntaxError(L_PARSE_OPERAND_WRONG, @@ -466,53 +471,55 @@ RplASItem* RplMFParser::parseOperand(int level) RplASItem* RplMFParser::parseExpr(int depth){ RplToken* token; RplASItem* top = parseOperand(depth); - int lastPrio = INT_MAX; - bool again = true; - do { - token = m_lexer.nextNonSpaceToken(); - RplTokenType tokenType = token->tokenType(); - switch(tokenType){ - case TOKEN_OPERATOR: - { - Operator opId = (Operator) token->id(); - if (IS_BINARY_OP(opId)){ - RplASBinaryOp* op = new RplASBinaryOp(); - op->setPosition(m_lexer.currentPosition()); - op->setOperator(opId); + if (top != NULL){ + int lastPrio = INT_MAX; + bool again = true; + do { + token = m_lexer.nextNonSpaceToken(); + RplTokenType tokenType = token->tokenType(); + switch(tokenType){ + case TOKEN_OPERATOR: + { + Operator opId = (Operator) token->id(); + if (IS_BINARY_OP(opId)){ + RplASBinaryOp* op = new RplASBinaryOp(); + op->setPosition(m_lexer.currentPosition()); + op->setOperator(opId); - int prio = m_lexer.prioOfOp(token->id()); - if (prio < lastPrio - || (prio == lastPrio - && ! m_lexer.isRightAssociative(opId))){ - op->setChild(top); - top = op; - } else { - // right assoc or higher priority: - RplASBinaryOp* top2 = dynamic_cast(top); - op->setChild(top2->child2()); - top2->setChild2(op); - } - lastPrio = prio; - op->setChild2(parseOperand(depth)); - } else + int prio = m_lexer.prioOfOp(token->id()); + if (prio < lastPrio + || (prio == lastPrio + && ! m_lexer.isRightAssociative(opId))){ + op->setChild(top); + top = op; + } else { + // right assoc or higher priority: + RplASBinaryOp* top2 = dynamic_cast(top); + op->setChild(top2->child2()); + top2->setChild2(op); + } + lastPrio = prio; + op->setChild2(parseOperand(depth)); + } else + again = false; + break; + } + case TOKEN_STRING: + syntaxError(L_TERM_WRONG_STRING, "Operator expected, not a string"); + break; + case TOKEN_NUMBER: + case TOKEN_REAL: + syntaxError(L_TERM_WRONG_NUMBER, "Operator expected, not a number"); + break; + case TOKEN_KEYWORD: + case TOKEN_ID: + case TOKEN_END_OF_SOURCE: + default: again = false; - break; - } - case TOKEN_STRING: - syntaxError(L_TERM_WRONG_STRING, "Operator expected, not a string"); - break; - case TOKEN_NUMBER: - case TOKEN_REAL: - syntaxError(L_TERM_WRONG_NUMBER, "Operator expected, not a number"); - break; - case TOKEN_KEYWORD: - case TOKEN_ID: - case TOKEN_END_OF_SOURCE: - default: - again = false; - break; - } - } while(again); + break; + } + } while(again); + } return top; } @@ -528,9 +535,12 @@ RplASItem* RplMFParser::parseExpr(int depth){ RplASItem* RplMFParser::parseExprStatement() { RplASItem* item = parseExpr(0); - RplASExprStatement* statement = new RplASExprStatement(); - statement->setPosition(item->position()); - statement->setChild(item); + RplASExprStatement* statement = NULL; + if (item != NULL){ + statement = new RplASExprStatement(); + statement->setPosition(item->position()); + statement->setChild(item); + } return statement; } diff --git a/test/rplmfparser/list1.txt b/test/rplmfparser/list1.txt new file mode 100644 index 0000000..2b6cc66 --- /dev/null +++ b/test/rplmfparser/list1.txt @@ -0,0 +1,8 @@ +List b = []; += (module) parent: global +== Classes: +== Variables: +== Body: +varDef b (List) id: 1 succ: 0 attr: 0x0 :1:5 + listConst id: 2 :1:9 + [] diff --git a/test/rplmfparser/list2.txt b/test/rplmfparser/list2.txt new file mode 100644 index 0000000..cc1885d --- /dev/null +++ b/test/rplmfparser/list2.txt @@ -0,0 +1,11 @@ +List a = [2+3, 3.14, 7, 'hi', a]; List b = []; += (module) parent: global +== Classes: +== Variables: +== Body: +varDef a (List) id: 1 succ: 9 attr: 0x0 :1:5 + listConst id: 2 :1:9 + [,3.140000,7,'hi',] +varDef b (List) id: 9 succ: 0 attr: 0x0 :1:39 + listConst id: 10 :1:43 + [] diff --git a/unittests/rplmfparser_test.cpp b/unittests/rplmfparser_test.cpp index f2ad3b7..533b369 100644 --- a/unittests/rplmfparser_test.cpp +++ b/unittests/rplmfparser_test.cpp @@ -114,10 +114,13 @@ public: checkAST("forIt1.txt", __LINE__); } void listTest(){ - setSource("List a = [2, 3.14, 1+9, 'hi', a]; List b = [];"); + setSource("List b = [];"); RplMFParser parser(m_source, m_tree); parser.parse(); - checkAST("forIt1.txt", __LINE__); + checkAST("list1.txt", __LINE__); + setSource("List a = [2+3, 3.14, 7, 'hi', a]; List b = [];"); + parser.parse(); + checkAST("list2.txt", __LINE__); } virtual void doIt(void) { -- 2.39.5