Commits

Tommaso Urli committed 60105b3

Now the parser works correctly and can read either from a string or from a file.

  • Participants
  • Parent commits ac10dd3

Comments (0)

Files changed (6)

 all: json test
 	
 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  
+	g++ -lfl -std=c++11 json.cc json.tab.c lex.yy.c -o json  
 	
 json.tab.c: json.y
 	bison -d json.y

File json

Binary file removed.
 
 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) { }
     Value(const bool& b);
     
     Value(const std::string& s);
-    
-    Value(const char* s);
-    
+        
     Value(const Object& o);
     
     Value(const Array& o);
 %option noyywrap yylineno nodefault
 %{
-    #include <iostream>
-
+    // Provided externally
     extern "C" 
     {
         int yylex();
-    } 
+    }
     
+    // Needed for the tokens
     #include "json.tab.h"
-
 %}
 
 %%
 [ \t]                   { }
 [-+]?[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; }
+true|false              { yylval.bool_v = ( strcmp(yytext, "true") == 0 ? true : false); return BOOLEAN; }
 .                       {  }
+
 %%
+
+/** Sets the input string to the lexer */
+void load_string(const char* str)
+{
+    yy_switch_to_buffer(yy_scan_string(str));
+}
+
+/** Sets the input file to the lexer */
+void load_file(FILE* file)
+{
+    yyrestart(file);
+}
 %{
 
     #include <iostream>
+    #include <cstring>
     #include "json.hh"
     
     extern "C" 
     {
         void yyerror(const char *);
         int yylex();
+        
     } 
     
     #include "json.hh"
+    
+    void load_string(const char *);
+    void load_file(FILE*);
+    
+    Value* parsd = nullptr;
 %}
 
 %code requires { #include "json.hh" }
 %type <array_p> array list
 %type <value_p> value
 
+%start json
+
 %%
 
+// Entry point (every JSON file represents a value)
+json: value { parsd = $1; } ;
+
+object: CURLY_BRACKET_L assignment_list CURLY_BRACKET_R 
+    { 
+        $$ = $2;
+    }
+    ;
+
+array : SQUARE_BRACKET_L list SQUARE_BRACKET_R
+    {
+        $$ = $2;
+    }
+    ;
+
 value : NUMBER_I 
     { 
         $$ = new Value($1); 
     }
     | string 
     { 
-        $$ = new Value($1);     
+        $$ = new Value(std::string($1));     
     }
     | object 
     { 
     
 string : DOUBLE_QUOTED_STRING 
     {
+        // Trim string
         std::string s($1);
-        $$ = const_cast<char*>(s.substr(1, s.length()-2).c_str());
+        s = s.substr(1, s.length()-2);
+        
+        char* t = new char[s.length()+1];
+        strcpy(t, s.c_str());
+
+        $$ = t;
     } 
     | SINGLE_QUOTED_STRING
     {
+        // Trim string
         std::string s($1);
-        $$ = const_cast<char*>(s.substr(1, s.length()-2).c_str());
+        s = s.substr(1, s.length()-2);
+        
+        char* t = new char[s.length()+1];
+        strcpy(t, s.c_str());
+
+        $$ = t;
     };
 
 assignment_list:
     }
     ;
     
-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)
 {
-    int t = yyparse();
-    std::cerr << t << std::endl;
+    FILE* in = fopen(argv[1], "r");
+    
+    load_file(in);
+    
+    int status = yyparse();
+    
+    // If parsing went wrong delete the object constructed so far
+    if (status)
+        delete parsd;
+    
+    std::cerr << *parsd << std::endl;
 }
 
+
 void yyerror(const char *s)
 {
     fprintf(stderr, "error: %s\n", s);