Abstract syntax tree

An abstract syntax tree for the following code for the Euclidean algorithm:
while b != 0:
    if a > b:
        a := a - b
    else:
        b := b - a
return a

An abstract syntax tree (AST) is a tree data structure used in computer science to represent the abstract syntactic structure of text, often source code, written in a formal language. Each node of the tree denotes a construct occurring in the text. It is sometimes called simply a syntax tree.[1]

The syntax is "abstract" in the sense that it does not represent every detail of the concrete syntax, but instead represents the essential structural information of the text. For example, grouping parentheses need not be represented as separate nodes because their effect is implicit in the tree structure. Similarly, punctuation and delimiters such as braces, semicolons, and parentheses may be omitted from an AST.[1]

This distinguishes an abstract syntax tree from a concrete syntax tree, traditionally called a parse tree. During syntax analysis, a parser may construct an AST representing the syntactic structure of the input program.[1] The AST can then serve as an intermediate representation for subsequent compiler phases, which may use information in the AST, annotate it with additional information, or transform it.[1]

Abstract syntax trees are also used in program analysis and program transformation systems.[2]

Overview

An AST represents the structure of an expression or program independently of many details of its concrete syntax. For example, the expression

a + b * c

can be represented by a simplified AST such as:

      +
     / \
    a   *
       / \
      b   c

In this representation, the structure of the tree captures the order in which the operations are grouped: the multiplication of b and c forms a subtree that is an operand of the addition. The precedence of multiplication over addition is therefore represented by the tree structure rather than by an explicit precedence rule once the AST has been constructed.[1]

An AST differs in this respect from a concrete syntax tree. A concrete syntax tree reflects the grammatical structure used to parse the source text and may contain nodes corresponding to grammar productions or syntactic elements that are not needed for later processing. An AST instead retains the structure considered significant for subsequent processing while omitting some details of the concrete syntax.[3]

This structured representation allows software to inspect and manipulate a program in terms of constructs such as expressions, statements, declarations, and identifiers rather than treating the source solely as a sequence of characters. ASTs can therefore be traversed and processed by compilers and by other software-development tools.[1]

History

The development of abstract syntax is closely connected with early work on the formal description and implementation of programming languages. John McCarthy, who developed Lisp and coined the term Artificial Intelligence, introduced the idea of abstract syntax in work published in the early 1960s.[4][5]

McCarthy's motivation was to describe the structure of programming-language expressions independently of the notation used to represent them. For example, a sum might be written in infix notation as a+b, in prefix or postfix notation, or as the Lisp S-expression (PLUS A B), while representing the same underlying syntactic operation. In this view, the important properties are the ability to recognize a construct and to identify its constituent parts rather than the particular sequence of symbols used to write it.[4][6]

Tree-based representations of syntax subsequently became part of practical compiler construction. The TREE-META compiler-compiler system, documented in 1969, used grammar rules with embedded tree-building directives and provided tree-scanning and code-generation facilities for processing the resulting structures.[7]

Application in compilers

Abstract syntax trees are data structures widely used in compilers to represent the structure of program code. An AST is commonly constructed during the syntax analysis phase and can serve as an intermediate representation through which information is conveyed between subsequent compiler phases.[1]

Motivation

An AST provides a structured representation of a program that can be used by subsequent phases of a compiler. Compared with a concrete syntax tree, an AST generally omits syntactic details that are not needed for later processing while retaining the essential structure of the program.[8] It can therefore serve as an intermediate representation through which information is conveyed between compiler phases.[1]

Later compiler passes may associate additional information with the program represented by the AST. For example, symbol processing can associate uses of names with their declarations and record attributes of those names in a symbol table; this information can subsequently be used for tasks such as type checking.[9]

Some properties of a program cannot be determined from its context-free syntax alone. In particular, semantic constraints such as whether an identifier refers to an appropriate declaration or whether an expression has a valid type depend on information about declarations and the surrounding program. These constraints are typically checked during semantic analysis, using information represented by the AST together with structures such as symbol tables.[9]

Design

The structure of an AST depends on the constructs of the source language and on the requirements of the compiler or other tool that uses it. In general, an AST preserves the essential hierarchical structure of the program while omitting syntactic details that are unnecessary for subsequent processing.[1]

Different kinds of language constructs are typically represented by different kinds of AST nodes. For example, a binary expression can be represented by a node containing an operator and two operand subtrees, while constructs such as statement or argument lists may contain a variable number of child nodes. The particular representation is an implementation choice and varies among AST designs.[3]

An AST may also contain or be associated with information used by later compiler phases. For example, nodes may record source locations, while semantic analysis may associate identifiers with declarations and determine information such as types.[9] The exact information retained in or alongside the AST depends on the compiler's implementation.

Some AST implementations support unparsing, in which a source-code representation is generated by traversing the tree. Because an AST normally omits details of the concrete syntax, the resulting source need not reproduce the original text exactly; formatting, comments, punctuation, or redundant parentheses may differ.[10]

During semantic analysis, the AST can be used together with information such as symbol tables to check semantic constraints including scope and type rules.[9] After semantic analysis, a compiler may translate the program represented by the AST into another intermediate representation for optimization or code generation, although some compilers generate target code without a separate IR.[11]

Other applications

Beyond their role in compiler construction, abstract syntax trees are used by software-development tools that need to inspect, analyze, or transform source code according to its structure. Applications include static analysis, linting, automated refactoring, source-to-source transformation, code generation, and program comparison.

Static analysis and linting

Static-analysis and linting tools can traverse a program's syntax tree and identify particular kinds of constructs or structural patterns. ESLint, for example, parses source code into a syntax tree that is exposed to linting rules. Rules can respond to particular node types, inspect the surrounding tree and scope information, report problems associated with AST nodes, and in some cases provide automatic fixes.[12]

Refactoring and development tools

ASTs are also used by development environments and refactoring tools because they allow source-code changes to be described in terms of program constructs rather than solely as textual replacements. Clang provides facilities for matching patterns in its C and C++ AST and using those matches in source-analysis and transformation tools. Clang deliberately preserves some source-level constructs in its AST that other compiler representations may discard, which its documentation identifies as useful for refactoring.[13]

The Eclipse Java Development Tools similarly provide a Java DOM/AST model and an ASTRewrite API for describing changes to AST nodes and applying those changes back to source code.[14]

Source transformation and code generation

Source-to-source transformation tools can parse source code into an AST, modify the resulting tree, and generate source code from the modified representation. Babel, for example, provides separate components for parsing JavaScript into an AST, traversing and updating AST nodes, and generating JavaScript source from an AST.[15][16][17] Because details such as whitespace and line breaks are not necessarily represented in the AST, generated source code need not reproduce the formatting of the original input.[17]

Language and library interfaces

Some programming languages expose their AST representations directly to programmers. Python's standard library, for example, includes the ast module, which can parse Python source into objects representing nodes of Python's abstract syntax grammar. The resulting AST can be inspected or transformed and can subsequently be compiled into a Python code object.[18]

Representative modern uses of ASTs include:

Technology Example use of ASTs
Clang Compilation, source analysis, structural matching, and refactoring[13]
Babel Parsing, transforming, and regenerating JavaScript source[15][16][17]
ESLint Structural source-code analysis, linting, and automated fixes[12]
Eclipse JDT Java source analysis and AST-based source rewriting[14]
Python ast Programmatic inspection, transformation, and compilation of Python syntax trees[18]

AST differencing

AST differencing, or for short tree differencing, consists of computing the list of differences between two ASTs.[19][20] This list of differences is typically called an edit script. The edit script directly refers to the AST of the code. For instance, an edit action may result in the addition of a new AST node representing a function.

Clone detection

An AST is a powerful abstraction to perform code clone detection.[21]

Formalization

One formal treatment of abstract syntax represents ASTs using multiple sorts corresponding to different syntactic categories. In this formulation, the categories of syntax are represented by sorts, while language constructs are represented by operators whose arities specify the number and sorts of their arguments. ASTs are then defined inductively from variables and applications of these operators.[22]

The following gives this construction explicitly.

Arities

Let be a set of sorts, an arity is a tuple , for , also written as . More precisely, .

Let be an -indexed family of disjoint sets of operators. If is an operator arity we say that has sort and has arguments of sorts .

ASTs

Fix be a finite set of sorts, and an -indexed family of disjoint sets of operators. Let be an -indexed family of disjoint sets of variables. The family of abstract syntax trees, or ASTs, is the smallest -indexed family of disjoint sets closed under the following conditions:

  1. Variables are ASTs: if , then .
  2. Operators combine ASTs: If is an operator of arity , and for all , then .[22]

See also

References

  1. ^ a b c d e f g h i Fischer, Charles N.; Cytron, Ron K.; LeBlanc, Richard J. "Syntax-Directed Translation". Crafting a Compiler. Addison-Wesley. ISBN 978-0-13-606705-4.
  2. ^ Kats, Lennart C. L.; Visser, Eelco (2008). "Fusing a Transformation Language with an Open Compiler". Electronic Notes in Theoretical Computer Science. 203 (2): 21–36. doi:10.1016/j.entcs.2008.03.042.
  3. ^ a b "Syntax-Directed Translation". University of Wisconsin–Madison. Retrieved 19 August 2026.
  4. ^ a b McCarthy, John (1963). "Towards a Mathematical Science of Computation". Proceedings of the IFIP Congress 1962. North-Holland. pp. 21–28. Retrieved 19 August 2026.
  5. ^ McCarthy, John; Minsky, Marvin L.; Rochester, Nathaniel; Shannon, Claude E. (2006). "A Proposal for the Dartmouth Summer Research Project on Artificial Intelligence: August 31, 1955". AI Magazine. 27 (4): 12–14. doi:10.1609/aimag.v27i4.1904.
  6. ^ McCarthy, John. "Abstract Languages". Retrieved 19 August 2026.
  7. ^ Carr, C. S.; Luther, D. A.; Erdmann, S. (1969). The Tree-Meta Compiler-Compiler System: A Meta Compiler System for the Univac 1108 and the General Electric 645 (Report). National Technical Information Service. AD855122. Retrieved 19 August 2026.
  8. ^ Cooper, Keith D.; Torczon, Linda (2023). "Intermediate Representations". Engineering a Compiler (3rd ed.). Morgan Kaufmann. ISBN 978-0-12-815412-0.
  9. ^ a b c d "Symbol Tables and Declaration Processing". Crafting a Compiler. Washington University in St. Louis. Retrieved 19 August 2026.
  10. ^ "Programming Assignment 3: The Parser". University of Wisconsin–Madison. Retrieved 19 August 2026.
  11. ^ "Intermediate Representations". Crafting a Compiler. Washington University in St. Louis. Retrieved 19 August 2026.
  12. ^ a b "Custom Rules". ESLint. Retrieved 19 August 2026.
  13. ^ a b "Introduction to the Clang AST". Clang documentation. LLVM Project. Retrieved 19 August 2026.
  14. ^ a b "Package org.eclipse.jdt.core.dom.rewrite". Eclipse JDT API Specification. Eclipse Foundation. Retrieved 19 August 2026.
  15. ^ a b "@babel/parser". Babel documentation. Retrieved 19 August 2026.
  16. ^ a b "@babel/traverse". Babel documentation. Retrieved 19 August 2026.
  17. ^ a b c "@babel/generator". Babel documentation. Retrieved 19 August 2026.
  18. ^ a b "ast — Abstract syntax trees". Python documentation. Python Software Foundation. Retrieved 19 August 2026.
  19. ^ Fluri, Beat; Wursch, Michael; PInzger, Martin; Gall, Harald (2007). "Change Distilling:Tree Differencing for Fine-Grained Source Code Change Extraction". IEEE Transactions on Software Engineering. 33 (11): 725–743. Bibcode:2007ITSEn..33..725F. doi:10.1109/tse.2007.70731. ISSN 0098-5589. S2CID 13659557.
  20. ^ Falleri, Jean-Rémy; Morandat, Floréal; Blanc, Xavier; Martinez, Matias; Monperrus, Martin (2014). "Fine-grained and accurate source code differencing". Proceedings of the 29th ACM/IEEE International Conference on Automated Software Engineering. pp. 313–324. doi:10.1145/2642937.2642982. ISBN 978-1-4503-3013-8.
  21. ^ Koschke, Rainer; Falke, Raimar; Frenzel, Pierre (2006). "Clone Detection Using Abstract Syntax Suffix Trees". 2006 13th Working Conference on Reverse Engineering. IEEE. pp. 253–262. doi:10.1109/wcre.2006.18. ISBN 0-7695-2719-1. S2CID 6985484.
  22. ^ a b Harper, Robert (2016). "Abstract Syntax". Practical Foundations for Programming Languages (2nd ed.). Cambridge University Press. pp. 3–6. doi:10.1017/CBO9781316576892.003. ISBN 978-1-107-15030-0.

Further reading

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.