Skip to content

Latest commit

 

History

History
89 lines (66 loc) · 4.46 KB

version2.md

File metadata and controls

89 lines (66 loc) · 4.46 KB

Plan for AST Implementation

  1. Evolve the AST: From Homogeneous to Heterogeneous

    Your current AST class is a good start (a homogeneous AST). However, for a JSON parser, a more expressive and type-safe structure is a heterogeneous AST. This means having different classes for different types of JSON values.

    I suggest creating a JsonNode interface and then a class for each JSON type. This will make the resulting tree much easier to work with.

    Action: Create the following files in src/main/java/it/diamondnet/challenge/:

    • JsonNode.java (an interface, maybe empty for now)
    • JsonObjectNode.java (contains a Map<String, JsonNode>)
    • JsonArrayNode.java (contains a List)
    • JsonStringNode.java (contains a String)
    • JsonNumberNode.java (contains a Number)
    • JsonBooleanNode.java (contains a boolean)
    • JsonNullNode.java (can be a singleton)
  2. Modify the Parser to Return JsonNode

    The core of the work is to change the signature of your JsonParser methods to return JsonNode objects.

    • public void jValue() will become public JsonNode jValue()
    • public void jObject() will become public JsonObjectNode jObject()
    • public void jArray() will become public JsonArrayNode jArray()
    • ...and so on for jString(), jNumber(), jBool(), jNull().
  3. Progressive Implementation: One Value at a Time

    Instead of changing everything at once, we can do it step-by-step.

    • Step A: Simple Values. Start with the simplest methods. Modify jString(), jNumber(), jBool(), and jNull() to create and return their corresponding new node types (e.g., jString() will return a JsonStringNode containing the string from the token).
    • Step B: Arrays. Modify jArray() to create a JsonArrayNode. Inside its loop, it will call jValue() and add the returned JsonNode to the list within the JsonArrayNode.
    • Step C: Objects. Modify jObject(). This is the most complex. It will create a JsonObjectNode. In the loop, it will parse the key (which is a string) and then call jValue() to parse the value. It will then put the key and the JsonNode value into the map of the JsonObjectNode.
    • Step D: Top-Level. Finally, jPayload() will be modified to return the root JsonNode of the entire document.
  4. Update and Create New Tests

    Your existing tests are great for validation, but you'll need new ones to verify the AST structure. For each step above, you should create a test that:

    1. Parses a sample JSON string.
    2. Gets the resulting JsonNode (the AST).
    3. Asserts that the tree has the correct structure and that the values in the nodes are correct.

explanation of classes:

  1. JsonNode: This is a common interface. Its purpose is to allow you to treat all the different kinds of JSON values (objects, arrays, strings, numbers, etc.) in a uniform way. This is why a List is so powerful—it can hold any valid JSON element.

  2. "Leaf" Nodes (Primitives):

    • JsonStringNode, JsonNumberNode, JsonBooleanNode, JsonNullNode
    • These classes represent a single, final value. A JsonStringNode holds a String, a JsonNumberNode holds a number, and so on. They don't have "children" because they are the leaves of the tree.
  3. "Branch" Nodes (Containers):

    • JsonArrayNode: As you correctly deduced, its private final List children field holds the entire list of elements in the array. Each element is, in turn, another object that implements JsonNode.
    • JsonObjectNode: Similarly, its private final Map<String, JsonNode> children field stores the key-value pairs of a JSON object. The keys are Strings, and the values are any other JsonNode.

Example

If your parser processes the following JSON:

1 [ 2 "apple", 3 { "id": 101 }, 4 true 5 ]

It would build an object structure like this in memory:

1 new JsonArrayNode(
2     children = [
3         new JsonStringNode("apple"),
4         new JsonObjectNode(
5             children = {
6                 "id": new JsonNumberNode(101)
7             }
8         ),
9         new JsonBooleanNode(true)

10 ] 11 )

So, to summarize: Yes, the children list in JsonArrayNode (and the map in JsonObjectNode) maintains all the object data for its elements. This composite structure is what allows you to represent any arbitrarily complex JSON document.