erl_parse(3)
π NAME π
Okay bestie, welcome to erl_parse(3) β it's part of the Erlang Module Definition docs. So basically, erl_parse is THE basic Erlang parser. It takes tokens and converts them into the abstract form of either forms (aka top-level constructs), expressions, or terms. Periodt. π
β¨ DESCRIPTION β¨
So the Abstract Format is described in the ERTS User's Guide. And important: a token list must end with the dot token to be acceptable to the parse functions (see the erl_scan module). No dot, no parse, iykyk. π
π«Ά Error Information π«Ά
ErrorInfo is the standard ErrorInfo structure that is returned from all I/O modules. The format is as follows:
{ErrorLine, Module, ErrorDescriptor}
A string describing the error is obtained with the following call:
Module:format_error(ErrorDescriptor)
πΈ See Also πΈ
erl_annoerl_scanio- section The Abstract Format in the ERTS User's Guide.
π¦ DATA TYPES π¦
Okay so here's the whole squad of data types, bestie. Don't skip any, they're all important. π
abstract_clause()
abstract_clause() :: af_clause().
Abstract form of an Erlang clause.
abstract_expr()
abstract_expr() ::
af_literal() |
af_match(abstract_expr()) |
af_maybe_match() |
af_variable() |
af_tuple(abstract_expr()) |
af_nil() |
af_cons(abstract_expr()) |
af_bin(abstract_expr()) |
af_binary_op(abstract_expr()) |
af_unary_op(abstract_expr()) |
af_record_creation(abstract_expr()) |
af_record_update(abstract_expr()) |
af_record_index() |
af_record_field_access(abstract_expr()) |
af_native_record_creation() |
af_native_record_update() |
af_map_creation(abstract_expr()) |
af_map_update(abstract_expr()) |
af_catch() |
af_local_call() |
af_remote_call() |
af_list_comprehension() |
af_map_comprehension() |
af_binary_comprehension() |
af_block() |
af_if() |
af_case() |
af_try() |
af_receive() |
af_local_fun() |
af_remote_fun() |
af_fun() |
af_named_fun() |
af_maybe() |
af_maybe_else().
Abstract form of an Erlang expression.
abstract_form()
abstract_form() ::
af_module() |
af_behavior() |
af_behaviour() |
af_export() |
af_import() |
af_import_record() |
af_export_type() |
af_compile() |
af_file() |
af_record_decl() |
af_native_record_decl() |
af_type_decl() |
af_function_spec() |
af_wild_attribute() |
af_function_decl().
Abstract form of an Erlang form.
abstract_type()
abstract_type() ::
af_annotated_type() |
af_atom() |
af_bitstring_type() |
af_empty_list_type() |
af_fun_type() |
af_integer_range_type() |
af_map_type() |
af_predefined_type() |
af_record_type() |
af_remote_type() |
af_singleton_integer_type() |
af_tuple_type() |
af_type_union() |
af_type_variable() |
af_user_defined_type().
Abstract form of an Erlang type.
af_anno()
af_anno() :: af_variable().
af_annotated_type()
af_annotated_type() ::
{ann_type, anno(), [af_anno() | abstract_type()]}.
af_args()
af_args() :: [abstract_expr()].
af_assoc(T)
af_assoc(T) :: {map_field_assoc, anno(), T, T} | af_assoc_exact(T).
af_assoc_exact(T)
af_assoc_exact(T) :: {map_field_exact, anno(), T, T}.
af_assoc_type()
af_assoc_type() ::
{type, anno(), map_field_assoc, [abstract_type()]} |
{type, anno(), map_field_exact, [abstract_type()]}.
af_atom()
af_atom() :: af_lit_atom(atom()).
af_behavior()
af_behavior() :: {attribute, anno(), behavior, behaviour()}.
af_behaviour()
af_behaviour() :: {attribute, anno(), behaviour, behaviour()}.
af_bin(T)
af_bin(T) :: {bin, anno(), [af_binelement(T)]}.
af_binary_comprehension()
af_binary_comprehension() ::
{bc, anno(), af_template(), af_qualifier_seq()}.
af_binary_op(T)
af_binary_op(T) :: {op, anno(), binary_op(), T, T}.
af_binelement(T)
af_binelement(T) ::
{bin_element,
anno(),
T,
af_binelement_size(),
type_specifier_list()}.
Abstract representation of an element of a bitstring.
af_binelement_size()
af_binelement_size() :: default | abstract_expr().
af_bitstring_type()
af_bitstring_type() ::
{type, anno(), binary, [af_singleton_integer_type()]}.
af_block()
af_block() :: {block, anno(), af_body()}.
af_body()
af_body() :: [abstract_expr(), ...].
af_case()
af_case() :: {'case', anno(), abstract_expr(), af_clause_seq()}.
af_catch()
af_catch() :: {'catch', anno(), abstract_expr()}.
af_character()
af_character() :: {char, anno(), char()}.
af_clause()
af_clause() ::
{clause, anno(), [af_pattern()], af_guard_seq(), af_body()}.
af_clause_seq()
af_clause_seq() :: [af_clause(), ...].
af_compile()
af_compile() :: {attribute, anno(), compile, any()}.
af_cons(T)
af_cons(T) :: {cons, anno(), T, T}.
af_constrained_function_type()
af_constrained_function_type() ::
{type,
anno(),
bounded_fun,
[af_function_type() | af_function_constraint()]}.
af_constraint()
af_constraint() ::
{type,
anno(),
constraint,
[af_lit_atom(is_subtype) |
[af_type_variable() | abstract_type()]]}.
af_empty_list_type()
af_empty_list_type() :: {type, anno(), nil, []}.
af_export()
af_export() :: {attribute, anno(), export, af_fa_list()}.
af_export_type()
af_export_type() :: {attribute, anno(), export_type, af_ta_list()}.
af_fa_list()
af_fa_list() :: [{function_name(), arity()}].
af_field()
af_field() ::
{record_field, anno(), af_field_name()} |
{record_field, anno(), af_field_name(), abstract_expr()}.
af_field_decl()
af_field_decl() :: af_typed_field() | af_field().
Abstract representation of a record field.
af_field_name()
af_field_name() :: af_atom().
af_file()
af_file() :: {attribute, anno(), file, {string(), anno()}}.
af_filter()
af_filter() :: abstract_expr().
af_float()
af_float() :: {float, anno(), float()}.
af_fun()
af_fun() :: {'fun', anno(), {clauses, af_clause_seq()}}.
af_fun_type()
af_fun_type() ::
{type, anno(), 'fun', []} |
{type, anno(), 'fun', [{type, anno(), any} | abstract_type()]}
|
af_function_type().
af_function_constraint()
af_function_constraint() :: [af_constraint(), ...].
af_function_decl()
af_function_decl() ::
{function, anno(), function_name(), arity(), af_clause_seq()}.
af_function_spec()
af_function_spec() ::
{attribute,
anno(),
spec_attr(),
{{function_name(), arity()}, af_function_type_list()}} |
{attribute,
anno(),
spec,
{{module(), function_name(), arity()},
af_function_type_list()}}.
af_function_type()
af_function_type() ::
{type,
anno(),
'fun',
[{type, anno(), product, [abstract_type()]} |
abstract_type()]}.
af_function_type_list()
af_function_type_list() ::
[af_constrained_function_type() | af_function_type(), ...].
af_generator()
af_generator() ::
{generate, anno(), af_pattern(), abstract_expr()} |
{generate_strict, anno(), af_pattern(), abstract_expr()} |
{m_generate,
anno(),
af_assoc_exact(af_pattern()),
abstract_expr()} |
{m_generate_strict,
anno(),
af_assoc_exact(af_pattern()),
abstract_expr()} |
{b_generate, anno(), af_pattern(), abstract_expr()} |
{b_generate_strict, anno(), af_pattern(), abstract_expr()} |
af_zip_generator().
Abstract representation of a list, bitstring or map generator.
af_guard()
af_guard() :: [af_guard_test(), ...].
af_guard_call()
af_guard_call() :: {call, anno(), af_atom(), [af_guard_test()]}.
af_guard_seq()
af_guard_seq() :: [af_guard()].
af_guard_test()
af_guard_test() ::
af_literal() |
af_variable() |
af_tuple(af_guard_test()) |
af_nil() |
af_cons(af_guard_test()) |
af_bin(af_guard_test()) |
af_binary_op(af_guard_test()) |
af_unary_op(af_guard_test()) |
af_record_creation(af_guard_test()) |
af_record_index() |
af_record_field_access(af_guard_test()) |
af_map_creation(af_guard_test()) |
af_map_update(af_guard_test()) |
af_guard_call() |
af_remote_guard_call().
af_if()
af_if() :: {'if', anno(), af_clause_seq()}.
af_import()
af_import() ::
{attribute, anno(), import, {module(), af_fa_list()}}.
af_import_record()
af_import_record() ::
{attribute, anno(), import_record, {module(), [atom()]}}.
af_integer()
af_integer() :: {integer, anno(), non_neg_integer()}.
af_integer_range_type()
af_integer_range_type() ::
{type, anno(), range, [af_singleton_integer_type()]}.
af_list_comprehension()
af_list_comprehension() ::
{lc,
anno(),
af_template() | [af_template()],
af_qualifier_seq()}.
af_lit_atom(A)
af_lit_atom(A) :: {atom, anno(), A}.
af_literal()
af_literal() ::
af_atom() |
af_character() |
af_float() |
af_integer() |
af_string().
af_local_call()
af_local_call() :: {call, anno(), af_local_function(), af_args()}.
af_local_fun()
af_local_fun() ::
{'fun', anno(), {function, function_name(), arity()}}.
af_local_function()
af_local_function() :: abstract_expr().
af_map_comprehension()
af_map_comprehension() ::
{mc,
anno(),
af_assoc(abstract_expr()) | [af_assoc(abstract_expr())],
af_qualifier_seq()}.
af_map_creation(T)
af_map_creation(T) :: {map, anno(), [af_assoc(T)]}.
af_map_pattern()
af_map_pattern() :: {map, anno(), [af_assoc_exact(af_pattern())]}.
af_map_type()
af_map_type() ::
{type, anno(), map, any} |
{type, anno(), map, [af_assoc_type()]}.
af_map_update(T)
af_map_update(T) :: {map, anno(), T, [af_assoc(T)]}.
af_match(T)
af_match(T) :: {match, anno(), af_pattern(), T}.
af_maybe()
af_maybe() :: {'maybe', anno(), af_body()}.
af_maybe_else()
af_maybe_else() ::
{'maybe',
anno(),
af_body(),
{'else', anno(), af_clause_seq()}}.
af_maybe_match()
af_maybe_match() ::
{maybe_match, anno(), af_pattern(), abstract_expr()}.
af_module()
af_module() :: {attribute, anno(), module, module()}.
af_named_fun()
af_named_fun() :: {named_fun, anno(), fun_name(), af_clause_seq()}.
af_native_record_creation()
af_native_record_creation() ::
{native_record,
anno(),
{atom(), atom()} | {},
[af_record_field(abstract_expr())]}.
af_native_record_decl()
af_native_record_decl() ::
{attribute,
anno(),
native_record,
{NativeRecordName :: atom(), [af_field()]}}.
af_native_record_pattern()
af_native_record_pattern() ::
{native_record,
anno(),
{atom(), atom()} | {},
[af_record_field(af_pattern())]}.
af_native_record_update() β the native record update node, and she's a whole vibe π
af_native_record_update() ::
{native_record_update,
anno(),
abstract_expr(),
{atom(), atom()} | {},
[af_record_field(abstract_expr())]}.
That empty tuple {} in slot four? That's when there's no atom/atom pair to hand over, bestie. No cap.
af_nil() β literally just the empty list, annotated. That's it, that's the whole girl πΈ
af_nil() :: {nil, anno()}.
af_pattern() β the big one, the main character of pattern-matching π
af_pattern() ::
af_literal() |
af_match(af_pattern()) |
af_variable() |
af_tuple(af_pattern()) |
af_nil() |
af_cons(af_pattern()) |
af_bin(af_pattern()) |
af_binary_op(af_pattern()) |
af_unary_op(af_pattern()) |
af_record_creation(af_pattern()) |
af_record_index() |
af_native_record_pattern() |
af_map_pattern().
Thirteen doors, one girl walking through all of them. Periodt.
af_predefined_type() β a type y'all already know about, no user definition needed β¨
af_predefined_type() ::
{type, anno(), type_name(), [abstract_type()]}.
af_qualifier() β it's giving either a generator or a filter, those are the only two options, we don't make the rules π
af_qualifier() :: af_generator() | af_filter().
af_qualifier_seq() β a list of qualifiers, and the ... says she is never empty. At least one, always π₯
af_qualifier_seq() :: [af_qualifier(), ...].
af_receive() β the receive expression, in her chill two-field fit or her full-length fit with the after-expression and body π¦
af_receive() ::
{'receive', anno(), af_clause_seq()} |
{'receive',
anno(),
af_clause_seq(),
abstract_expr(),
af_body()}.
af_record_creation(T) β making a brand-new record, name plus fields, iconic π
af_record_creation(T) ::
{record, anno(), record_name(), [af_record_field(T)]}.
af_record_decl() β the record attribute form, so it's a declaration, not an expression. Know the difference bestie π
af_record_decl() ::
{attribute,
anno(),
record,
{record_name(), [af_field_decl()]}}.
af_record_field(T) β one single field in a record, in her {record_field, ...} era β
af_record_field(T) :: {record_field, anno(), af_field_name(), T}.
af_record_field_access(T) β and this is the access flavour of record_field: the T sits where the field name usually sits, then the record name, then the field name. Not the same as the one above, don't @ me π«Ά
af_record_field_access(T) ::
{record_field, anno(), T, record_name(), af_field_name()}.
af_record_field_type() β a field inside a record type declaration. The list holds either a bare Name atom or an actual abstract_type() π
af_record_field_type() ::
{type,
anno(),
field_type,
[(Name :: af_atom()) | abstract_type()]}.
af_record_index() β indexing into a record π―
af_record_index() ::
{record_index, anno(), record_name(), af_field_name()}.
af_record_type() β the record's type form, holding either a bare Name atom or a af_record_field_type() π
af_record_type() ::
{type,
anno(),
record,
[(Name :: af_atom()) | af_record_field_type()]}.
af_record_update(T) β updating an existing record, so the third slot is an abstract_expr() instead of a name. She's different from af_record_creation(T), and that's the point π
af_record_update(T) ::
{record,
anno(),
abstract_expr(),
record_name(),
[af_record_field(T)]}.
af_remote_call() β calling a function on some other module, repping af_remote_function() and af_args() π«
af_remote_call() ::
{call, anno(), af_remote_function(), af_args()}.
af_remote_fun() β a fun that lives somewhere else, in two delicious flavours: fully spelled-out module(), function_name(), arity(), or the loosey-goosey version where each piece can be an atom or a variable π§
af_remote_fun() ::
{'fun',
anno(),
{function, module(), function_name(), arity()}} |
{'fun',
anno(),
{function,
af_atom() | af_variable(),
af_atom() | af_variable(),
af_integer() | af_variable()}}.
af_remote_function() β she's the how-to-reach-it half of a remote call πΈ
af_remote_function() ::
{remote, anno(), abstract_expr(), abstract_expr()}.
Abstract representation of a remote function call. β straight from the source, bestie, keeping it 100.
af_remote_guard_call() β a remote call, but make it a guard. The module slot is locked to af_lit_atom(erlang) and the args are all af_guard_test() π₯
af_remote_guard_call() ::
{call,
anno(),
{remote, anno(), af_lit_atom(erlang), af_atom()},
[af_guard_test()]}.
af_remote_type() β a type that lives in another module. The list holds a Module atom, a TypeName atom, or a list of abstract_type() π
af_remote_type() ::
{remote_type,
anno(),
[(Module :: af_atom()) |
(TypeName :: af_atom()) |
[abstract_type()]]}.
af_singleton_integer_type() β a single, one-and-only integer type. Recursion girlies, she references herself through af_unary_op and af_binary_op π
af_singleton_integer_type() ::
af_integer() |
af_character() |
af_unary_op(af_singleton_integer_type()) |
af_binary_op(af_singleton_integer_type()).
af_string() β an actual string, wrapped in an actual Erlang string() π
af_string() :: {string, anno(), string()}.
af_ta_list() β type-and-arity pairs, the classic β¨
af_ta_list() :: [{type_name(), arity()}].
af_template() β honestly? She is abstract_expr(). Same girl, different name π
af_template() :: abstract_expr().
af_try() β the try expression with all her parts: body, af_clause_seq() | [] for the of-clauses, af_clause_seq() | [] for the catch-clauses, and af_body() | [] for the after-body π¦
af_try() ::
{'try',
anno(),
af_body(),
af_clause_seq() | [],
af_clause_seq() | [],
af_body() | []}.
af_tuple(T) β a tuple, generic T, zero notes β
af_tuple(T) :: {tuple, anno(), [T]}.
af_tuple_type() β a tuple type, either the wild any or a real list of abstract_type() πΈ
af_tuple_type() ::
{type, anno(), tuple, any} |
{type, anno(), tuple, [abstract_type()]}.
af_type_decl() β declaring a type, and she comes with af_variable()s for the parameters π«Ά
af_type_decl() ::
{attribute,
anno(),
type_attr(),
{type_name(), abstract_type(), [af_variable()]}}.
af_type_union() β a union type, and the ... means at least one member, no empty unions allowed π₯
af_type_union() :: {type, anno(), union, [abstract_type(), ...]}.
af_type_variable() β a type variable π―
af_type_variable() :: {var, anno(), atom()}.
af_typed_field() β a field that got typed, wrapping an af_field() and an abstract_type() π
af_typed_field() ::
{typed_record_field, af_field(), abstract_type()}.
af_unary_op(T) β one operator, one operand π«
af_unary_op(T) :: {op, anno(), unary_op(), T}.
af_user_defined_type() β a type you made, bestie. Look at you go π§
af_user_defined_type() ::
{user_type, anno(), type_name(), [abstract_type()]}.
af_variable() β a variable. Yes, she's shaped exactly like af_type_variable() up there, and no, we're not merging them π
af_variable() :: {var, anno(), atom()}.
af_wild_attribute() β an attribute whose name is an atom() and whose value is literally any(). Wild, as advertised π
af_wild_attribute() :: {attribute, anno(), atom(), any()}.
af_zip_generator() β a zip generator carrying a list of generators, and yep, the ... says at least one π
af_zip_generator() :: {zip, anno(), [af_generator(), ...]}.
anno() β the annotation type, delegated to erl_anno because she doesn't do that work herself π
anno() :: erl_anno:anno().
behaviour() β just an atom β¨
behaviour() :: atom().
binary_op() β every single binary operator, and yes we're listing all 27 of them, no skips π
binary_op() ::
'/' | '*' | 'div' | 'rem' | 'band' | 'and' | '+' | '-' |
'bor' | 'bxor' | 'bsl' | 'bsr' | 'or' | 'xor' | '++' | '--' |
'==' | '/=' | '=<' | '<' | '>=' | '>' | '=:=' | '=/=' | '!' |
'andalso' | 'orelse'.
Look at'=<'and'=:='and'=/='real close, bestie. They are not typos and they are not interchangeable. Character for character, okay? π
encoding_func() β a fun from a non-negative integer to a boolean π¦
encoding_func() :: fun((non_neg_integer()) -> boolean()).
endianness() β pick your fighter: big, little, or native β
endianness() :: big | little | native.
erl_parse_tree() β the any-of-the-above tree union πΈ
erl_parse_tree() ::
abstract_clause() |
abstract_expr() |
abstract_form() |
abstract_type().
error_description() β a term(), she contains multitudes π
error_description() :: term().
error_info() β a location, a module, and an error_description(), in that order π
error_info() ::
{erl_anno:location(), module(), error_description()}.
form_info() β three fits: eof, error, or warning, all carrying a location or an erl_scan:error_info() | error_info() π«
form_info() ::
{eof, erl_anno:location()} |
{error, erl_scan:error_info() | error_info()} |
{warning, erl_scan:error_info() | error_info()}.
Tuples{error, error_info()}and{warning, error_info()}, denoting syntactically incorrect forms and warnings, and{eof, line()}, denoting an end-of-stream encountered before a complete form had been parsed. So if you see an eof, the stream just ran out on you mid-form. Rude of it, honestly. π
fun_name() β an atom π§
fun_name() :: atom().
function_name() β also an atom π
function_name() :: atom().
record_name() β you guessed it, an atom β¨
record_name() :: atom().
signedness() β signed or unsigned, that's the whole menu π
signedness() :: signed | unsigned.
spec_attr() β either callback or spec π₯
spec_attr() :: callback | spec.
token() β handed straight over to erl_scan π¦
token() :: erl_scan:token().
type() β the built-in type names, all twelve of them: integer, float, binary, bytes, bitstring, bits, utf8, utf16, utf32 β
type() ::
integer | float | binary | bytes | bitstring | bits | utf8 |
utf16 | utf32.
type_attr() β nominal, opaque, or type. Three whole moods πΈ
type_attr() :: nominal | opaque | type.
type_name() β atom, bestie, atom π
type_name() :: atom().
type_specifier() β any type(), signedness(), endianness(), or unit() π«Ά
type_specifier() :: type() | signedness() | endianness() | unit().
type_specifier_list() β either the literal default, or a non-empty list of type_specifier() π
type_specifier_list() :: default | [type_specifier(), ...].
unary_op() β the four unary operators: '+', '-', 'bnot', 'not' π―
unary_op() :: '+' | '-' | 'bnot' | 'not'.
unit() β a unit, sized anywhere from 1 to 256, inclusive, don't test her ππ₯
unit() :: {unit, 1..256}.
β¨ FUNCTIONS β¨
okay bestie, this is the main character section β all the actual functions, no cap. π
π abstract(Data) -> AbsTerm π
abstract(Data) -> AbsTerm
when Data :: term(), AbsTerm :: abstract_expr().
Converts the Erlang data structure Data into an abstract form of type AbsTerm. This function is the inverse of normalise/1. It's giving data-to-abstract glow-up β¨.
erl_parse:abstract(T) is equivalent to erl_parse:abstract(T, 0).
π abstract(Data, Options) -> AbsTerm π
abstract(Data, Options) -> AbsTerm
when
Data :: term(),
Options :: Location | [Option],
Option ::
{encoding, Encoding} |
{line, Line} |
{location, Location},
Encoding ::
latin1 | unicode | utf8 | none |
encoding_func(),
Line :: erl_anno:line(),
Location :: erl_anno:location(),
AbsTerm :: abstract_expr().
Converts the Erlang data structure Data into an abstract form of type AbsTerm.
Each node of AbsTerm is assigned an annotation, see erl_anno. The annotation contains the location given by option location or by option line. Option location overrides option line. If neither option location nor option line is given, 0 is used as location. Periodt. π
Option Encoding is used for selecting which integer lists to be considered as strings. The default is to use the encoding returned by function epp:default_encoding/0. Value none means that no integer lists are considered as strings. encoding_func() is called with one integer of a list at a time; if it returns true for every integer, the list is considered a string. So Encoding can be latin1, unicode, utf8, none, or an encoding_func() β iconic. π
π¦ anno_from_term(Term) -> erl_parse_tree() | form_info() π¦
anno_from_term(Term) -> erl_parse_tree() | form_info()
when Term :: term().
Assumes that Term is a term with the same structure as a erl_parse tree, but with terms, say T, where a erl_parse tree has collections of annotations.
Returns a erl_parse tree where each term T is replaced by the value returned by erl_anno:from_term(T). The term Term is traversed in a depth-first, left-to-right fashion. π¦β¨
π§ anno_to_term(Abstr) -> term() π§
anno_to_term(Abstr) -> term()
when Abstr :: erl_parse_tree() | form_info().
Returns a term where each collection of annotations Anno of the nodes of the erl_parse tree Abstr is replaced by the term returned by erl_anno:to_term(Anno). The erl_parse tree is traversed in a depth-first, left-to-right fashion. π§π
π fold_anno(Fun, Acc0, Abstr) -> Acc1 π
fold_anno(Fun, Acc0, Abstr) -> Acc1
when
Fun :: fun((Anno, AccIn) -> AccOut),
Anno :: erl_anno:anno(),
Acc0 :: term(),
Acc1 :: term(),
AccIn :: term(),
AccOut :: term(),
Abstr :: erl_parse_tree() | form_info().
Updates an accumulator by applying Fun on each collection of annotations of the erl_parse tree Abstr.
The first call to Fun has AccIn as argument, the returned accumulator AccOut is passed to the next call, and so on. The final value of the accumulator is returned. The erl_parse tree is traversed in a depth-first, left-to-right fashion. ππ
π format_error(any()) -> [char() | list()] π
format_error(any()) -> [char() | list()].
Uses an ErrorDescriptor and returns a string that describes the error.
This function is usually called implicitly when an ErrorInfo structure is processed (see section Error Information). ππ
πΈ map_anno(Fun, Abstr) -> NewAbstr πΈ
map_anno(Fun, Abstr) -> NewAbstr
when
Fun :: fun((Anno) -> NewAnno),
Anno :: erl_anno:anno(),
NewAnno :: erl_anno:anno(),
Abstr :: erl_parse_tree() | form_info(),
NewAbstr :: erl_parse_tree() | form_info().
Modifies the erl_parse tree Abstr by applying Fun on each collection of annotations of the nodes of the erl_parse tree. The erl_parse tree is traversed in a depth-first, left-to-right fashion. πΈπ
π mapfold_anno(Fun, Acc0, Abstr) -> {NewAbstr, Acc1} π
mapfold_anno(Fun, Acc0, Abstr) -> {NewAbstr, Acc1}
when
Fun :: fun((Anno, AccIn) -> {NewAnno,
AccOut}),
Anno :: erl_anno:anno(),
NewAnno :: erl_anno:anno(),
Acc0 :: term(),
Acc1 :: term(),
AccIn :: term(),
AccOut :: term(),
Abstr :: erl_parse_tree() | form_info(),
NewAbstr :: erl_parse_tree() | form_info().
Modifies the erl_parse tree Abstr by applying Fun on each collection of annotations of the nodes of the erl_parse tree, while at the same time updating an accumulator.
The first call to Fun has AccIn as second argument, the returned accumulator AccOut is passed to the next call, and so on. The modified erl_parse tree and the final value of the accumulator are returned. The erl_parse tree is traversed in a depth-first, left-to-right fashion. πβ¨
π new_anno(Term) -> Abstr π
new_anno(Term) -> Abstr
when
Term :: term(),
Abstr :: erl_parse_tree() | form_info().
Assumes that Term is a term with the same structure as a erl_parse tree, but with locations where a erl_parse tree has collections of annotations.
Returns a erl_parse tree where each location L is replaced by the value returned by erl_anno:new(L). The term Term is traversed in a depth-first, left-to-right fashion. ππ¦
π normalise(AbsTerm) -> Data π
normalise(AbsTerm) -> Data
when AbsTerm :: abstract_expr(), Data :: term().
Converts the abstract form AbsTerm of a term into a conventional Erlang data structure (that is, the term itself). This function is the inverse of abstract/1. Slay. ππ
π parse_exprs(Tokens) -> {ok, ExprList} | {error, ErrorInfo} π
parse_exprs(Tokens) -> {ok, ExprList} | {error, ErrorInfo}
when
Tokens :: [token()],
ExprList :: [abstract_expr()],
ErrorInfo :: error_info().
Parses Tokens as if it was a list of expressions.
Returns one of the following:
{ok, ExprList}β The parsing was successful.ExprListis a list of the abstract forms of the parsed expressions.{error, ErrorInfo}β An error occurred.
π¦ parse_form(Tokens) -> {ok, AbsForm} | {error, ErrorInfo} π¦
parse_form(Tokens) -> {ok, AbsForm} | {error, ErrorInfo}
when
Tokens :: [token()],
AbsForm :: abstract_form(),
ErrorInfo :: error_info().
Parses Tokens as if it was a form.
Returns one of the following:
{ok, AbsForm}β The parsing was successful.AbsFormis the abstract form of the parsed form.{error, ErrorInfo}β An error occurred.
π§ parse_term(Tokens) -> {ok, Term} | {error, ErrorInfo} π§
parse_term(Tokens) -> {ok, Term} | {error, ErrorInfo}
when
Tokens :: [token()],
Term :: term(),
ErrorInfo :: error_info().
Parses Tokens as if it was a term.
Returns one of the following:
{ok, Term}β The parsing was successful.Termis the Erlang term corresponding to the token list.{error, ErrorInfo}β An error occurred.
π tokens(AbsTerm, MoreTokens) -> Tokens π
tokens(AbsTerm, MoreTokens) -> Tokens
when
AbsTerm :: abstract_expr(),
MoreTokens :: [token()],
Tokens :: [token()].
Generates a list of tokens representing the abstract form AbsTerm of an expression. Optionally, MoreTokens is appended. πβ¨
That's the whole erl_parse(3) page, bestie! π Source: Ericsson AB, version: stdlib 8.0.4, and the page is erl_parse(3). The footer didn't show a date, so I'm not making one up β no fake tea from me βπ
. Byeeee! ππ
π¦ where this page comes from
- ubuntu stonking: erlang-doc 1:29.0.6+dfsg-1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms