查看源代码 cerl_clauses (编译器 v8.5.4)

用于 Core Erlang case/receive 子句的实用函数。

注意

Erlang 编译器公共接口的文档可以在模块 compile 中找到。

此模块是编译器的内部组成部分。其 API 不能保证在不同版本之间保持兼容性。

语法树在模块 cerl 中定义。

摘要

函数

如果列表中任何抽象子句是全捕获子句,则返回 true,否则返回 false

尝试将守卫表达式简化为单个常量值(如果可能)。

如果抽象子句是全捕获子句,则返回 true,否则返回 false

将模式与表达式匹配。

类似于 match/2,但是将模式序列与表达式序列匹配。

等效于 reduce(Cs, [])

如果可能,选择单个子句,否则减少可选择子句的列表。

类型

-type bindings() :: [{cerl(), cerl()}].
-type cerl() :: cerl:cerl().
-type expr() :: any | cerl().
-type match_ret() :: none | {true, bindings()} | {false, bindings()}.

函数

-spec any_catchall(Clauses :: [cerl()]) -> boolean().

如果列表中任何抽象子句是全捕获子句,则返回 true,否则返回 false

有关详细信息,请参阅 is_catchall/1

注意:Clauses 中的每个节点都必须具有类型 clause

另请参阅: is_catchall/1

-spec eval_guard(Expr :: cerl()) -> none | {value, term()}.

尝试将守卫表达式简化为单个常量值(如果可能)。

如果守卫表达式 Expr 总是产生常量值 Term,则返回的值为 {value, Term},否则为 none

请注意,虽然守卫表达式应该只产生布尔值,但此函数不保证 Termtruefalse。还要注意,只递归检查诸如 let 表达式之类的简单结构;不执行一般的常量折叠。

另请参阅: is_catchall/1

-spec is_catchall(Clause :: cerl:c_clause()) -> boolean().

如果抽象子句是全捕获子句,则返回 true,否则返回 false

如果一个子句的所有模式都是变量,并且其守卫表达式始终计算为 true,则该子句为全捕获子句;参见 eval_guard/1

注意:Clause 必须具有类型 clause

另请参阅: any_catchall/1, eval_guard/1

-spec match(Pattern :: cerl(), Expr :: expr()) -> match_ret().

将模式与表达式匹配。

如果不可能匹配,则返回的值为 none;如果 Pattern 确定与 Expr 匹配,则返回 {true, Bindings};如果匹配不确定,但不能排除,则返回 {false, Bindings}Bindings 是成对的 {Var, SubExpr} 列表,将模式中的每个变量与 Expr 的相应子表达式相关联,如果不存在匹配的子表达式,则与原子 any 相关联。(请记住,变量在 Core Erlang 模式中不能重复。)绑定列表以最内层优先的顺序给出;如果 Pattern 包含一个或多个别名模式,则这应该只是感兴趣的。如果返回的值是 {true, []},则表示模式和表达式在语法上是相同的。

对于 Expr,可以传递原子 any 来代替语法树(或者,更一般地说,只要抽象语法树实现允许,就可以用于 Expr 的任何子树);这意味着无法确定模式是否匹配,并且相应的变量绑定都将映射到 any。典型的用法是为 receive 子句生成绑定。

注意:此函数永远不会将二进制语法模式与二进制语法表达式进行结构匹配。

示例

  • 将模式“{X, Y}”与表达式“{foo, f(Z)}”匹配会产生 {true, Bindings},其中 Bindings 将 “X” 与子树 “foo” 关联,并将 “Y” 与子树 “f(Z)” 关联。
  • 将模式“{X, {bar, Y}}” 与表达式 “{foo, f(Z)}” 匹配会产生 {false, Bindings},其中 Bindings 将 “X” 与子树 “foo” 关联,并将 “Y” 与 any 关联(因为不知道 “{foo, Y}” 是否可能匹配 “f(Z)” 的运行时值)。
  • 将模式 “{foo, bar}” 与表达式 “{foo, f()}” 匹配会产生 {false, []},这告诉我们可能存在匹配,但我们无法推断出任何绑定。
  • {foo, X = {bar, Y}} 与表达式 “{foo, {bar, baz}}” 匹配会产生 {true, Bindings},其中 Bindings 将 “Y” 与 “baz” 关联,将 “X” 与 “{bar, baz}” 关联。
  • 将模式 “{X, Y}” 与 any 匹配会产生 {false, Bindings},其中 Bindings 将 “X” 和 “Y” 都与 any 关联。
链接到此函数

match_list(Patterns, Exprs)

查看源代码
-spec match_list(Patterns :: [cerl()], Exprs :: [expr()]) -> match_ret().

类似于 match/2,但是将模式序列与表达式序列匹配。

Exprs 传递空列表等效于传递一个与 Patterns 长度相同的 any 原子列表。

另请参阅: match/2

-spec reduce([cerl:c_clause()]) -> {true, {cerl:c_clause(), bindings()}} | {false, [cerl:c_clause()]}.

等效于 reduce(Cs, [])

链接到此函数

reduce(Clauses, Exprs)

查看源代码
-spec reduce(Clauses :: [cerl:c_clause()], Exprs :: [expr()]) ->
                {true, {cerl:c_clause(), bindings()}} | {false, [cerl:c_clause()]}.

如果可能,选择单个子句,否则减少可选择子句的列表。

输入是抽象子句列表 Clauses(即类型为 clause 的语法树)和切换表达式列表 Exprs。该函数尝试根据切换表达式唯一选择单个子句或丢弃不可选择的子句。列表中的所有抽象子句必须具有相同数量的模式。如果 Exprs 不是空列表,则其长度必须与每个子句中模式的数量相同;有关详细信息,请参阅 match_list/2

只有当守卫表达式始终产生原子 true 时,才能选择一个子句,而守卫表达式始终产生原子 false 的子句永远不会被选中。其他守卫表达式被认为具有未知值;参见 eval_guard/1

如果可以选择特定子句,则该函数返回 {true, {Clause, Bindings}},其中 Clause 是选定的子句,Bindings 是成对的 {Var, SubExpr} 列表,将 Clause 模式中出现的变量与 Exprs 中的相应子表达式相关联。绑定列表以最内层优先的顺序给出;有关详细信息,请参阅 match/2 函数。

如果无法明确选择任何子句,则该函数返回 {false, NewClauses},其中 NewClausesClauses 中在消除不可选择的子句后保留的条目列表,并保留相对顺序。

另请参阅: eval_guard/1, match/2, match_list/2