Spry LogoSpry Docs

AST (Abstract Syntax Trees)

AST in SPRY.

Introduction

Abstract Syntax Trees (AST) are structured, tree-like representations of source content.
In Spry, ASTs are widely used to inspect, transform, and automate workflows involving Markdown-based runbooks, configuration, and documentation.

Spry internally parses Markdown into axiom (Markdown AST) so that automated tools can analyze nodes, extract metadata, transform blocks, or execute code cells in runbooks.


Concept of AST

An AST (Abstract Syntax Tree) is:

  • A hierarchical representation of content
  • Broken into nodes (heading, paragraph, code, list, table, etc.)
  • Language-independent
  • Ideal for transformations, validations, and querying

In Spry, the AST lets you:

  • Inspect Markdown structure
  • Query nodes
  • Identify runbook cells
  • Modify or extract information
  • Understand flow and dependencies between cells (useful for DAG execution)

Spry mainly works with axiom, a Markdown AST format from the unified ecosystem.


How AST Is Used in SPRY

1. Runbook Analysis

Spry parses Markdown runbooks into AST to:

  • Detect executable code blocks
  • Determine DAG ordering
  • Execute tasks in correct dependency order
  • Validate metadata (YAML frontmatter, tags, identifiers)

2. Markdown Processing

Spry uses AST to:

  • Inspect headings and structure
  • Transform content programmatically
  • Extract identifiers, links, or code samples

3. Spry CLI Tools

Commands like spry axiom allow:

  • Querying AST nodes
  • Listing node hierarchies
  • Inspecting Markdown documents before automation or execution

Possible SPRY AST Commands

Sample file.md:

file.md
# AST 
Abstract Syntax Trees (AST) are structured, tree-like representations of source content.

## Task

``` bash tsk-1 --descr "Task1"
echo "Task1"
```
``` bash tsk-2 --dep tsk-1 --descr "Task1"
echo "Task2"
``` 

1. List Nodes

spry axiom ls file.md

Shows a structured view of all nodes.

Example Output

NAME                                     TYPE      FILE         DATA  
---------------------------------------  --------  -----------  ------
file.md                                  document                     
└─ heading: #1 AST                       heading   file.md:1:1        
   └─ heading: #2 Task                   heading   file.md:4:1        
      ├─ code[tsk-1]: bash echo "Task1"  code      file.md:6:1  codeFM
      └─ code[tsk-2]: bash echo "Task2"  code      file.md:9:1  codeFM

2. Inspect mdast nodes as a hierarchy

spry axiom inspect file.md

Example Output

├─0 heading[1] (1:1-1:7, 0-6)
│   │ depth: 1
│   └─0 text "AST" (1:3-1:6, 2-5)
├─1 paragraph[1] (2:1-2:89, 7-95)
│   └─0 text "Abstract Syntax Trees (AST) are structured, tree-like representations of source content." (2:1-2:89, 7-95)
├─2 heading[1] (4:1-4:8, 97-104)
│   │ depth: 2
│   └─0 text "Task" (4:4-4:8, 100-104)
├─3 code "echo \"Task1\"" (6:1-8:4, 106-153)
│     lang: "bash"
│     meta: "tsk-1 --descr \"Task1\""
│     data: {"codeFM":{"lang":"bash","langSpec":{"id":"shell","aliases":["bash","sh","zsh"],"extensions":[".sh",".bash",".zsh"],"shebangs":["bash","sh","zsh"],"comment":{"line":["#"],"block":[]}},"meta":"tsk-1 --descr \"Task1\"","pi":{"args":["bash","tsk-1","--descr","Task1"],"pos":["tsk-1","descr"],"flags":{"tsk-1":true,"descr":"Task1"},"count":4,"posCount":2},"cmdLang":"bash","cli":"bash tsk-1 --descr \"Task1\"","fromPresets":[]}}
│     nature: "EXECUTABLE"
│     isActionableCodeCandidate: true
│     spawnableIdentity: "tsk-1"
│     language: {"id":"shell","aliases":["bash","sh","zsh"],"extensions":[".sh",".bash",".zsh"],"shebangs":["bash","sh","zsh"],"comment":{"line":["#"],"block":[]}}
│     spawnableArgs: {"description":"Task1","deps":[],"graphs":[],"injectedDep":[]}
│     memoizeOnly: false
└─4 code "echo \"Task2\"" (9:1-11:5, 154-214)
      lang: "bash"
      meta: "tsk-2 --dep tsk-1 --descr \"Task1\""
      data: {"codeFM":{"lang":"bash","langSpec":{"id":"shell","aliases":["bash","sh","zsh"],"extensions":[".sh",".bash",".zsh"],"shebangs":["bash","sh","zsh"],"comment":{"line":["#"],"block":[]}},"meta":"tsk-2 --dep tsk-1 --descr \"Task1\"","pi":{"args":["bash","tsk-2","--dep","tsk-1","--descr","Task1"],"pos":["tsk-2","dep","descr"],"flags":{"tsk-2":true,"dep":"tsk-1","descr":"Task1"},"count":6,"posCount":3},"cmdLang":"bash","cli":"bash tsk-2 --dep tsk-1 --descr \"Task1\"","fromPresets":[]}}
      nature: "EXECUTABLE"
      isActionableCodeCandidate: true
      spawnableIdentity: "tsk-2"
      language: {"id":"shell","aliases":["bash","sh","zsh"],"extensions":[".sh",".bash",".zsh"],"shebangs":["bash","sh","zsh"],"comment":{"line":["#"],"block":[]}}
      spawnableArgs: {"description":"Task1","deps":["tsk-1"],"graphs":[],"injectedDep":[]}
      memoizeOnly: false

This document provides an overview of AST usage in Spry, with commands and examples for easy reference.

How is this guide?

Last updated on

On this page