Glossary

AST

AST stands for abstract syntax tree, a tree of nodes that represents the grammatical structure of source code without the punctuation and whitespace. A parser builds it from text, and tools such as compilers, linters, formatters, bundlers and transpilers read and change it. For JavaScript, the community format is ESTree, whose steering committee has members from ESLint, Acorn and Babel.

How it works

A parser first splits code into tokens, then arranges the tokens into a tree that follows the language grammar. Each node has a type, such as an assignment, a function call or a number, and children for its parts. The tree is "abstract" because it drops details that do not change meaning: parentheses, semicolons and most whitespace. Operator precedence is already resolved by the tree shape.

  • Parse: source text in, tree out.
  • Walk or transform: a tool visits nodes, reports problems (a linter) or rewrites them (a transpiler or minifier).
  • Generate: the tree is printed back to source code, optionally with a source map that links the output to the original positions.

Node names are not universal. Python's ast module, ESTree for JavaScript and other languages each define their own node types, so a tool written for one tree format will not read another. Trees also change between language versions as new syntax is added.

This Python run parses a one-line assignment and prints the tree. Note that the multiplication sits deeper than the addition, which is how precedence appears in a tree:

import ast
t = ast.parse("total = price * 2 + 1")
print(ast.dump(t, indent=2))
Module(
  body=[
    Assign(
      targets=[
        Name(id='total', ctx=Store())],
      value=BinOp(
        left=BinOp(
          left=Name(id='price', ctx=Load()),
          op=Mult(),
          right=Constant(value=2)),
        op=Add(),
        right=Constant(value=1)))],
  type_ignores=[])

That output came from Python 3.11.15. The indent option of ast.dump was added in Python 3.9. From Python 3.13, ast.dump hides empty lists by default, so the type_ignores=[] line does not appear.

What is the difference between an AST and a parse tree?

A parse tree, also called a concrete syntax tree, keeps every token the grammar matched, including parentheses and punctuation. An AST keeps only the structure that matters for meaning. Parse trees are larger and mirror the grammar exactly, while an AST is smaller and easier to analyze. Some formatters need extra comment and whitespace data attached to the AST so they can print code the way it was written.

What is an AST used for?

Linters such as ESLint find bugs by matching tree patterns. Formatters re-print code from the tree. Transpilers like Babel rewrite newer syntax into older syntax. Bundlers use the tree to find imports and remove unused code, and code-search and refactoring tools use it to find a function call without confusing it with the same text inside a string.

Common pitfalls

  • Using a regex to find code constructs: a pattern cannot tell a function call from the same text inside a string or comment. Parse the code and query the tree instead.
  • Assuming one tree format per language: parsers can emit different node names for the same code. Pick a parser and match its documented format, such as ESTree for JavaScript.
  • Pinning to node shapes that change: Python 3.8 moved all literals to the Constant node, and 3.12 added TypeAlias and type_params. Test your tooling on each version you support.
  • Losing comments and formatting: most ASTs drop them. A tool that rewrites code must carry comments separately or it will delete them.
  • Treating untrusted code as safe to parse: parsing does not run the code, but Python's docs warn that a large or deeply nested input can crash the interpreter. Limit input size, and never pass it to eval or exec.
  • Forgetting syntax errors: a parser throws on invalid code. Catch the error and report the line and column it gives.

Related terms

  • Source map — links generated code back to the original positions after a tool rewrites the tree.
  • Minifier — a tool that parses code, shortens it and prints it back.
  • Regex — pattern matching on text, which cannot understand nested structure the way a tree can.
  • JSON — a common way to serialize a tree for inspection.

See also

  • Term: Source map — shows how tree-based tools keep output traceable to the original code.