]> gitweb.hamatoma.de Git - reqt/commitdiff
day's work
authorhama <hama@siduction.net>
Tue, 8 Jul 2014 22:50:47 +0000 (00:50 +0200)
committerhama <hama@siduction.net>
Tue, 8 Jul 2014 22:50:47 +0000 (00:50 +0200)
rplexpr/rplasclasses.cpp
rplexpr/rplasclasses.hpp
rplexpr/rplastree.cpp
rplexpr/rplastree.hpp
rplexpr/rpllexer.cpp
rplexpr/rpllexer.hpp
rplexpr/rplmfparser.cpp
rplexpr/rplmfparser.hpp
unittests/rplmfparser_test.cpp

index 72f2a60a421a0e73fcb7890ebf94ddd4e3955998..47fd2a4f086b002e00ebfeb291d2188713e3179f 100644 (file)
@@ -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<ListOfVariants*>(object);
+    delete static_cast<RplASListOfVariants*>(object);
 }
 
 /**
@@ -528,7 +528,7 @@ bool RplASList::boolValueOf(void* object) const
 {
     bool rc = false;
     if (object != NULL){
-        ListOfVariants* list = static_cast<ListOfVariants*>(object);
+        RplASListOfVariants* list = static_cast<RplASListOfVariants*>(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<ListOfVariants*>(object);
-    ListOfVariants::iterator it;
+    RplASListOfVariants* list = reinterpret_cast<RplASListOfVariants*>(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<MapValueType*>(source);
+        RplASMapValueType* source2 =
+                static_cast<RplASMapValueType*>(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<MapValueType*>(object);
+        RplASMapValueType* map = reinterpret_cast<RplASMapValueType*>(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<MapValueType*>(object);
-    MapValueType::iterator it;
+    RplASMapValueType* map = reinterpret_cast<RplASMapValueType*>(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();
 }
 
 /**
index 1eca8440653f66ee220d3a1a840ccdc50e19b19d..d1f7d9756561fba600f9d3d3fc7eb9b8d874eeb0 100644 (file)
@@ -112,8 +112,6 @@ public:
 };
 
 class RplASList : public RplASClass {
-public:
-    typedef QList<RplASVariant*> ListOfVariants;
 public:
     RplASList();
 public:
@@ -126,8 +124,6 @@ public:
 };
 
 class RplASMap : public RplASClass {
-public:
-    typedef QMap<QString, RplASVariant*> MapValueType;
 public:
     RplASMap();
 public:
index 3faf3055268976da1e0821801e1db35667380b1b..fd74edb9fb86f8f134c41553bd74a49d7a8452ec 100644 (file)
@@ -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<RplASListOfVariants*>
+             (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());
 }
index 68a61836766ed9262060f45fa32bd518c4912382..64537afe299a2a969c2d1c620cf51538542edc66 100644 (file)
@@ -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<RplASVariant*> RplASListOfVariants;
+typedef QMap<QString, RplASVariant*> 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;
 };
index 03bf08841a9dbeacf0affe27d42336c8383bf30b..ef5c7c93a87323f6617635af43d922a6800dcd54 100644 (file)
@@ -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 <code>nextToken()</code>.
+ *
+ * Makes that <code>nextToken()</code> 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 <code>nextToken()</code>.
+ *
+ * Makes that <code>nextToken()</code> 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:
+ * <pre><code>
+ * token1 = nextToken();
+ * saveLastToken();
+ * token2 = nextToken();
+ * </code></pre>
+ * Then <code>token1</code> and <code>token2</code> contains the wanted content.
+ */
+void RplLexer::saveLastToken()
+{
+    m_currentToken = m_currentToken == &m_token1 ? &m_token2 : &m_token1;
 }
 
 /**
index 89d6cbf0570c276770d38119c2dd6c1f2ea38192..4c385f52e852d7d9aae4430e9d31e6f51fc68f33 100644 (file)
@@ -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;
index 9138ef5369572c0855c246e7f4dd5bae7c53deed..1ac53f93310a65a18b19d2b4076df80db3a099bd 100644 (file)
@@ -231,10 +231,96 @@ RplASItem* RplMFParser::parseVarDefinition(Keyword attribute)
     return rc;
 }
 
+/**
+ * @brief Parses a list.
+ *
+ * Syntax:<br>
+ * '[' [<expr_1> [ ',' <expr_2> ...]] ']'
+ *
+ * @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:<br>
+ * '{' [ <string_expr1> ':' <expr_1> [ ',' <string_expr1> ': <expr_2> ...]] '}'
+ *
+ * @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)){
index 50f0818efa0dd5d134141bff68e5e85e4e8fed53..49429aac57f2cd04cae959d0dd8ac5c74add80d9 100644 (file)
@@ -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);
index 5472042e37592d1072f22c0681871c18d4008003..f2ad3b77fe86c5e0b488542b1993adbfe40feca0 100644 (file)
@@ -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();