Commits

Tommaso Urli  committed ac10dd3

First working parser.

  • Participants
  • Parent commits 54f7585

Comments (0)

Files changed (6)

 	
 all: json test
 	
-json: json.tab.c lex.yy.c json.hh
-	g++ -std=c++11 -lfl json.tab.c json.tab.h lex.yy.c -o json  
+json: json.tab.c lex.yy.c json.hh json.cc
+	g++ -std=c++11 json.cc json.tab.c lex.yy.c -o json  
 	
 json.tab.c: json.y
 	bison -d json.y
 
 using namespace std;
 
+Value::Value() {}
+
+Value::Value(const int& i) : int_v(i), type_t(INT) { }
+
+Value::Value(const float& f) : float_v(f), type_t(FLOAT) { }
+
+Value::Value(const bool& b) : bool_v(b), type_t(BOOL) { }
+
+Value::Value(const std::string& s) : string_v(s), type_t(STRING) { }
+
+Value::Value(const char* s) : string_v(s), type_t(STRING) { }
+
+Value::Value(const Object& o) : object_v(o), type_t(OBJECT) { }
+
+Value::Value(const Array& o) : array_v(o), type_t(ARRAY) { }
+
+Object::Object() { }
+
+Object::Object(const Object& o) : _object(o._object) { }
+
+Object& Object::operator=(const Object& o)
+{
+    _object = o._object;
+}
+
+Value& Object::operator[] (const std::string& key)
+{
+    return _object[key];
+}
+
+std::pair<std::map<std::string, Value>::iterator, bool> Object::insert(const std::pair<std::string, Value>& v)
+{
+    return _object.insert(v);
+}
+
+std::map<std::string, Value>::const_iterator Object::begin() const
+{
+    return _object.begin();
+}
+
+std::map<std::string, Value>::const_iterator Object::end() const
+{
+    return _object.end();
+}
+
+size_t Object::size() const
+{
+    return _object.size();
+}
+
+Array::Array() { }
+
+Array::Array(const Array& o)
+{
+    _array = o._array;
+}
+
+Value& Array::operator[] (const int i)
+{
+    return _array[i];
+}
+
+std::vector<Value>::const_iterator Array::begin() const
+{
+    return _array.begin();
+}
+
+std::vector<Value>::const_iterator Array::end() const
+{
+    return _array.end();
+}
+
+size_t Array::size() const
+{
+    return _array.size();
+}
+
+void Array::push_back(const Value& v)
+{
+    _array.push_back(v);
+}
+
+Value& Value::operator=(const Value& e)
+{
+    
+    type_t = e.type();
+    
+    switch (type_t)
+    {
+        case INT:
+        int_v = e.int_v;
+        break;
+
+        case FLOAT:
+        float_v = e.float_v;
+        break;
+
+        case BOOL:
+        bool_v = e.bool_v;
+        break;
+
+        case STRING:
+        string_v = e.string_v;
+        break;
+
+        case OBJECT:
+        object_v = e.object_v;
+        break;
+
+        case ARRAY:
+        array_v = e.array_v;
+        break;                
+    }
+
+    return *this;
+}
+
+
 void indent(ostream& os)
 {
     for (unsigned int i  = 0; i < ind; i++)
     return os;
 }
 
-std::ostream& operator<<(ostream& os, const map<string, Value>& o)
+std::ostream& operator<<(ostream& os, const Object& o)
 {    
     os << "{" << endl;
     ind++;
     os << "}";
 }
 
-std::ostream& operator<<(ostream& os, const vector<Value>& a)
+std::ostream& operator<<(ostream& os, const Array& a)
 {
     os << "[" << endl;
     ind++;
 #include <vector>
 #include <iostream>
 #include <map>
+#include <stack>
 
 
-    enum ValueType
+enum ValueType
+{
+    INT,
+    FLOAT,
+    BOOL,
+    STRING,
+    OBJECT,
+    ARRAY
+};
+
+class Value;
+
+class Object
+{
+public:
+
+    Object();
+    
+    Object(const Object& o);
+    
+    Object& operator=(const Object& o);
+
+    Value& operator[] (const std::string& key);
+
+    std::map<std::string, Value>::const_iterator begin() const;
+
+    std::map<std::string, Value>::const_iterator end() const;
+    
+    std::pair<std::map<std::string, Value>::iterator, bool> insert(const std::pair<std::string, Value>& v);
+
+    size_t size() const;
+
+protected:
+
+    std::map<std::string, Value> _object;
+};
+
+class Array
+{
+public:
+
+    Array();
+    
+    Array(const Array& o);
+    
+    Array& operator=(const Object& o);
+
+    Value& operator[] (const int i);
+
+    std::vector<Value>::const_iterator begin() const;
+
+    std::vector<Value>::const_iterator end() const;
+
+    void push_back(const Value& n);
+
+    size_t size() const;
+
+protected:
+
+    std::vector<Value> _array;
+
+};
+
+class Value
+{
+public:
+    
+    Value();
+    
+    Value(const int& i);
+    
+    Value(const float& f);
+    
+    Value(const bool& b);
+    
+    Value(const std::string& s);
+    
+    Value(const char* s);
+    
+    Value(const Object& o);
+    
+    Value(const Array& o);
+
+    Value& operator=(const Value& e);
+    
+    ValueType type() const
     {
-        INT,
-        FLOAT,
-        BOOL,
-        STRING,
-        OBJECT,
-        ARRAY
-    };
+        return type_t;
+    }
+            
+    float           float_v;
+    int             int_v;
+    bool            bool_v;
+    std::string     string_v;
+    Object          object_v;
+    Array           array_v;
+    ValueType       type_t;
+};
     
-    class Value;
-            
-    class Value
-    {
-    public:
-        
-        Value() {}
-        
-        Value(const int& i) : int_v(i), type_t(INT) { }
-        
-        Value(const float& f) : float_v(f), type_t(FLOAT) { }
-        
-        Value(const bool& b) : bool_v(b), type_t(BOOL) { }
-        
-        Value(const std::string& s) : string_v(s), type_t(STRING) { }
-        
-        Value(const char* s) : string_v(s), type_t(STRING) { }
-        
-        Value(const std::map<std::string, Value>& o) : object_v(o), type_t(OBJECT) { }
-        
-        Value(const std::vector<Value>& o) : array_v(o), type_t(ARRAY) { }
-
-        Value& operator=(const Value& e)
-        {
-            
-            type_t = e.type();
-            
-            switch (type_t)
-            {
-                case INT:
-                int_v = e.int_v;
-                break;
-
-                case FLOAT:
-                float_v = e.float_v;
-                break;
-
-                case BOOL:
-                bool_v = e.bool_v;
-                break;
-
-                case STRING:
-                string_v = e.string_v;
-                break;
-
-                case OBJECT:
-                object_v = e.object_v;
-                break;
-
-                case ARRAY:
-                array_v = e.array_v;
-                break;                
-            }
-        
-            return *this;
-        }
-        
-        
-        ValueType type() const
-        {
-            return type_t;
-        }
-                
-        float float_v;
-        int int_v;
-        bool bool_v;
-        std::string string_v;
-        std::map<std::string, Value> object_v;
-        std::vector<Value> array_v;
-        ValueType type_t;
-    };
-
-
 std::ostream& operator<<(std::ostream&, const Value&);
 
-std::ostream& operator<<(std::ostream&, const std::map<std::string, Value>&);
+std::ostream& operator<<(std::ostream&, const Object&);
 
-std::ostream& operator<<(std::ostream&, const std::vector<Value>&);
+std::ostream& operator<<(std::ostream&, const Array&);
 
 static unsigned int ind;
 
+static unsigned int count;
+
+static std::stack<Value> list_s;
+
+static std::stack<std::pair<std::string, Value> > assign_list_s;
+
 static void indent(std::ostream& os = std::cout);
 
 #endif
 
 %%
 
-\"[^\"]*?\"             { yylval.string_v = yytext; return DOUBLE_QUOTED_STRING; }
-\'[^\']*?\'             { yylval.string_v = yytext; return SINGLE_QUOTED_STRING; }
+\"[^\"]*\"              { yylval.string_v = yytext; return DOUBLE_QUOTED_STRING; }
+\'[^\']*\'              { yylval.string_v = yytext; return SINGLE_QUOTED_STRING; }
 "["                     { return SQUARE_BRACKET_L; }
 "]"                     { return SQUARE_BRACKET_R; }
 "{"                     { return CURLY_BRACKET_L; }
 [-+]?[0-9]+             { yylval.int_v = atoi(yytext); return NUMBER_I; }
 [-+]?[0-9]*\.?[0-9]*    { yylval.float_v = atof(yytext); return NUMBER_F; }
 true|false              { yylval.bool_v = (std::string(yytext) == "true" ? true : false); return BOOLEAN; }
-.                       { printf("Unrecognized: ", yytext); }
+.                       {  }
 %%
         int yylex();
     } 
     
-    #include "json.hh"    
+    #include "json.hh"
 %}
 
+%code requires { #include "json.hh" }
+
 %union
 {
     int int_v;
     float float_v;
     char* string_v;
     bool bool_v;
-    std::map<std::string, Value>* object_p;
+    Object* object_p;
+    Array* array_p;
     Value* value_p;
 } 
 
 
 /** Define types for union values */
-%type<string_v> key string DOUBLE_QUOTED_STRING SINGLE_QUOTED_STRING
+%type<string_v> DOUBLE_QUOTED_STRING SINGLE_QUOTED_STRING string
 %type<int_v> NUMBER_I
 %type<float_v> NUMBER_F
 %type<bool_v> BOOLEAN
 %token BOOLEAN
 
 %type <object_p> object assignment_list
+%type <array_p> array list
 %type <value_p> value
-    
 
 %%
 
-/** Grammar for objects:
-    
-    {}
-    { "foo": 1 }
-    { "foo": 1, "bar": "k" }
-*/
-
-object: CURLY_BRACKET_L CURLY_BRACKET_R { $$ = new Object(); }
-    | CURLY_BRACKET_L assignment_list CURLY_BRACKET_R { $$ = $2; }
-    ;
-
-value : NUMBER_I { $$ = new Value($1); }
-    | NUMBER_F { $$ = new Value($1); }
-    | BOOLEAN { $$ = new Value($1); }
-    | string { $$ = new Value($1); }
-    | object { $$ = new Value($1); }
-    ;
-
-string : DOUBLE_QUOTED_STRING { $$ = $1; }
-    | SINGLE_QUOTED_STRING { $$ = $1; }
-    ;
-
-key: string 
+value : NUMBER_I 
+    { 
+        $$ = new Value($1); 
+    }
+    | NUMBER_F 
+    { 
+        $$ = new Value($1); 
+    }
+    | BOOLEAN 
+    { 
+        $$ = new Value($1); 
+    }
+    | string 
+    { 
+        $$ = new Value($1);     
+    }
+    | object 
+    { 
+        $$ = new Value(*$1); 
+    }
+    | array 
+    { 
+        $$ = new Value(*$1); 
+    }
     ;
     
-assignment_list: 
-    key COLON value 
+string : DOUBLE_QUOTED_STRING 
+    {
+        std::string s($1);
+        $$ = const_cast<char*>(s.substr(1, s.length()-2).c_str());
+    } 
+    | SINGLE_QUOTED_STRING
+    {
+        std::string s($1);
+        $$ = const_cast<char*>(s.substr(1, s.length()-2).c_str());
+    };
+
+assignment_list:
     {
         $$ = new Object();
-        $$->insert( std::make_pair($1, Value($3) ));
     }
-    | key COLON value COMMA assignment_list 
+    |   string COLON value
     {
-        $$ = $5;
-        $$->insert( std::make_pair($1, Value($3) ));
+        $$ = new Object();
+        $$->insert(std::make_pair($1, *$3));
+    } 
+    | assignment_list COMMA string COLON value 
+    {
+        $$->insert(std::make_pair($3, *$5));
     }
     ;
 
+list:  
+    {
+        $$ = new Array();
+    }
+    | value
+    {
+        $$ = new Array();
+        $$->push_back(*$1);
+    }
+    | list COMMA value
+    {
+        $$->push_back(*$3);   
+    }
+    ;
+    
+object: CURLY_BRACKET_L assignment_list CURLY_BRACKET_R 
+    { 
+        $$ = $2;
+    }
+    ;
+
+array : SQUARE_BRACKET_L list SQUARE_BRACKET_R
+    {
+        $$ = $2;
+    }
+    ;
 
 %%
 
 int main(int argc, char **argv)
 {
-    yyparse();
+    int t = yyparse();
+    std::cerr << t << std::endl;
 }
 
 void yyerror(const char *s)
 
 int main(int argc, char** argv)
 {
-    map<string, Value> obj;
+    Object obj;
     
     obj["foo"] = true;
     obj["bar"] = 1;
     
-    map<string, Value> o;
+    Object o;
     o["failure"] = true;
     o["success"] = "no way";
     
     obj["baz"] = o;
         
-    vector<Value> a;
+    Array a;
     a.push_back(Value(true));
     a.push_back(Value("iajsia"));
     a.push_back(Value("asas"));