liveBook · Manning

Depth-first tree traversal

As explained in Building User-Friendly DSLs

A tree traversal technique that visits a child subtree before later nodes at the same or higher level, then backtracks to continue.

Depth-first tree traversal (DFTT) visits an abstract syntax tree (AST) in a fixed, orderly path: visit an object, inspect its settings, descend into a contained child before later siblings, then backtrack when that child is complete. The pattern specifies visitation order rather than the work performed at each visit, so the same traversal can search, modify, copy, or analyze an AST. section 3.3 section 3.3.1

Figure 3.15 Traversing an AST generically
figure

Use the generic traversal diagram to follow the movement from an AST object through its settings, into contained objects, and back to unfinished work. section 3.3.1

For each value encountered, a DFTT handles its shape deliberately:

  • For an AST object, process the object and visit its settings in a consistent order. section 3.3.1
  • For a contained AST object, recurse into it; after its settings are complete, return to the containing object. section 3.3.1
  • For a reference object, inspect its target when needed but do not traverse into that target. section 3.3.1
  • For an array setting, traverse each item in array order; for simple values, inspect them if useful but do not descend. section 3.3.1

Count AST leaves recursively

A recursive numberOfLeaves function accepts any encoded AST value. For an AST object, it recursively totals leaf counts from its settings and returns 1 when that total is zero. References contribute 0, arrays sum their items, and simple values contribute 0. Calling the function on the rental AST returns 4. Recursion lets the JavaScript call tree retain the path needed for backtracking. section 3.3.2 section 3.3.1

DFTT also supports AST transformations. A migration can recursively visit objects and arrays, then rename the Data Attribute concept to Attribute and replace its initial value setting with value. Such migrations update ASTs that conform to an earlier DSL structure so they conform to a later one; version IDs should be checked before and updated after migration. section 10.3.2

How Building User-Friendly DSLs covers it

How deep it goes
Gives a general value-by-value recipe and recursive JavaScript implementation, including containment, references, arrays, and backtracking.
Examples
Demonstrates a Record Type and Data Attribute AST, a recursive leaf counter returning 4, and a Data Attribute migration.
What it assumes
Assumes familiarity with encoded AST values and helper checks for AST and reference objects.
What you can do after
Build it from scratch as a recursive function that processes encoded AST objects, references, arrays, and simple values.
How it connects
Connects abstract syntax trees, containment relations, reference relations, recursion, serialization, constraints, and AST migration.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Building User-Friendly DSLs. The section links point to the parts of the book it draws on.