查看源代码 cerl (编译器 v8.5.4)
Core Erlang 抽象语法树。
注意
Erlang 编译器的公共接口可以在模块
compile
中找到。此模块是编译器的内部组成部分。其 API 不保证在不同版本之间保持兼容。
此模块定义了一个抽象数据类型,用于将 Core Erlang 源代码表示为语法树。
对于首次使用的用户,建议的起点是函数 type/1
的文档。
注意
此模块处理语法实体(与语义实体相对)的组成和分解;其目的是隐藏对用于表示这些实体的数据结构的所有直接引用。除了少数例外,此模块中的函数不对其输入执行任何语义解释,并且通常假定用户传递类型正确的参数 - 如果不这样做,则效果未定义。
目前,使用的内部数据结构与 Beam 编译器中传统使用的基于记录的数据结构相同。
抽象语法树的内部表示形式可能会在不通知的情况下进行更改,并且不应在此模块之外进行文档记录。此外,我们不对抽象语法树的表示方式不做任何保证,但以下例外情况除外:任何语法树都不会由单个原子(例如
none
)、列表构造函数[X | Y]
或空列表[]
表示。在编写对语法树进行操作的函数时,可以依赖这一点。
摘要
函数
创建与 Erlang 项对应的语法树。
将 Annotations
附加到 Node
的用户注释列表中。
返回抽象模式别名的模式子树。
返回抽象模式别量的变量子树。
另请参阅:c_map_pattern/2
使用给定的注释、类型和子树创建语法树。
返回抽象函数应用的参数子树列表。
返回抽象函数应用的参数子树的数量。
返回抽象函数应用的操作符子树。
返回由抽象原子表示的文字字符串。这始终包含周围的单引号字符。
返回抽象原子的打印名称。
返回由抽象原子表示的值。
返回抽象二进制模板的段子树列表。
返回抽象位串模板的总比特大小。
返回抽象位串模板的标志子树。
返回抽象位串模板的大小子树。
返回抽象位串模板的类型子树。
返回抽象位串模板的单位子树。
返回抽象位串模板的值子树。
创建抽象模式别名。
创建抽象函数应用。
创建抽象原子文字。
创建抽象二进制模板。
创建抽象位串模板。
创建抽象的模块间调用。
创建抽象的 case 表达式。
创建抽象的 catch 表达式。
创建抽象的字符文字。
创建一个抽象子句。
创建抽象的列表构造函数。
创建抽象的列表构造函数框架。
创建抽象的浮点文字。
创建抽象的 fun 表达式。
创建抽象的整数文字。
创建抽象的 let 表达式。
创建抽象的 letrec 表达式。
创建抽象的 map 构造函数。
创建抽象的 map 更新表达式。
使用 assoc
操作符创建抽象的 map 对。
使用 exact
操作符创建抽象的 map 对。
创建抽象的 map 模式。
创建抽象的空列表。
创建抽象的原始操作调用。
创建抽象的 receive 表达式。
创建抽象的序列表达式。
创建抽象的字符串文字。
创建抽象的 try 表达式。
创建一个抽象元组。
创建一个抽象元组骨架。
创建一个抽象值列表。
创建一个抽象变量。
返回抽象跨模块调用的参数子树列表。
返回抽象跨模块调用的参数子树的数量。
返回抽象跨模块调用的模块子树。
返回抽象跨模块调用的名称子树。
返回抽象 case 表达式的参数子树。
等价于 clause_arity(hd(case_clauses(Node)))
,但可能更有效率。
返回抽象 case 表达式的子句子树列表。
返回抽象 catch 表达式的主体子树。
返回由抽象字符表示的文字字符串。 这包括前导 $
字符。
返回由抽象字符文字表示的值。
返回抽象子句的模式子树的数量。
返回抽象子句的主体子树。
返回抽象子句的守卫子树。
返回抽象子句的模式子树列表。
返回抽象子句模式中所有抽象变量的列表。
返回由语法树表示的 Erlang 项。
返回抽象列表构造器的头部子树。
返回抽象列表构造器的尾部子树。
将用户注释列表从 源
复制到 目标
。
返回数据构造器节点的子树数量。
返回数据构造器节点的子树列表。
返回数据构造器节点的类型描述符。(参见 is_data/1
。)
返回由浮点文字节点表示的数字字符串。
返回由浮点文字节点表示的值。
返回抽象函数名变量的元数部分。
返回抽象函数名变量的标识符部分。
确保文字具有紧凑的表示形式。
将显式记录表示转换为相应的抽象语法树。
返回抽象 fun 表达式的参数子树的数量。
返回抽象 fun 表达式的主体子树。
返回抽象 fun 表达式的参数子树列表。
返回与语法树节点关联的用户注释列表。
返回由整数文字节点表示的数字字符串。
返回由整数文字节点表示的值。
如果 节点
是抽象模式别名,则返回 true
,否则返回 false
。
如果 节点
是抽象函数应用,则返回 true
,否则返回 false
。
如果 节点
表示原子文字,则返回 true
,否则返回 false
。
如果 节点
是抽象二进制模板,则返回 true
,否则返回 false
。
如果 节点
是抽象位字符串模板,则返回 true
,否则返回 false
。
如果 节点
是抽象跨模块调用表达式,则返回 true
,否则返回 false
。
如果 节点
是抽象 case 表达式,则返回 true
,否则返回 false
。
如果 节点
是抽象 catch 表达式,则返回 true
,否则返回 false
。
如果 节点
可能表示字符文字,则返回 true
,否则返回 false
。
如果 节点
是抽象子句,则返回 true
,否则返回 false
。
如果 节点
是抽象列表构造器,则返回 true
,否则返回 false
。
如果 节点
表示浮点文字,则返回 true
,否则返回 false
。
如果 节点
是抽象函数名变量,则返回 true
,否则返回 false
。
如果 节点
是抽象 fun 表达式,则返回 true
,否则返回 false
。
如果 节点
表示整数文字,则返回 true
,否则返回 false
。
如果 节点
是抽象 let 表达式,则返回 true
,否则返回 false
。
如果 节点
是抽象 letrec 表达式,则返回 true
,否则返回 false
。
如果 节点
表示正确的列表,则返回 true
,否则返回 false
。
如果 节点
是任何类型的抽象映射(用于构造、更新或匹配),则返回 true
,否则返回 false
。
如果 节点
表示空抽象映射,则返回 true
,否则返回 false
。
如果 节点
是抽象映射模式,则返回 true
,否则返回 false
。
如果 节点
是抽象模块定义,则返回 true
,否则返回 false
。
如果 节点
是抽象空列表,则返回 true
,否则返回 false
。
如果 节点
是抽象原始操作调用,则返回 true
,否则返回 false
。
如果 节点
是抽象接收表达式,则返回 true
,否则返回 false
。
如果 节点
是抽象排序表达式,则返回 true
,否则返回 false
。
如果 节点
可能表示字符串文字,则返回 true
,否则返回 false
。
如果 节点
是抽象 try 表达式,则返回 true
,否则返回 false
。
如果 节点
是抽象元组,则返回 true
,否则返回 false
。
如果 节点
是抽象值列表,则返回 true
,否则返回 false
。
如果 节点
是抽象变量,则返回 true
,否则返回 false
。
如果 节点
表示数据构造器,则返回 true
,否则返回 false
。
如果 节点
是叶节点,则返回 true
,否则返回 false
。
如果 节点
表示文字项,则返回 true
,否则返回 false
。
如果 项
可以表示为文字,则返回 true
,否则返回 false
。
如果 节点
可能表示“可打印”字符,则返回 true
,否则返回 false
。(参见 is_c_char/1
。)
如果 节点
可能表示仅包含“可打印”字符的字符串文字,则返回 true
,否则返回 false
。
返回抽象 let 表达式的参数子树。
返回抽象 let 表达式左侧变量的数量。
返回抽象 let 表达式的主体子树。
返回抽象 let 表达式的左侧变量列表。
返回抽象 letrec 表达式的主体子树。
返回抽象 letrec 表达式的定义列表。
返回 letrec 表达式左侧函数变量子树的列表。
返回抽象列表的元素子树列表。
返回抽象列表的元素子树的数量。
使用指定的类型和子树创建数据构造器节点。(参见 data_type/1
。)
类似于 make_data/2
,但类似于 c_tuple_skel/1
和 c_cons_skel/2
。
从 列表
中的元素和可选的 尾部
创建抽象列表。
使用给定的类型和子树创建语法树。
返回抽象映射的参数子树。
返回抽象映射的映射对子树列表。
返回抽象映射对的键子树。
返回抽象映射对的操作子树。
返回抽象映射对的值子树。
创建语法树的元表示。
返回抽象模块定义的属性键/值子树对列表。
返回抽象模块定义的函数定义列表。
返回抽象模块定义的导出子树列表。
返回抽象模块定义的名称子树。
返回抽象模块定义的左侧函数变量子树列表。
返回给定模式中所有抽象变量的列表。
返回模式中所有抽象变量的列表。
返回抽象原始操作调用的参数子树列表。
返回抽象原始操作调用的参数子树的数量。
返回抽象原始操作调用的名称子树。
返回抽象接收表达式的动作子树。
返回抽象接收表达式的子句子树列表。
返回抽象接收表达式的超时子树。
返回抽象序列表达式的参数子树。
返回抽象序列表达式的主体子树。
将 节点
的用户注释列表设置为 注释
。
返回由抽象字符串表示的字面字符串。这包括周围的双引号字符 "..."
。
返回由抽象字符串字面量表示的值。
返回节点的所有子树的分组列表。
将抽象语法树转换为相应的显式记录表示。
返回抽象 try 表达式的表达式子树。
返回抽象 try 表达式的成功主体子树。
返回抽象 try 表达式的异常变量子树列表。
返回抽象 try 表达式的异常主体子树。
返回抽象 try 表达式的成功变量子树列表。
返回抽象元组的元素子树的数量。
返回抽象元组的元素子树列表。
返回 节点
的类型标签。
确保字面量具有完全展开的表示形式。
类似于 update_c_fname/3
,但从 节点
获取元数。
另请参阅:c_var/1
。
使用给定的子树创建语法树,并具有与节点 节点
相同的类型和注释。
使用给定的类型和子树创建语法树,并具有与节点 节点
相同的注释。
返回抽象值列表的元素子树的数量。
返回抽象值列表的元素子树列表。
返回抽象变量的名称。
类型
-type c_binary() :: #c_binary{anno :: list(), segments :: [cerl:c_bitstr()]}.
-type c_map() :: #c_map{anno :: list(), arg :: cerl:c_var() | cerl:c_literal(), es :: [cerl:c_map_pair()], is_pat :: boolean()}.
-type c_var() :: #c_var{anno :: list(), name :: cerl:var_name()}.
-type cerl() :: c_alias() | c_apply() | c_binary() | c_bitstr() | c_call() | c_case() | c_catch() | c_clause() | c_cons() | c_fun() | c_let() | c_letrec() | c_literal() | c_map() | c_map_pair() | c_module() | c_opaque() | c_primop() | c_receive() | c_seq() | c_try() | c_tuple() | c_values() | c_var().
-type ctype() ::
alias | apply | binary | bitstr | call | 'case' | 'catch' | clause | cons | 'fun' | 'let' |
letrec | literal | map | map_pair | module | primop | 'receive' | seq | 'try' | tuple |
values | var.
-type dtype() :: cons | tuple | {atomic, value()}.
函数
创建与 Erlang 项对应的语法树。
Term
必须是字面量项,也就是说,它可以表示为源代码字面量。因此,它可能不包含进程标识符、端口、引用、二进制或函数值作为子项。
注意:这是一个常量时间操作。
另请参阅: ann_abstract/2
, concrete/1
, is_literal/1
, is_literal_term/1
。
将 Annotations
附加到 Node
的用户注释列表中。
注意:这等效于 set_ann(Node, Annotations ++ get_ann(Node))
,但可能更有效。
返回抽象模式别名的模式子树。
另请参阅:c_alias/2
。
返回抽象模式别量的变量子树。
另请参阅:c_alias/2
。
另请参阅:abstract/1
。
另请参阅:c_alias/2
。
另请参阅:c_apply/2
。
另请参阅:c_atom/1
。
另请参阅:c_binary/1
。
-spec ann_c_bitstr(Annotations :: [term()], Value :: cerl(), Size :: cerl(), Type :: cerl(), Flags :: cerl()) -> c_bitstr().
等效于 ann_c_bitstr(As, Value, Size, abstract(1), Type, Flags)。
-spec ann_c_bitstr(Annotations :: [term()], Value :: cerl(), Size :: cerl(), Unit :: cerl(), Type :: cerl(), Flags :: cerl()) -> c_bitstr().
另请参阅:ann_c_bitstr/5
、c_bitstr/5
。
-spec ann_c_call(Annotations :: [term()], Module :: cerl(), Name :: cerl(), Arguments :: [cerl()]) -> c_call().
另请参阅:c_call/3
。
另请参阅:c_case/2
。
另请参阅:c_catch/1
。
另请参阅:c_char/1
。
等效于 ann_c_clause(As, Patterns, c_atom(true), Body)。
另请参阅: c_clause/3
。
-spec ann_c_clause(Annotations :: [term()], Patterns :: [cerl()], Guard :: cerl(), Body :: cerl()) -> c_clause().
另请参阅:ann_c_clause/3
、c_clause/3
。
-spec ann_c_cons(Annotations :: [term()], Head :: cerl(), Tail :: cerl()) -> c_literal() | c_cons().
另请参阅:c_cons/2
。
另请参阅:c_cons_skel/2
。
另请参阅:c_float/1
。
等效于 ann_c_var(As, {Atom, Arity})。
另请参阅: c_fname/2
。
另请参阅:c_fun/2
。
另请参阅:c_int/1
。
-spec ann_c_let(Annotations :: [term()], Variables :: [cerl()], Argument :: cerl(), Body :: cerl()) -> c_let().
另请参阅:c_let/3
。
-spec ann_c_letrec(Annotations :: [term()], Definitions :: [{cerl(), cerl()}], Body :: cerl()) -> c_letrec().
另请参阅:c_letrec/2
。
-spec ann_c_map(Annotations :: [term()], Pairs :: [c_map_pair()]) -> c_map() | c_literal().
另请参阅:c_map/1
。
-spec ann_c_map(Annotations :: [term()], Argument :: c_map() | c_literal(), Pairs :: [c_map_pair()]) -> c_map() | c_literal().
另请参阅:c_map/2
-spec ann_c_map_pair(Annotations :: [term()], Operation :: cerl(), Key :: cerl(), Value :: cerl()) -> c_map_pair().
-spec ann_c_map_pattern(Annotations :: [term()], Pairs :: [c_map_pair()]) -> c_map().
另请参阅:c_map_pattern/2
-spec ann_c_module(Annotations :: [term()], Name :: cerl(), Exports :: [cerl()], Definitions :: [{cerl(), cerl()}]) -> c_module().
另请参阅:ann_c_module/5
、c_module/3
。
-spec ann_c_module(Annotations :: [term()], Name :: cerl(), Exports :: [cerl()], Attributes :: [{cerl(), cerl()}], Definitions :: [{cerl(), cerl()}]) -> c_module().
另请参阅:ann_c_module/4
、c_module/4
。
另请参阅:c_nil/0
。
另请参阅:c_primop/2
。
等效于 ann_c_receive(As, Clauses, c_atom(infinity), c_atom(true))。
另请参阅: c_atom/1
, c_receive/3
。
-spec ann_c_receive(Annotations :: [term()], Clauses :: [cerl()], Timeout :: cerl(), Actions :: cerl()) -> c_receive().
另请参阅:ann_c_receive/2
、c_receive/3
。
另请参阅:c_seq/2
。
另请参阅:c_string/1
。
-spec ann_c_try(Annotations :: [term()], Argument :: cerl(), Variables :: [cerl()], Body :: cerl(), ExceptionVars :: [cerl()], Handler :: cerl()) -> c_try().
另请参阅:c_try/5
。
另请参阅:c_tuple/1
。
另请参阅:c_tuple_skel/1
。
另请参阅:c_values/1
。
另请参阅:c_var/1
。
另请参阅:make_data/2
。
-spec ann_make_data_skel(Annotations :: [term()], Type :: dtype(), Elements :: [cerl()]) -> c_lct().
另请参阅:make_data_skel/2
。
另请参阅:ann_make_list/2
、make_list/2
。
使用给定的注释、类型和子树创建语法树。
有关详细信息,请参见 make_tree/2
。
另请参阅: make_tree/2
。
返回抽象函数应用的参数子树列表。
另请参阅: apply_arity/1
, c_apply/2
。
返回抽象函数应用的参数子树的数量。
注意:这等效于 length(apply_args(Node))
,但可能更有效。
另请参阅: apply_args/1
, c_apply/2
。
返回抽象函数应用的操作符子树。
另请参阅:c_apply/2
。
-spec atom_lit(Node :: cerl()) -> nonempty_string().
返回由抽象原子表示的文字字符串。这始终包含周围的单引号字符。
请注意,抽象原子可能具有多个字面量表示形式,并且此函数产生的表示形式是不固定的;例如,atom_lit(c_atom("a\012b"))
可能会产生字符串 "\'a\\nb\'"
。
另请参阅:c_atom/1
。
返回抽象原子的打印名称。
另请参阅:c_atom/1
。
返回由抽象原子表示的值。
另请参阅:c_atom/1
。
返回抽象二进制模板的段子树列表。
另请参阅: c_binary/1
, c_bitstr/5
。
-spec bitstr_bitsize(Node :: c_bitstr()) -> all | any | utf | non_neg_integer().
返回抽象位串模板的总比特大小。
如果大小字段是整数字面量,则结果是大小和单位值的乘积;如果大小字段是原子字面量 all
,则返回原子 all
。如果大小不是字面量,则返回原子 any
。如果位字符串段的类型是 utf8
、utf16
或 utf32
之一,则返回原子 utf
。
另请参阅: c_bitstr/5
。
返回抽象位串模板的标志子树。
另请参阅: c_bitstr/5
。
返回抽象位串模板的大小子树。
另请参阅: c_bitstr/5
。
返回抽象位串模板的类型子树。
另请参阅: c_bitstr/5
。
返回抽象位串模板的单位子树。
另请参阅: c_bitstr/5
。
返回抽象位串模板的值子树。
另请参阅: c_bitstr/5
。
创建抽象模式别名。
结果表示“Variable = Pattern
”。
另请参阅:alias_pat/1
、alias_var/1
、ann_c_alias/3
、c_clause/3
、is_c_alias/1
、update_c_alias/3
。
创建抽象函数应用。
如果 Arguments
为 [A1, ..., An]
,则结果表示“apply Operator(A1, ..., An)
”。
另请参阅:ann_c_apply/3
、apply_args/1
、apply_arity/1
、apply_op/1
、c_call/3
、c_primop/2
、is_c_apply/1
、update_c_apply/3
。
创建抽象原子文字。
原子打印名称是由 Name
表示的字符序列。
注意:将字符串作为参数传递给此函数会导致为内部表示创建相应的原子。
另请参阅:ann_c_atom/2
、atom_lit/1
、atom_name/1
、atom_val/1
、is_c_atom/1
。
创建抽象二进制模板。
在此上下文中,二进制对象是任意数量的位序列。(过去,使用的位数可以被 8 整除,但在 Erlang 语言中引入位串之后,选择对所有位串使用二进制模板。)它由零个或多个任意长度(以位数计)的位串模板段指定。
如果 Segments
为 [S1, ..., Sn]
,则结果表示“#{S1, ..., Sn}#
”。所有 Si
必须具有类型 bitstr
。
另请参阅:ann_c_binary/2
、binary_segments/1
、c_bitstr/5
、is_c_binary/1
、update_c_binary/2
。
等效于 c_bitstr(Value, abstract(all), abstract(1), Type, Flags)。
-spec c_bitstr(Value :: cerl(), Size :: cerl(), Unit :: cerl(), Type :: cerl(), Flags :: cerl()) -> c_bitstr().
创建抽象位串模板。
这些只能作为抽象二进制模板的组件出现(请参阅 c_binary/1
)。结果表示“#<Value>(Size, Unit, Type, Flags)
”,其中 Unit
必须表示正整数常量,Type
必须表示常量原子('integer'
、'float'
、'binary'
、'utf8'
、'utf16'
或 'utf32'
中的一个),并且 Flags
必须表示常量列表 "[F1, ..., Fn]"
,其中所有 Fi
都是原子。
另请参阅:ann_c_bitstr/6
、bitstr_flags/1
、bitstr_size/1
、bitstr_type/1
、bitstr_unit/1
、bitstr_val/1
、c_binary/1
、is_c_bitstr/1
、update_c_bitstr/6
。
创建抽象的模块间调用。
如果 Arguments
为 [A1, ..., An]
,则结果表示“call Module:Name(A1, ..., An)
”。
另请参阅:ann_c_call/4
、c_apply/2
、c_primop/2
、call_args/1
、call_arity/1
、call_module/1
、call_name/1
、is_c_call/1
、update_c_call/4
。
创建抽象的 case 表达式。
如果 Clauses
为 [C1, ..., Cn]
,则结果表示“case Argument of C1 ... Cn end
”。Clauses
不得为空。
另请参阅:ann_c_case/3
、c_clause/3
、case_arg/1
、case_arity/1
、case_clauses/1
、is_c_case/1
、update_c_case/3
。
创建抽象的 catch 表达式。
结果表示“catch Body
”。
注意:catch 表达式可以重写为 try 表达式,并最终将从 Core Erlang 中删除。
另请参阅:ann_c_catch/2
、c_try/5
、catch_body/1
、is_c_catch/1
、update_c_catch/2
。
-spec c_char(Value :: non_neg_integer()) -> c_literal().
创建抽象的字符文字。
如果 Erlang 的本地实现将 char/0
定义为 integer/0
的子集,则此函数等效于 c_int/1
。否则,如果给定值是整数,它将转换为具有相应代码的字符。字符的词法表示为“$Char
”,其中 Char
是单个打印字符或转义序列。
另请参阅:ann_c_char/2
、c_int/1
、c_string/1
、char_lit/1
、char_val/1
、is_c_char/1
、is_print_char/1
。
等效于 c_clause(Patterns, c_atom(true), Body)。
另请参阅:c_atom/1
。
创建一个抽象子句。
如果 Patterns
为 [P1, ..., Pn]
,则结果表示“<P1, ..., Pn> when Guard -> Body
”。
另请参阅:ann_c_clause/4
、c_case/2
、c_clause/2
、c_receive/3
、clause_arity/1
、clause_body/1
、clause_guard/1
、clause_pats/1
、clause_vars/1
、is_c_clause/1
、update_c_clause/4
。
创建抽象的列表构造函数。
结果表示“[Head | Tail]
”。请注意,如果 Head
和 Tail
都具有类型 literal
,则结果也将具有类型 literal
,并且 Head
和 Tail
上的注释将丢失。
回想一下,在 Erlang 中,列表构造函数的尾部元素不一定是列表。
另请参阅:ann_c_cons/3
、c_cons_skel/2
、c_nil/0
、cons_hd/1
、cons_tl/1
、is_c_cons/1
、is_c_list/1
、list_elements/1
、list_length/1
、make_list/2
、update_c_cons/3
。
创建抽象的列表构造函数框架。
不折叠常量字面量,也就是说,结果始终具有类型 cons
,表示“[Head | Tail]
”。
当需要对列表构造函数节点的子节点进行注释时,即使子节点是常量字面量,此函数也偶尔有用。但是,请注意,如果将此函数的结果传递给 is_literal/1
,则会产生 false
,如果传递给 concrete/1
,则会失败。
fold_literal/1
可用于将节点恢复为标准形式表示。
另请参阅:ann_c_cons_skel/3
、c_cons/2
、c_nil/0
、concrete/1
、fold_literal/1
、is_c_cons/1
、is_c_list/1
、is_literal/1
、update_c_cons_skel/3
。
创建抽象的浮点文字。
词法表示为 Value
的十进制浮点数。
等效于 c_var({Name, Arity})。
另请参阅:ann_c_fname/3
、fname_arity/1
、fname_id/1
、is_c_fname/1
、update_c_fname/3
。
创建抽象的 fun 表达式。
如果 Variables
为 [V1, ..., Vn]
,则结果表示“fun (V1, ..., Vn) -> Body
”。所有 Vi
必须具有类型 var
。
另请参阅:ann_c_fun/3
、fun_arity/1
、fun_body/1
、fun_vars/1
、is_c_fun/1
、update_c_fun/3
。
创建抽象的整数文字。
词法表示为 Value
的规范十进制数。
创建抽象的 let 表达式。
如果 Variables
为 [V1, ..., Vn]
,则结果表示“let <V1, ..., Vn> = Argument in Body
”。所有 Vi
必须具有类型 var
。
另请参阅:ann_c_let/4
、is_c_let/1
、let_arg/1
、let_arity/1
、let_body/1
、let_vars/1
、update_c_let/4
。
创建抽象的 letrec 表达式。
如果 Definitions
为 [{V1, F1}, ..., {Vn, Fn}]
,则结果表示“letrec V1 = F1 ... Vn = Fn in Body
”。所有 Vi
必须具有类型 var
并且表示函数名称。所有 Fi
必须具有类型 'fun'
。
另请参阅:ann_c_letrec/3
、is_c_letrec/1
、letrec_body/1
、letrec_defs/1
、letrec_vars/1
、update_c_letrec/3
。
-spec c_map(Pairs :: [c_map_pair()]) -> c_map().
创建抽象的 map 构造函数。
如果 Pairs
为 [E1, ..., EN]
,则结果表示“~{E1, ..., EN}~
”(创建一个新映射)。请注意,如果 Pairs
中的所有对的键和值都具有类型 literal
,或者如果 Pairs
为空,则结果也将具有类型 literal
,并且 Pairs
中节点的注释将丢失。
所有 Ei
必须是由 c_map_pair/2
构造的抽象对。
另请参阅:ann_c_map/2
、is_c_map/1
、is_c_map_empty/1
、is_c_map_pattern/1
、map_es/1
、c_map_pair/2
、c_map_pair_exact/2
。
-spec c_map(Argument :: cerl(), Pairs :: [c_map_pair()]) -> c_map().
创建抽象的 map 更新表达式。
如果 Pairs
是 [E1, ..., EN]
,则结果表示“~{E1, ..., EN | Argument}~
”(更新现有映射)。请注意,如果 Argument
是一个字面量,并且 Pairs
中的所有对的键和值都具有 literal
类型,或者如果 Pairs
为空,则结果也将具有 literal
类型,并且 Pairs
中节点的注释将丢失。
所有 Ei
都必须是由 c_map_pair/2
或 c_map_pair_exact/2
构造的抽象对。
另请参阅:ann_c_map/2
、is_c_map/1
、is_c_map_empty/1
、is_c_map_pattern/1
、map_es/1
、c_map_pair/2
、c_map_pair_exact/2
。
-spec c_map_pair(Key :: cerl(), Value :: cerl()) -> c_map_pair().
使用 assoc
操作符创建抽象的 map 对。
这些只能作为抽象映射创建表达式或抽象更新表达式的组成部分出现(请参阅 c_map/1
和 c_map/2
)。
结果表示“Key => Value
”。
-spec c_map_pair_exact(Key :: cerl(), Value :: cerl()) -> c_map_pair().
使用 exact
操作符创建抽象的 map 对。
这些只能作为抽象映射更新表达式或抽象映射模式的组成部分出现(请参阅 c_map/1
和 c_map_pattern/1
)。
结果表示“Key := Value
”。
-spec c_map_pattern(Pairs :: [c_map_pair()]) -> c_map().
创建抽象的 map 模式。
如果 Pairs
是 [E1, ..., EN]
,则结果表示“~{E1, ..., EN}~
”。
所有 Ei
都必须是由 c_map_pair_exact/2
构造的抽象对。
另请参阅:ann_c_map/2
、is_c_map/1
、is_c_map_empty/1
、is_c_map_pattern/1
、map_es/1
、c_map_pair_exact/2
。
-spec c_module(Name :: cerl(), Exports :: [cerl()], Attributes :: [{cerl(), cerl()}], Definitions :: [{cerl(), cerl()}]) -> c_module().
创建抽象的模块定义。
结果表示
module Name [E1, ..., Ek]
attributes [K1 = T1, ...,
Km = Tm]
V1 = F1
...
Vn = Fn
end
如果 Exports
= [E1, ..., Ek]
,Attributes
= [{K1, T1}, ..., {Km, Tm}]
,并且 Definitions
= [{V1, F1}, ..., {Vn, Fn}]
。
Name
和所有 Ki
必须是原子字面量,并且所有 Ti
必须是常量字面量。所有 Vi
和 Ei
都必须具有 var
类型,并表示函数名称。所有 Fi
都必须具有 'fun'
类型。
另请参阅:ann_c_module/4
、ann_c_module/5
、c_atom/1
、c_fun/2
、c_module/3
、c_var/1
、is_literal/1
、module_attrs/1
、module_defs/1
、module_exports/1
、module_name/1
、module_vars/1
、update_c_module/5
。
-spec c_nil() -> c_literal().
创建抽象的空列表。
结果表示“[]
”。空列表通常称为“nil”。
另请参阅:ann_c_nil/1
、c_cons/2
、is_c_list/1
。
创建抽象的原始操作调用。
如果 Arguments
是 [A1, ..., An]
,则结果表示“primop Name(A1, ..., An)
”。Name
必须是原子字面量。
另请参阅:ann_c_primop/3
、c_apply/2
、c_call/3
、is_c_primop/1
、primop_args/1
、primop_arity/1
、primop_name/1
、update_c_primop/3
。
等效于 c_receive(Clauses, c_atom(infinity), c_atom(true))。
另请参阅:c_atom/1
。
创建抽象的 receive 表达式。
如果 Clauses
是 [C1, ..., Cn]
,则结果表示“receive C1 ... Cn after Timeout -> Action end
”。
另请参阅:ann_c_receive/4
、c_receive/1
、is_c_receive/1
、receive_action/1
、receive_clauses/1
、receive_timeout/1
、update_c_receive/4
。
创建抽象的序列表达式。
结果表示“do Argument Body
”。
另请参阅:ann_c_seq/3
、is_c_seq/1
、seq_arg/1
、seq_body/1
、update_c_seq/3
。
创建抽象的字符串文字。
等效于创建相应字符字面量的抽象列表(参见 is_c_string/1
),但通常更有效率。字符串的词法表示形式为“"Chars"
”,其中 Chars
是打印字符或空格的序列。
另请参阅:ann_c_string/2
、c_char/1
、is_c_string/1
、is_print_string/1
、string_lit/1
、string_val/1
。
-spec c_try(Argument :: cerl(), Variables :: [cerl()], Body :: cerl(), ExceptionVars :: [cerl()], Handler :: cerl()) -> c_try().
创建抽象的 try 表达式。
如果 Variables
是 [V1, ..., Vn]
并且 ExceptionVars
是 [X1, ..., Xm]
,则结果表示“try Argument of <V1, ..., Vn> -> Body catch <X1, ..., Xm> -> Handler
”。所有 Vi
和 Xi
都必须具有 var
类型。
另请参阅:ann_c_try/6
、c_catch/1
、is_c_try/1
、try_arg/1
、try_body/1
、try_vars/1
、update_c_try/6
。
创建一个抽象元组。
如果 Elements
是 [E1, ..., En]
,则结果表示“{E1, ..., En}
”。请注意,如果 Elements
中的所有节点都具有 literal
类型,或者如果 Elements
为空,则结果也将具有 literal
类型,并且 Elements
中节点的注释将丢失。
请记住,Erlang 具有不同的 1 元组,即 {X}
始终与 X
本身不同。
另请参阅:ann_c_tuple/2
、c_tuple_skel/1
、is_c_tuple/1
、tuple_arity/1
、tuple_es/1
、update_c_tuple/2
。
创建一个抽象元组骨架。
不折叠常量字面量,也就是说,如果 Elements
是 [E1, ..., En]
,则结果始终具有 tuple
类型,表示“{E1, ..., En}
”。
当需要对元组节点的子节点进行注释时,即使所有子节点都是常量字面量,此函数有时也很有用。但是请注意,如果将此函数的结果传递给 is_literal/1
,则将产生 false
,并且如果将此函数的结果传递给 concrete/1
,则会失败。
fold_literal/1
可用于将节点恢复为标准形式表示。
另请参阅:ann_c_tuple_skel/2
、c_tuple/1
、concrete/1
、fold_literal/1
、is_c_tuple/1
、is_literal/1
、tuple_es/1
、update_c_tuple_skel/2
。
创建一个抽象值列表。
如果 Elements
是 [E1, ..., En]
,则结果表示“<E1, ..., En>
”。
另请参阅:ann_c_values/2
、is_c_values/1
、update_c_values/2
、values_arity/1
、values_es/1
。
创建一个抽象变量。
变量由其名称标识,名称由 Name
参数给出。
如果名称由单个原子给出,则它应该是一个“简单”原子,不需要在 Erlang 中用单引号引起来,否则其打印名称应对应于正确的 Erlang 变量,即以大写字母或下划线开头。形式为 {A, N}
的名称表示函数名变量“A/N
”;这些是特殊变量,只能在模块的函数定义或 letrec
中绑定。它们不能在 let
表达式中绑定,也不能出现在子句模式中。函数名称中的原子 A
可以是任何原子;整数 N
必须是非负数。函数 c_fname/2
等是用于处理函数名称变量的实用程序。
打印变量名时,它们必须符合 Core Erlang 变量和函数名的形式。例如,一个由整数表示的名称,如 42
,可以格式化为 "_42
";一个原子 'Xxx'
可以简单地格式化为 "Xxx
";而一个原子 foo
可以格式化为 "_foo
"。但是,必须确保任何两个有效的不同名称永远不会映射到相同的字符串。表示函数名的元组,如 {foo, 2}
,可以简单地格式化为 "'foo'/2
",不会有冲突的风险。
另请参阅: ann_c_var/2
、 c_fname/2
、 c_letrec/2
、 c_module/4
、 is_c_var/1
、 update_c_var/2
、 var_name/1
。
返回抽象跨模块调用的参数子树列表。
另请参阅: c_call/3
、 call_arity/1
。
返回抽象跨模块调用的参数子树的数量。
注意:这等效于 length(call_args(Node))
,但可能更高效。
另请参阅: c_call/3
、 call_args/1
。
返回抽象跨模块调用的模块子树。
另请参阅:c_call/3
。
返回抽象跨模块调用的名称子树。
另请参阅:c_call/3
。
返回抽象 case 表达式的参数子树。
另请参阅:c_case/2
。
-spec case_arity(Node :: c_case()) -> non_neg_integer().
等价于 clause_arity(hd(case_clauses(Node)))
,但可能更有效率。
另请参阅: c_case/2
、 case_clauses/1
、 clause_arity/1
。
返回抽象 case 表达式的子句子树列表。
另请参阅: c_case/2
、 case_arity/1
。
返回抽象 catch 表达式的主体子树。
另请参阅:c_catch/1
。
-spec char_lit(Node :: c_literal()) -> nonempty_string().
返回由抽象字符表示的文字字符串。 这包括前导 $
字符。
当前,所有不在 ISO 8859-1 (Latin-1) "可打印" 字符集中的字符都将被转义。
另请参阅:c_char/1
。
返回由抽象字符文字表示的值。
另请参阅:c_char/1
。
-spec clause_arity(Node :: c_clause()) -> non_neg_integer().
返回抽象子句的模式子树的数量。
注意:这等效于 length(clause_pats(Node))
,但可能更高效。
另请参阅: c_clause/3
、 clause_pats/1
。
返回抽象子句的主体子树。
另请参阅: c_clause/3
。
返回抽象子句的守卫子树。
另请参阅: c_clause/3
。
返回抽象子句的模式子树列表。
另请参阅: c_clause/3
、 clause_arity/1
。
返回抽象子句模式中所有抽象变量的列表。
列表的顺序未定义。
另请参阅: c_clause/3
、 pat_list_vars/1
。
返回由语法树表示的 Erlang 项。
如果 Node
不表示字面量,则会抛出异常。
注意:这是一个常量时间操作。
另请参阅: abstract/1
、 is_literal/1
。
返回抽象列表构造器的头部子树。
另请参阅:c_cons/2
。
返回抽象列表构造器的尾部子树。
请记住,尾部不一定代表一个正确的列表。
另请参阅:c_cons/2
。
将用户注释列表从 源
复制到 目标
。
注意:这等效于 set_ann(Target, get_ann(Source))
,但可能更高效。
-spec data_arity(Node :: c_lct()) -> non_neg_integer().
返回数据构造器节点的子树数量。
这等效于 length(data_es(Node))
,但可能更高效。
返回数据构造器节点的子树列表。
如果构造函数的元数为零,则结果为空列表。
注意:如果 data_type(Node)
是 cons
,则子树的数量恰好为两个。如果 data_type(Node)
是 {atomic, Value}
,则子树的数量为零。
另请参阅: data_arity/1
、 data_type/1
、 is_data/1
、 make_data/2
。
返回数据构造器节点的类型描述符。(参见 is_data/1
。)
这主要用于比较类型和构造相同类型的新节点(参见 make_data/2
)。如果 Node
表示整数、浮点数、原子或空列表,则结果为 {atomic, Value}
,其中 Value
是 concrete(Node)
的值,否则结果为 cons
或 tuple
。
类型描述符可以比较相等性或顺序(在 Erlang 术语顺序中),但请记住,浮点数值通常永远不应测试相等性。
另请参阅: concrete/1
、 is_data/1
、 make_data/2
、 type/1
。
返回由浮点文字节点表示的数字字符串。
另请参阅:c_float/1
。
返回由浮点文字节点表示的值。
另请参阅:c_float/1
。
返回抽象函数名变量的元数部分。
另请参阅: c_fname/2
、 fname_id/1
。
返回抽象函数名变量的标识符部分。
另请参阅: c_fname/2
、 fname_arity/1
。
确保文字具有紧凑的表示形式。
如果 Node
的构造使用了 c_cons_skel/2
、 c_tuple_skel/1
或 unfold_literal/1
,并且您想恢复为字面量的正常“折叠”表示形式,则这有时很有用。如果 Node
表示元组或列表构造函数,则其元素将被递归重写,并且该节点将分别使用 c_cons/2
或 c_tuple/1
重构;否则,Node
不会改变。
另请参阅: c_cons/2
、 c_cons_skel/2
、 c_tuple/1
、 c_tuple_skel/1
、 is_literal/1
、 unfold_literal/1
。
将显式记录表示转换为相应的抽象语法树。
记录在文件 "core_parse.hrl
" 中定义。
另请参阅: to_records/1
、 type/1
。
返回抽象 fun 表达式的参数子树的数量。
注意:这等效于 length(fun_vars(Node))
,但可能更高效。
另请参阅: c_fun/2
、 fun_vars/1
。
返回抽象 fun 表达式的主体子树。
另请参阅:c_fun/2
。
返回抽象 fun 表达式的参数子树列表。
另请参阅: c_fun/2
、 fun_arity/1
。
返回与语法树节点关联的用户注释列表。
对于新创建的节点,这是一个空列表。注解可以是任何术语。
另请参阅: set_ann/2
。
返回由整数文字节点表示的数字字符串。
另请参阅:c_int/1
。
返回由整数文字节点表示的值。
另请参阅:c_int/1
。
如果 节点
是抽象模式别名,则返回 true
,否则返回 false
。
另请参阅:c_alias/2
。
如果 节点
是抽象函数应用,则返回 true
,否则返回 false
。
另请参阅:c_apply/2
。
如果 节点
表示原子文字,则返回 true
,否则返回 false
。
另请参阅:c_atom/1
。
如果 节点
是抽象二进制模板,则返回 true
,否则返回 false
。
另请参阅:c_binary/1
。
如果 节点
是抽象位字符串模板,则返回 true
,否则返回 false
。
另请参阅: c_bitstr/5
。
如果 节点
是抽象跨模块调用表达式,则返回 true
,否则返回 false
。
另请参阅:c_call/3
。
如果 节点
是抽象 case 表达式,则返回 true
,否则返回 false
。
另请参阅:c_case/2
。
如果 节点
是抽象 catch 表达式,则返回 true
,否则返回 false
。
另请参阅:c_catch/1
。
如果 节点
可能表示字符文字,则返回 true
,否则返回 false
。
如果 Erlang 的本地实现将 char/0
定义为 integer/0
的子集,则 is_c_int(Node)
也会产生 true
。
另请参阅: c_char/1
、 is_print_char/1
。
如果 节点
是抽象子句,则返回 true
,否则返回 false
。
另请参阅: c_clause/3
。
如果 节点
是抽象列表构造器,则返回 true
,否则返回 false
。
如果 节点
表示浮点文字,则返回 true
,否则返回 false
。
另请参阅:c_float/1
。
如果 节点
是抽象函数名变量,则返回 true
,否则返回 false
。
另请参阅: c_fname/2
、 c_var/1
、 var_name/1
。
如果 节点
是抽象 fun 表达式,则返回 true
,否则返回 false
。
另请参阅:c_fun/2
。
如果 节点
表示整数文字,则返回 true
,否则返回 false
。
另请参阅:c_int/1
。
如果 节点
是抽象 let 表达式,则返回 true
,否则返回 false
。
另请参阅:c_let/3
。
如果 节点
是抽象 letrec 表达式,则返回 true
,否则返回 false
。
另请参阅:c_letrec/2
。
如果 节点
表示正确的列表,则返回 true
,否则返回 false
。
正确的列表要么是空列表 []
,要么是 cons 单元 [Head | Tail]
,其中递归地 Tail
是一个正确的列表。
注意:由于 Node
是一个语法树,因此与其子树相对应的实际运行时值通常可能部分或完全未知。因此,如果 Node
例如表示 "[... | Ns]
"(其中 Ns
是一个变量),则该函数将返回 false
,因为不知道 Ns
在运行时是否会绑定到列表。如果 Node
例如表示 "[1, 2, 3]
" 或 "[A | []]
",则该函数将返回 true
。
另请参阅: c_cons/2
、 c_nil/0
、 list_elements/1
、 list_length/1
。
如果 节点
是任何类型的抽象映射(用于构造、更新或匹配),则返回 true
,否则返回 false
。
另请参阅: ann_c_map/3
、 c_map/1
、 c_map_pattern/1
。
如果 节点
表示空抽象映射,则返回 true
,否则返回 false
。
另请参阅: c_map/1
, c_map_pattern/1
。
如果 节点
是抽象映射模式,则返回 true
,否则返回 false
。
另请参阅: c_map/1
, c_map_pattern/1
。
如果 节点
是抽象模块定义,则返回 true
,否则返回 false
。
另请参阅: type/1
。
如果 节点
是抽象空列表,则返回 true
,否则返回 false
。
如果 节点
是抽象原始操作调用,则返回 true
,否则返回 false
。
另请参阅:c_primop/2
。
如果 节点
是抽象接收表达式,则返回 true
,否则返回 false
。
另请参阅: c_receive/3
。
如果 节点
是抽象排序表达式,则返回 true
,否则返回 false
。
另请参阅:c_seq/2
。
如果 节点
可能表示字符串文字,则返回 true
,否则返回 false
。
字符串定义为字符列表;有关详细信息,请参见 is_c_char/1
。
另请参阅: c_string/1
、 is_c_char/1
、 is_print_string/1
。
如果 节点
是抽象 try 表达式,则返回 true
,否则返回 false
。
另请参阅:c_try/5
。
如果 节点
是抽象元组,则返回 true
,否则返回 false
。
另请参阅:c_tuple/1
。
如果 节点
是抽象值列表,则返回 true
,否则返回 false
。
另请参阅:c_values/1
。
如果 节点
是抽象变量,则返回 true
,否则返回 false
。
另请参阅:c_var/1
。
如果 节点
表示数据构造器,则返回 true
,否则返回 false
。
数据构造函数是 cons 单元、元组和原子字面量。
另请参阅: data_arity/1
、 data_es/1
、 data_type/1
。
如果 节点
是叶节点,则返回 true
,否则返回 false
。
当前的叶节点类型为 literal
和 var
。
注意:所有字面量(参见 is_literal/1
)都是叶节点,即使它们表示结构化的(常量)值,如 {foo, [bar, baz]}
。另请注意,变量是叶节点但不是字面量。
另请参阅: is_literal/1
、 type/1
。
如果 节点
表示文字项,则返回 true
,否则返回 false
。
当且仅当 concrete(Node)
的值已定义时,此函数才返回 true
。
注意:这是一个常量时间操作。
另请参阅: abstract/1
、 concrete/1
、 fold_literal/1
。
如果 项
可以表示为文字,则返回 true
,否则返回 false
。
此函数花费的时间与 Term
的大小成正比。
另请参阅:abstract/1
。
如果 节点
可能表示“可打印”字符,则返回 true
,否则返回 false
。(参见 is_c_char/1
。)
“可打印”字符要么具有给定的图形表示形式,要么具有“命名”转义序列,如 "\n
"。目前,仅识别 ISO 8859-1 (Latin-1) 字符值。
另请参阅: c_char/1
、 is_c_char/1
。
如果 节点
可能表示仅包含“可打印”字符的字符串文字,则返回 true
,否则返回 false
。
有关详细信息,请参见 is_c_string/1
和 is_print_char/1
。目前,仅识别 ISO 8859-1 (Latin-1) 字符值。
另请参阅: c_string/1
、 is_c_string/1
、 is_print_char/1
。
返回抽象 let 表达式的参数子树。
另请参阅:c_let/3
。
-spec let_arity(Node :: c_let()) -> non_neg_integer().
返回抽象 let 表达式左侧变量的数量。
注意:这等效于 length(let_vars(Node))
,但可能更高效。
另请参阅: c_let/3
、 let_vars/1
。
返回抽象 let 表达式的主体子树。
另请参阅:c_let/3
。
返回抽象 let 表达式的左侧变量列表。
另请参阅: c_let/3
、 let_arity/1
。
返回抽象 letrec 表达式的主体子树。
另请参阅:c_letrec/2
。
返回抽象 letrec 表达式的定义列表。
如果 Node
表示“letrec V1 = F1 ... Vn = Fn in Body
”,则返回值是 [{V1, F1}, ..., {Vn, Fn}]
。
另请参阅:c_letrec/2
。
返回 letrec 表达式左侧函数变量子树的列表。
如果 Node
表示“letrec V1 = F1 ... Vn = Fn in Body
”,则返回值是 [V1, ..., Vn]
。
另请参阅:c_letrec/2
。
返回抽象列表的元素子树列表。
Node
必须表示一个正确的列表。例如,如果 Node
表示“[X1, X2 | [X3, X4 | []]
”,则 list_elements(Node)
会产生列表 [X1, X2, X3, X4]
。
另请参阅:c_cons/2
、c_nil/0
、is_c_list/1
、list_length/1
、make_list/2
。
-spec list_length(Node :: c_cons() | c_literal()) -> non_neg_integer().
返回抽象列表的元素子树的数量。
Node
必须表示一个正确的列表。例如,如果 Node
表示 “[X1 | [X2, X3 | [X4, X5, X6]]]
”,则 list_length(Node)
返回整数 6。
注意:这等效于 length(list_elements(Node))
,但可能更有效率。
使用指定的类型和子树创建数据构造器节点。(参见 data_type/1
。)
如果 Elements
的长度对于给定的 Type
无效,则会抛出异常;有关构造器类型的元数约束,请参阅 data_es/1
。
另请参阅:ann_make_data/3
、data_es/1
、data_type/1
、make_data_skel/2
、update_data/3
。
类似于 make_data/2
,但类似于 c_tuple_skel/1
和 c_cons_skel/2
。
另请参阅:ann_make_data_skel/3
、c_cons_skel/2
、c_tuple_skel/1
、make_data/2
、update_data_skel/3
。
从 列表
中的元素和可选的 尾部
创建抽象列表。
如果 Tail
是 none
,则结果将表示一个以 nil 结尾的列表,否则表示“[... | Tail]
”。
另请参阅:ann_make_list/3
、c_cons/2
、c_nil/0
、list_elements/1
、update_list/3
。
使用给定的类型和子树创建语法树。
Type
必须是节点类型名称(参见 type/1
),它不表示叶节点类型(参见 is_leaf/1
)。
Groups
必须是语法树组的非空列表,表示给定类型的节点的子树,按照它们在打印的程序文本中出现的从左到右的顺序排列,并按 subtrees/1
所做的那样按类别分组。
ann_make_tree(get_ann(Node), type(Node), subtrees(Node))
的结果(参见 update_tree/2
)表示与原始 Node
相同的源代码文本,假设 subtrees(Node)
产生一个非空列表。但是,它不一定具有与 Node
完全相同的数据表示。
另请参阅:ann_make_tree/3
、is_leaf/1
、subtrees/1
、type/1
、update_tree/2
。
返回抽象映射的参数子树。
另请参阅:c_map/2
。
-spec map_es(Node :: c_map() | c_literal()) -> [c_map_pair()].
返回抽象映射的映射对子树列表。
另请参阅:c_map/1
。
-spec map_pair_key(Node :: c_map_pair()) -> cerl().
返回抽象映射对的键子树。
-spec map_pair_op(Node :: c_map_pair()) -> map_op().
返回抽象映射对的操作子树。
-spec map_pair_val(Node :: c_map_pair()) -> cerl().
返回抽象映射对的值子树。
创建语法树的元表示。
结果表示一个 Erlang 表达式 “MetaTree
”,如果对其进行求值,将产生一个新的语法树,该语法树表示与 Tree
相同的源代码文本(尽管实际的数据表示可能不同)。由 MetaTree
表示的表达式在抽象语法树实现所使用的数据结构方面是与实现无关的。
在 Tree
中,任何节点类型为 var
(参见 type/1
)并且其注释列表(参见 get_ann/1
)包含原子 meta_var
的节点,在生成的树中将保持不变,只是会从其注释列表中删除一个 meta_var
。
函数 meta/1
的主要用途是将表示一段程序代码的数据结构 Tree
转换为一种在打印时与表示无关的形式。例如,假设 Tree
表示一个名为 “V” 的变量。然后(假设有一个用于打印语法树的函数 print/1
),对 print(abstract(Tree))
求值(仅使用 abstract/1
将实际的数据结构映射到语法树表示)将输出一个可能类似于 “{var, ..., 'V'}
” 的字符串,这显然取决于抽象语法树的实现。例如,这对于在文件中缓存语法树可能很有用。但是,在某些情况下(例如在程序生成器生成器(带有两个“生成器”)中),这可能是不可接受的。使用 print(meta(Tree))
代替将输出一个与表示无关的语法树生成表达式;在上面的例子中,类似于 “cerl:c_var('V')
”。
该实现试图生成关于文字和列表的紧凑代码。
另请参阅:abstract/1
、get_ann/1
、type/1
。
返回抽象模块定义的属性键/值子树对列表。
另请参阅: c_module/4
。
返回抽象模块定义的函数定义列表。
另请参阅: c_module/4
。
返回抽象模块定义的导出子树列表。
另请参阅: c_module/4
。
返回抽象模块定义的名称子树。
另请参阅: c_module/4
。
返回抽象模块定义的左侧函数变量子树列表。
另请参阅: c_module/4
。
返回给定模式中所有抽象变量的列表。
如果 Patterns
中的某些元素不表示格式良好的 Core Erlang 子句模式,则会抛出异常。列表的顺序未定义。
另请参阅:clause_vars/1
、pat_vars/1
。
返回模式中所有抽象变量的列表。
如果 Node
不表示格式良好的 Core Erlang 子句模式,则会抛出异常。列表的顺序未定义。
另请参阅:clause_vars/1
、pat_list_vars/1
。
返回抽象原始操作调用的参数子树列表。
另请参阅:c_primop/2
、primop_arity/1
。
返回抽象原始操作调用的参数子树的数量。
注意:这等效于 length(primop_args(Node))
,但可能更有效率。
另请参阅:c_primop/2
、primop_args/1
。
返回抽象原始操作调用的名称子树。
另请参阅:c_primop/2
。
返回抽象接收表达式的动作子树。
另请参阅: c_receive/3
。
返回抽象接收表达式的子句子树列表。
另请参阅: c_receive/3
。
返回抽象接收表达式的超时子树。
另请参阅: c_receive/3
。
返回抽象序列表达式的参数子树。
另请参阅:c_seq/2
。
返回抽象序列表达式的主体子树。
另请参阅:c_seq/2
。
将 节点
的用户注释列表设置为 注释
。
另请参阅:add_ann/2
、copy_ann/2
、get_ann/1
。
-spec string_lit(Node :: c_literal()) -> nonempty_string().
返回由抽象字符串表示的字面字符串。这包括周围的双引号字符 "..."
。
当前,除了空格之外,不在 ISO 8859-1(Latin-1)“打印”字符集中的字符将被转义。
另请参阅:c_string/1
。
返回由抽象字符串字面量表示的值。
另请参阅:c_string/1
。
返回节点的所有子树的分组列表。
如果 Node
是一个叶节点(参见 is_leaf/1
),则这是空列表,否则结果始终是非空列表,其中包含 Node
的子树列表,按照它们在打印的程序文本中出现的从左到右的顺序排列,并按类别分组。通常,每个组仅包含一个子树。
根据 Node
的类型,某些组的大小可能是可变的(例如,由元组的所有元素组成的组),而另一些组始终包含相同数量的元素 - 通常恰好是一个(例如,包含 case 表达式的参数表达式的组)。但是请注意,通常不应依赖返回列表(对于给定的节点类型)的确切结构,因为它可能会在没有通知的情况下发生更改。
如果要遍历语法树、访问其所有子树,但在大多数或所有情况下以统一的方式处理树的节点,那么函数 subtrees/1
和构造函数 make_tree/2
和 update_tree/2
可以提供很大的帮助。使用这些函数可以简化此操作,并且还可以确保您的代码不会对语法树数据类型的扩展过于敏感,因为您的代码未显式处理的任何节点类型都可以留给默认情况。
例如
postorder(F, Tree) ->
F(case subtrees(Tree) of
[] -> Tree;
List -> update_tree(Tree,
[[postorder(F, Subtree)
|| Subtree <- Group]
|| Group <- List])
end).
将函数 F
映射到 Tree
及其所有子树,执行语法树的后序遍历。(请注意使用 update_tree/2
来保留注释。)对于像这样的简单函数
f(Node) ->
case type(Node) of
atom -> atom("a_" ++ atom_name(Node));
_ -> Node
end.
调用 postorder(fun f/1, Tree)
将产生 Tree
的新表示形式,其中所有原子名称都已扩展了前缀 “a_”,但其他任何内容(包括注释)均未更改。
将抽象语法树转换为相应的显式记录表示。
这些记录在文件 “cerl.hrl
” 中定义。
另请参阅:from_records/1
、type/1
。
返回抽象 try 表达式的表达式子树。
另请参阅:c_try/5
。
返回抽象 try 表达式的成功主体子树。
另请参阅:c_try/5
。
返回抽象 try 表达式的异常变量子树列表。
另请参阅:c_try/5
。
返回抽象 try 表达式的异常主体子树。
另请参阅:c_try/5
。
返回抽象 try 表达式的成功变量子树列表。
另请参阅:c_try/5
。
-spec tuple_arity(Node :: c_tuple() | c_literal()) -> non_neg_integer().
返回抽象元组的元素子树的数量。
注意:这等效于 length(tuple_es(Node))
,但可能更有效率。
另请参阅:c_tuple/1
、tuple_es/1
。
返回抽象元组的元素子树列表。
另请参阅:c_tuple/1
。
返回 节点
的类型标签。
当前的节点类型是
alias
apply
binary
bitstr
call
case
catch
clause
cons
fun
let
letrec
literal
map
map_pair
module
opaque
primop
receive
seq
try
tuple
values
var
注意
节点类型的主要构造器函数的名称始终是类型本身的名称,前缀为 “
c_
”;识别谓词相应地以 “is_c_
” 为前缀。此外,为了简化注释的保留(参见get_ann/1
),还有以 “ann_c_
” 和 “update_c_
” 为前缀的类似构造器函数,分别用于将新节点的注释列表设置为特定值或设置为现有节点的注释。
opaque
类型的唯一目的是方便编译器的测试。
另请参阅:abstract/1
、c_alias/2
、c_apply/2
、c_binary/1
、c_bitstr/5
、c_call/3
、c_case/2
、c_catch/1
、c_clause/3
、c_cons/2
、c_fun/2
、c_let/3
、c_letrec/2
、c_module/3
、c_primop/2
、c_receive/1
、c_seq/2
、c_try/5
、c_tuple/1
、c_values/1
、c_var/1
、data_type/1
、from_records/1
、get_ann/1
、meta/1
、subtrees/1
、to_records/1
。
确保字面量具有完全展开的表示形式。
如果 Node
表示字面元组或列表构造函数,则其元素会被递归重写,并分别使用 c_cons_skel/2
或 c_tuple_skel/1
重建节点;否则,Node
不会被更改。fold_literal/1
可用于恢复到正常的紧凑表示形式。
另请参阅:c_cons/2
、c_cons_skel/2
、c_tuple/1
、c_tuple_skel/1
、fold_literal/1
、is_literal/1
。
另请参阅:c_alias/2
。
另请参阅:c_apply/2
。
另请参阅:c_binary/1
。
-spec update_c_bitstr(Node :: c_bitstr(), Value :: cerl(), Size :: cerl(), Unit :: cerl(), Type :: cerl(), Flags :: cerl()) -> c_bitstr().
另请参阅: c_bitstr/5
, update_c_bitstr/5
。
-spec update_c_call(Node :: cerl(), Module :: cerl(), Name :: cerl(), Arguments :: [cerl()]) -> c_call().
另请参阅:c_call/3
。
另请参阅:c_case/2
。
另请参阅:c_catch/1
。
-spec update_c_clause(Node :: c_clause(), Patterns :: [cerl()], Guard :: cerl(), Body :: cerl()) -> c_clause().
另请参阅: c_clause/3
。
-spec update_c_cons(Node :: c_literal() | c_cons(), Head :: cerl(), Tail :: cerl()) -> c_literal() | c_cons().
另请参阅:c_cons/2
。
-spec update_c_cons_skel(Node :: c_cons() | c_literal(), Head :: cerl(), Tail :: cerl()) -> c_cons().
另请参阅:c_cons_skel/2
。
类似于 update_c_fname/3
,但从 节点
获取元数。
另请参阅:c_fname/2
、update_c_fname/3
。
等效于 update_c_var(Old, {Atom, Arity})。
另请参阅:c_fname/2
、update_c_fname/2
。
另请参阅:c_fun/2
。
-spec update_c_let(Node :: c_let(), Variables :: [cerl()], Argument :: cerl(), Body :: cerl()) -> c_let().
另请参阅:c_let/3
。
-spec update_c_letrec(Node :: c_letrec(), Definitions :: [{cerl(), cerl()}], Body :: cerl()) -> c_letrec().
另请参阅:c_letrec/2
。
-spec update_c_map(Node :: c_map(), Map :: cerl(), Pairs :: [c_map_pair()]) -> c_map() | c_literal().
另请参阅: c_map/1
, c_map_pattern/1
。
-spec update_c_map_pair(Node :: c_map_pair(), Operation :: map_op(), Key :: cerl(), Value :: cerl()) -> c_map_pair().
-spec update_c_module(Node :: c_module(), Name :: cerl(), Exports :: [cerl()], Attributes :: [{cerl(), cerl()}], Definitions :: [{cerl(), cerl()}]) -> c_module().
另请参阅: c_module/4
。
另请参阅:c_primop/2
。
-spec update_c_receive(Node :: c_receive(), Clauses :: [cerl()], Timeout :: cerl(), Action :: cerl()) -> c_receive().
另请参阅: c_receive/3
。
另请参阅:c_seq/2
。
-spec update_c_try(Node :: c_try(), Argument :: cerl(), Variables :: [cerl()], Body :: cerl(), ExceptionVars :: [cerl()], Handler :: cerl()) -> c_try().
另请参阅:c_try/5
。
-spec update_c_tuple(Node :: c_tuple() | c_literal(), Elements :: [cerl()]) -> c_tuple() | c_literal().
另请参阅:c_tuple/1
。
另请参阅:c_tuple_skel/1
。
另请参阅:c_values/1
。
另请参阅:c_var/1
。
另请参阅:make_data/2
。
另请参阅:make_data_skel/2
。
另请参阅: make_list/2
, update_list/2
。
使用给定的子树创建语法树,并具有与节点 节点
相同的类型和注释。
这等效于 ann_make_tree(get_ann(Node), type(Node), Groups)
,但可能更有效。
使用给定的类型和子树创建语法树,并具有与节点 节点
相同的注释。
这等效于 ann_make_tree(get_ann(Node), Type, Groups)
,但可能更有效。
-spec values_arity(Node :: c_values()) -> non_neg_integer().
返回抽象值列表的元素子树的数量。
注意:这等效于 length(values_es(Node))
,但可能更有效。
另请参阅:c_values/1
、values_es/1
。
返回抽象值列表的元素子树列表。
另请参阅:c_values/1
、values_arity/1
。
返回抽象变量的名称。
另请参阅:c_var/1
。