Academy
ProgrammingJS AdvancedParsing & ASTs

Parsing & ASTs

Your Code Is Just Text Until Something Reads It

When you write const x = 1 + 2, that is a string of characters. Before V8 can execute it, it must be understood — transformed from raw text into a structured representation the engine can reason about and optimise.

This transformation happens in three stages:

Source code (text)
    ↓  Lexer (tokeniser)
Stream of tokens
    ↓  Parser
Abstract Syntax Tree (AST)
    ↓  Interpreter / Compiler
Result

Babel, ESLint, TypeScript, Prettier, and V8 itself all begin here. Understanding this pipeline is what separates developers who use these tools from developers who can build them.

Stage 1 — The Lexer

A lexer (also called a tokeniser) reads raw source character by character and groups them into meaningful units called tokens. It does not understand structure — it just categorises text:

The lexer produced a flat list of tokens — it has no idea that (radius + 2) is a grouped sub-expression. That understanding is the parser's job.

Stage 2 — The Parser

A parser takes the token stream and builds a tree that reflects the structure and precedence of the expression. This tree is the AST — Abstract Syntax Tree:

The tree for 2 + 3 * 4 has * deeper than + — because the parser's precedence rules correctly made 3 * 4 a sub-tree before adding 2. The tree is the precedence.

Stage 3 — The Interpreter

With an AST, evaluation is a simple recursive tree walk. Each node type has a handler — the interpreter pattern:

The Visitor Pattern — Separating Traversal from Logic

Real tools like ESLint and Babel don't hard-code every operation into the interpreter. They use the Visitor pattern: the traversal walks the AST, and pluggable visitors define what to do at each node type:

This is exactly how ESLint plugins work: you register a visitor for node types you care about, ESLint walks the AST and calls your visitor, and you report problems. You never write a lexer or parser — ESLint provides the AST, you provide the logic.

AST Transformation — How Babel Works

Babel's core job is AST transformation: parse modern JavaScript, walk the AST, replace new syntax nodes with equivalent older syntax nodes, then serialise back to source. The transformation is just a visitor that returns new nodes:

This is constant folding — when V8 sees const PI_2 = 3.14159 * 2, it evaluates it at compile time and replaces the entire expression with 6.28318. You are watching a real compiler optimisation in action, built in twenty lines of JavaScript.

A Complete Mini Language

Extend the language to support let statements and sequences — a tiny but complete programming language:

You just built a programming language. It has variables, arithmetic, operator precedence, and a runtime environment. Every language — from Python to Rust to JavaScript itself — is this pipeline at a larger scale.

Real-World AST Tools You Can Use Today

You do not need to build your own parser for production work — mature tools exist for every use case:

What You Have Learned

Parsing is the foundational technology beneath every developer tool. Understanding the pipeline means you can read Babel plugin docs, write ESLint rules, and understand TypeScript error messages at a structural level.

The key ideas:

  • Lexer: raw text → flat stream of typed tokens — no understanding of structure, just categorisation
  • Parser: token stream → AST — the tree captures operator precedence, grouping, and nesting naturally
  • Recursive descent: one function per grammar rule, naturally handles precedence through call depth
  • Interpreter: walk the AST recursively, evaluate each node type — the tree structure makes precedence evaluation automatic
  • Visitor pattern: decouple traversal from logic — pluggable visitors at each node type are how ESLint rules and Babel plugins work
  • Transformation: walk the AST, replace nodes with new nodes, serialise back — this is Babel's entire job
  • Constant folding: evaluate constant sub-trees at compile time — a real optimisation, trivially expressible as an AST transform
  • Every major JS tool (Babel, ESLint, Prettier, TypeScript) uses the same ESTree AST specification — learn the node shapes once, read all of them

In the final lesson: Security — XSS, CSRF, injection, prototype pollution, and the patterns that make JavaScript applications safe by construction rather than by luck.