build a parser for JSON, the JavaScript Object Notation. Input Input will be pro
ID: 3858287 • Letter: B
Question
build a parser for JSON, the JavaScript Object Notation.
Input
Input will be provided in the form of a file containing a single JSON object or array. The syntax for both structures is defined on the front page of http://www.json.org/ using railroad diagrams.
Processing
Build a recursive-descent parser for JSON. While the specification includes syntax diagrams for tokens, you may wish to build a separate scanner rather than creating procedures for string, number, true, false, and null.
As you parse the JSON object, construct an Abstract Syntax Tree using the following definitions:
Abstract Syntax Tree
ast.h
#ifndef AST_H_
#define AST_H_
class JsonValue
{
public:
virtual void Print() = 0;
};
class JsonObject : public JsonValue
{
private:
map<string, JsonValue*> pairs;
public:
virtual void Print();
void Add(string name, JsonValue* value);
};
class JsonArray : public JsonValue
{
private:
list<JsonValue*> values;
public:
virtual void Print();
void Add(JsonValue *v);
};
class JsonString : public JsonValue
{
private:
string value;
public:
JsonString(string s) : value(s) { };
virtual void Print();
};
class JsonNumber : public JsonValue
{
private:
double value;
public:
JsonNumber(double d) : value(d) { };
virtual void Print();
};
class JsonBoolean : public JsonValue
{
private:
bool value;
public:
JsonBoolean(bool b) : value(b) { };
virtual void Print();
};
class JsonNull : public JsonValue
{
public:
virtual void Print();
};
#endif // AST_H_
Usage
An AST for the following JSON object:
{
"str": "foo",
"num": 123,
"bool": true,
"nul": null,
"arr": [ "bar", 456, false ]
}
might be constructed with the following C++ code:
JsonObject* o = new JsonObject();
o->Add("str", new JsonString("foo"));
o->Add("num", new JsonNumber(123));
o->Add("bool", new JsonBoolean(true));
o->Add("nul", new JsonNull());
JsonArray *a = new JsonArray();
a->Add(new JsonString("bar"));
a->Add(new JsonNumber(456));
a->Add(new JsonBoolean(false));
o->Add("arr", a);
Output
If the file is parsed successfully, call the Print() method to traverse the AST and print the structure of the the tree as a Scheme list with one or more of the following elements:
( string value )
( number value )
( boolean value )
( null )
( array {value} )
( object {name value} )
As in the footnote on p. 49 of the textbook, curly braces ({ }) are used to indicate zero or more instances of the values inside.
Calling o->Print() on the object defined above should produce the following output:
( object arr ( array ( string bar ) ( number 456 ) ( boolean false ) ) bool ( boolean true ) nul ( null ) num ( number 123 ) str ( string foo ) )
Note that the order of the object’s name/value pairs has changed since the C++ std::map type sorts its keys.
If the file is not parsed successfully, output the line number and a clear error message describing what has gone wrong.
Explanation / Answer
"use strict"; // import fs for reading var fs = require ('fs'); // import the generated Parser var parser = require ('./ast.js').parser; var str = fs.readFileSync (process.argv[2], 'UTF-8'); // add a text to the parser try { // run the parser using a string, why are the values printed upside down? var info = parser.parse (str); console.log ('Symbol table'); console.log (JSON.stringify(info.parse_tree, null, 4)); // console.log ('Parse tree'); // console.log (JSON.stringify (info.parse_tree, null, 4)); } catch (e) { // display the error message and data // console.log ('You have an error at line '+(e.hash.line+1)+' at position '+e.hash.loc.first_column); // console.log (e.message); console.log (e); }
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.