From: hama Date: Tue, 8 Jul 2014 22:50:47 +0000 (+0200) Subject: day's work X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=bef022fe5dd04c8d0abbe87713d1fb8febcdd06d;p=reqt day's work --- diff --git a/rplexpr/rplasclasses.cpp b/rplexpr/rplasclasses.cpp index 72f2a60..47fd2a4 100644 --- a/rplexpr/rplasclasses.cpp +++ b/rplexpr/rplasclasses.cpp @@ -490,11 +490,11 @@ RplASList::RplASList() : */ void* RplASList::newValueInstance(void* source) const { - ListOfVariants* rc = new ListOfVariants(); + RplASListOfVariants* rc = new RplASListOfVariants(); if (source != NULL){ - ListOfVariants* source2 = (ListOfVariants*) source; + RplASListOfVariants* source2 = (RplASListOfVariants*) source; rc->reserve(source2->size()); - ListOfVariants::iterator it; + RplASListOfVariants::iterator it; for (it = source2->begin(); it != source2->end(); it++){ @@ -514,7 +514,7 @@ void* RplASList::newValueInstance(void* source) const */ void RplASList::destroyValueInstance(void* object) const { - delete static_cast(object); + delete static_cast(object); } /** @@ -528,7 +528,7 @@ bool RplASList::boolValueOf(void* object) const { bool rc = false; if (object != NULL){ - ListOfVariants* list = static_cast(object); + RplASListOfVariants* list = static_cast(object); if (list == NULL) throw RplException("RplASList.boolValueOf(): not a list"); rc = ! list->empty(); @@ -547,8 +547,8 @@ QString RplASList::toString(void* object, int maxLength) const QString rc; rc.reserve(maxLength); rc += "["; - ListOfVariants* list = reinterpret_cast(object); - ListOfVariants::iterator it; + RplASListOfVariants* list = reinterpret_cast(object); + RplASListOfVariants::iterator it; bool first = true; for(it = list->begin(); it != list->end(); it++){ if (first) @@ -590,12 +590,12 @@ RplASMap::RplASMap() : */ void* RplASMap::newValueInstance(void* source) const { - MapValueType* rc = new MapValueType(); + RplASMapValueType* rc = new RplASMapValueType(); if (source != NULL){ - MapValueType* source2 = - static_cast(source); + RplASMapValueType* source2 = + static_cast(source); // rc->reserve(source2->size()); - MapValueType::iterator it; + RplASMapValueType::iterator it; for (it = source2->begin(); it != source2->end(); it++){ // deleting in destroyValue(): const QString& key = it.key(); @@ -615,7 +615,7 @@ void* RplASMap::newValueInstance(void* source) const */ void RplASMap::destroyValueInstance(void* object) const { - delete (MapValueType*) object; + delete (RplASMapValueType*) object; } /** @@ -628,7 +628,7 @@ bool RplASMap::boolValueOf(void* object) const { bool rc = false; if (object != NULL){ - MapValueType* map = reinterpret_cast(object); + RplASMapValueType* map = reinterpret_cast(object); if (map == NULL) throw RplException("RplASMap.boolValueOf(): not a map"); rc = map->empty() > 0; @@ -647,8 +647,8 @@ QString RplASMap::toString(void* object, int maxLength) const QString rc; rc.reserve(maxLength); rc += "["; - MapValueType* map = reinterpret_cast(object); - MapValueType::iterator it; + RplASMapValueType* map = reinterpret_cast(object); + RplASMapValueType::iterator it; bool first = true; for(it = map->begin(); it != map->end(); it++){ if (first) @@ -785,12 +785,13 @@ RplASFormula::RplASFormula() : * * In this case we do nothing. * - * @param source ignored + * @param formula ignored * @return */ -void*RplASFormula::newValueInstance(void*) const +void*RplASFormula::newValueInstance(void* expr) const { - return NULL; + RplASExprStatement* rc = new RplASFormula(); + rc->setChild(); } /** diff --git a/rplexpr/rplasclasses.hpp b/rplexpr/rplasclasses.hpp index 1eca844..d1f7d97 100644 --- a/rplexpr/rplasclasses.hpp +++ b/rplexpr/rplasclasses.hpp @@ -112,8 +112,6 @@ public: }; class RplASList : public RplASClass { -public: - typedef QList ListOfVariants; public: RplASList(); public: @@ -126,8 +124,6 @@ public: }; class RplASMap : public RplASClass { -public: - typedef QMap MapValueType; public: RplASMap(); public: diff --git a/rplexpr/rplastree.cpp b/rplexpr/rplastree.cpp index 3faf305..fd74edb 100644 --- a/rplexpr/rplastree.cpp +++ b/rplexpr/rplastree.cpp @@ -181,7 +181,7 @@ RplASVariant::VariantType RplASVariant::variantType() const * * @return the variant type */ -RplASClass* RplASVariant::getClass() const +const RplASClass* RplASVariant::getClass() const { return m_class; } @@ -527,6 +527,18 @@ RplASListConstant::RplASListConstant() : RplASNode1(AST_LIST_CONSTANT), RplASCalculable() { + m_value.setObject(RplASList::m_instance.newValueInstance(), + &RplASList::m_instance); +} +/** + * @brief Returns the list. + * + * @return the list + */ +RplASListOfVariants* RplASListConstant::list(){ + RplASListOfVariants* rc = static_cast + (m_value.asObject(NULL)); + return rc; } /** @@ -552,8 +564,6 @@ void RplASListConstant::dump(FILE* fp, int indent) fprintf(fp, "%slistConst id: %d %s\n", tabs, m_id, positionStr(buffer, sizeof buffer)); - RplASList::ListOfVariants* list = (RplASList::ListOfVariants*) - m_value.asObject(); QString sValue = m_value.toString(8092); fprintf(fp, "%s\t%s\n", tabs, sValue.toUtf8().constData()); } diff --git a/rplexpr/rplastree.hpp b/rplexpr/rplastree.hpp index 68a6183..64537af 100644 --- a/rplexpr/rplastree.hpp +++ b/rplexpr/rplastree.hpp @@ -87,7 +87,7 @@ public: void setString(const QString& string); QString toString(int maxLength = 80) const; VariantType variantType() const; - RplASClass* getClass() const; + const RplASClass* getClass() const; protected: void copyValue(const RplASVariant& source); void destroyValue(); @@ -231,6 +231,8 @@ public: protected: RplASItem* m_child5; }; +typedef QList RplASListOfVariants; +typedef QMap RplASMapValueType; class RplASListConstant : public RplASNode1, public RplASCalculable { @@ -241,6 +243,7 @@ public: public: virtual void dump(FILE* fp, int indent); RplASVariant& value(); + RplASListOfVariants* list(); private: RplASVariant m_value; }; diff --git a/rplexpr/rpllexer.cpp b/rplexpr/rpllexer.cpp index 03bf088..ef5c7c9 100644 --- a/rplexpr/rpllexer.cpp +++ b/rplexpr/rpllexer.cpp @@ -354,9 +354,12 @@ RplLexer::RplLexer(RplSource* source, m_idRest2(), m_currentToken(&m_token1), m_waitingToken(NULL), + m_waitingToken2(NULL), m_token1(TOKEN_UNDEF), m_token2(TOKEN_UNDEF), m_currentPosition(NULL), + m_waitingPosition1(NULL), + m_waitingPosition2(NULL), m_maxTokenLength(64), m_input(), m_currentCol(0), @@ -855,17 +858,24 @@ RplToken* RplLexer::nextToken() int ix; if (m_waitingToken != NULL){ rc = m_currentToken = m_waitingToken; - m_waitingToken = NULL; + m_waitingToken = m_waitingToken2; + m_waitingToken2 = NULL; + m_currentPosition = m_waitingPosition1; + m_waitingPosition1 = m_waitingPosition2; + m_waitingPosition2 = NULL; } else { m_currentToken->clear(); RplReader* reader = m_source->currentReader(); if (reader == NULL) m_currentToken->m_tokenType = TOKEN_END_OF_SOURCE; else { - if (waitingPosition == NULL) + if (waitingPosition == NULL){ + m_waitingPosition2 = m_currentPosition; m_currentPosition = m_source->newPosition(m_currentCol); - else { - m_currentPosition = waitingPosition; + } else { + m_currentPosition = m_waitingPosition1; + m_waitingPosition1 = m_waitingPosition2; + m_waitingPosition2 = NULL; ((RplSourcePosition*)waitingPosition)->setSourceUnit( m_source->currentReader()->currentSourceUnit()); ((RplSourcePosition*)waitingPosition)->setColumn(m_currentCol); @@ -955,12 +965,44 @@ RplToken* RplLexer::nextToken() return rc; } /** - * @brief Makes that nextToken() returns the current token again. + * @brief Reverses the last nextToken(). + * + * Makes that nextToken() returns the current token again. */ void RplLexer::undoLastToken() { m_waitingToken = m_currentToken; m_currentToken = m_currentToken == &m_token1 ? &m_token2 : &m_token1; + m_waitingPosition1 = m_currentPosition; +} + +/** + * @brief Reverses the last nextToken(). + * + * Makes that nextToken() returns the current token again. + */ +void RplLexer::undoLastToken2() +{ + m_waitingToken = m_currentToken; + m_waitingToken2 = m_currentToken == &m_token1 ? &m_token2 : &m_token1; + m_waitingPosition2 = m_waitingPosition1; + m_waitingPosition1 = m_currentPosition; +} + +/** + * @brief Prevents the current token from data loss. + * + * Usage: + *

+ * token1 = nextToken();
+ * saveLastToken();
+ * token2 = nextToken();
+ * 
+ * Then token1 and token2 contains the wanted content. + */ +void RplLexer::saveLastToken() +{ + m_currentToken = m_currentToken == &m_token1 ? &m_token2 : &m_token1; } /** diff --git a/rplexpr/rpllexer.hpp b/rplexpr/rpllexer.hpp index 89d6cbf..4c385f5 100644 --- a/rplexpr/rpllexer.hpp +++ b/rplexpr/rpllexer.hpp @@ -170,6 +170,8 @@ public: public: RplToken* nextToken(); void undoLastToken(); + void undoLastToken2(); + void saveLastToken(); RplToken* peekNonSpaceToken(); RplToken* nextNonSpaceToken(); size_t maxTokenLength() const; @@ -214,9 +216,12 @@ protected: QString m_idRest2; RplToken* m_currentToken; RplToken* m_waitingToken; + RplToken* m_waitingToken2; RplToken m_token1; RplToken m_token2; const RplSourcePosition* m_currentPosition; + const RplSourcePosition* m_waitingPosition1; + const RplSourcePosition* m_waitingPosition2; int m_maxTokenLength; QString m_input; int m_currentCol; diff --git a/rplexpr/rplmfparser.cpp b/rplexpr/rplmfparser.cpp index 9138ef5..1ac53f9 100644 --- a/rplexpr/rplmfparser.cpp +++ b/rplexpr/rplmfparser.cpp @@ -231,10 +231,96 @@ RplASItem* RplMFParser::parseVarDefinition(Keyword attribute) return rc; } +/** + * @brief Parses a list. + * + * Syntax:
+ * '[' [ [ ',' ...]] ']' + * + * @precondition '[' is the current token + * @postcondition the token behind the ']' is read + * @return a node of the abstract syntax tree + */ +RplASItem* RplMFParser::parseList() +{ + RplASListConstant* rc = new RplASListConstant(); + rc->setPosition(m_lexer.currentPosition()); + + bool again = true; + RplToken* token; + RplToken* token2; + while(again){ + token = m_lexer.nextNonSpaceToken(); + if (token->isOperator(O_LBRACKET)) + again = false; + else{ + m_lexer.saveLastToken(); + RplASVariant* variant = NULL; + token2 = m_lexer.nextNonSpaceToken(); + if (token2->isOperator(O_COMMA)){ + switch(token->tokenType()){ + case TOKEN_NUMBER: + variant = new RplASVariant(); + variant->setInt(token->asInteger()); + break; + case TOKEN_STRING: + variant = new RplASVariant(); + variant->setString(token->toString()); + break; + case TOKEN_REAL: + variant = new RplASVariant(); + variant->setFloat(token->asReal()); + break; + case TOKEN_KEYWORD: + switch(token->id()){ + case K_TRUE: + case K_FALSE: + variant = new RplASVariant(); + variant->setBool(token->id() == K_TRUE); + break; + case K_NONE: + variant = new RplASVariant(); + break; + default: + break; + } + break; + default: + break; + } + } + if (variant == NULL){ + m_lexer.undoLastToken2(); + RplASExprStatement* expr = parseExprStatement(); + expr->successor(rc->child()); + rc->setChild(expr); + variant = RplASFormula::m_instance.newValueInstance(expr); + } + } + } + return rc; +} + +/** + * @brief Parses a map. + * + * Syntax:
+ * '{' [ ':' [ ',' ': ...]] '}' + * + * @precondition '{' is the current token + * @postcondition the token behind the '}' is read + * @return a node of the abstract syntax tree + */ +RplASItem* RplMFParser::parseMap() +{ + return NULL; +} + /** * @brief Parses an operand. - * An operand is the first and the third part of an binary operation. - * Examples: constant, variable, method call + * + * An operand is the first and the third part of a binary operation. + * Examples: constant, variable, method call, an expression in parentheses * * @return the node with the operand */ @@ -247,7 +333,11 @@ RplASItem* RplMFParser::parseOperand(int level) case TOKEN_OPERATOR: { Operator opId = (Operator) token->id(); - if (opId == O_LPARENTH){ + if (opId == O_LBRACKET){ + rc = parseList(); + } else if (opId == O_LBRACE){ + rc = parseMap(); + } else if (opId == O_LPARENTH){ rc = parseExpr(level + 1); token = m_lexer.currentToken(); if(! token->isOperator(O_RPARENT)){ diff --git a/rplexpr/rplmfparser.hpp b/rplexpr/rplmfparser.hpp index 50f0818..49429aa 100644 --- a/rplexpr/rplmfparser.hpp +++ b/rplexpr/rplmfparser.hpp @@ -80,6 +80,8 @@ public: RplASItem* parseModule(const QString& name); void parse(); RplASItem*parseExprStatement(); + RplASItem*parseList(); + RplASItem*parseMap(); protected: RplASArgument* parseArguments(); RplASItem* parseOperand(int level); diff --git a/unittests/rplmfparser_test.cpp b/unittests/rplmfparser_test.cpp index 5472042..f2ad3b7 100644 --- a/unittests/rplmfparser_test.cpp +++ b/unittests/rplmfparser_test.cpp @@ -113,8 +113,15 @@ public: parser.parse(); checkAST("forIt1.txt", __LINE__); } + void listTest(){ + setSource("List a = [2, 3.14, 1+9, 'hi', a]; List b = [];"); + RplMFParser parser(m_source, m_tree); + parser.parse(); + checkAST("forIt1.txt", __LINE__); + } virtual void doIt(void) { + listTest(); forCTest(); forItTest(); opTest();