This section describes the standard representation of parse trees for Erlang
programs as Erlang terms. This representation is known as the abstract
format. Functions dealing with such parse trees are
The functions are also used as input and output for parse transforms, see
the
We use the function
The word
As operators are not terms in their own right, when operators are mentioned below, the representation of an operator is to be taken to be the atom with a printname consisting of the same characters as the operator.
A module declaration consists of a sequence of forms, which are either function declarations or attributes.
If D is a module declaration consisting of the forms
If F is an attribute
If F is an attribute
If F is an attribute
If F is an attribute
If F is a function declaration
If F is a function specification
If F is a function specification
If F is a record declaration
If F is a type declaration
If F is a wild attribute
Each field in a record declaration can have an optional, explicit, default initializer expression, and an optional type.
If V is
If V is
If V is
If V is
In addition to the representations of forms, the list that represents
a module declaration (as returned by functions in
Tuples
There are five kinds of atomic literals, which are represented in the same way in patterns, expressions, and guards:
If L is an atom literal, then Rep(L) =
If L is a character literal, then Rep(L) =
If L is a float literal, then Rep(L) =
If L is an integer literal, then
Rep(L) =
If L is a string literal consisting of the characters
Notice that negative integer and float literals do not occur as such; they are parsed as an application of the unary negation operator.
If Ps is a sequence of patterns
Individual patterns are represented as follows:
If P is an atomic literal
If P is a bitstring pattern
If P is a compound pattern
If P is a cons pattern
If P is a map pattern
If P is a nil pattern
If P is an operator pattern
If P is an operator pattern
If P is a parenthesized pattern
If P is a record field index pattern
If P is a record pattern
If P is a tuple pattern
If P is a universal pattern
If P is a variable pattern
Notice that every pattern has the same source form as some expression, and is represented in the same way as the corresponding expression.
A body B is a non-empty sequence of expressions
An expression E is one of the following:
If E is an atomic literal
If E is a bitstring comprehension
If E is a bitstring constructor
If E is a block expression
If E is a case expression
If E is a catch expression
If E is a cons skeleton
If E is a fun expression
If E is a fun expression
If E is a fun expression
If E is a fun expression
If E is a function call
If E is a function call
If E is an if expression
If E is a list comprehension
If E is a map creation
If E is a map update
If E is a match operator expression
If E is nil,
If E is an operator expression
If E is an operator expression
If E is a parenthesized expression
If E is a receive expression
If E is a receive expression
If E is a record creation
If E is a record field access
If E is a record field index
If E is a record update
If E is a tuple skeleton
If E is a try expression
If E is a try expression
If E is a try expression
If E is a try expression
If E is a try expression
If E is a try expression
If E is a variable
A qualifier Q is one of the following:
If Q is a filter
If Q is a generator
If Q is a bitstring generator
A type specifier list TSL for a bitstring element is a sequence
of type specifiers
If TS is a type specifier
If TS is a type specifier
An association A is one of the following:
If A is an association
If A is an association
There are function clauses, if clauses, case clauses, and catch clauses.
A clause C is one of the following:
If C is a case clause
If C is a case clause
If C is a catch clause
If C is a catch clause
If C is a catch clause
If C is a catch clause
If C is a catch clause
If C is a catch clause
If C is a function clause
If C is a function clause
If C is an if clause
A guard sequence Gs is a sequence of guards
A guard G is a non-empty sequence of guard tests
A guard test Gt is one of the following:
If Gt is an atomic literal
If Gt is a bitstring constructor
If Gt is a cons skeleton
If Gt is a function call
If Gt is a function call
If Gt is a map creation
If Gt is a map update
If Gt is nil,
If Gt is an operator guard test
If Gt is an operator guard test
If Gt is a parenthesized guard test
If Gt is a record creation
If Gt is a record field access
If Gt is a record field index
If Gt is a tuple skeleton
If Gt is a variable pattern
Notice that every guard test has the same source form as some expression, and is represented in the same way as the corresponding expression.
If T is an annotated type
If T is an atom or integer literal L, then Rep(T) = Rep(L).
If T is a bitstring type
If T is the empty list type
If T is a fun type
If T is a fun type
If T is a fun type
If T is an integer range type
If T is a map type
If T is a map type
If T is an operator type
If T is an operator type
If T is
If T is a predefined (or built-in) type
If T is a record type
If T is a remote type
If T is a tuple type
If T is a tuple type
If T is a type union
If T is a type variable
If T is a user-defined type
A function type Ft is one of the following:
If Ft is a constrained function type
If Ft is a function type
A function constraint Fc is a non-empty sequence of constraints
If A is an association type
If A is an association type
The compilation option
As from Erlang/OTP R9C, the
In OTP releases before R9C, the abstract code after some more
processing was stored in the Beam file. The first element of the
tuple would be either