查看源代码 cerl_clauses (编译器 v8.5.4)
用于 Core Erlang case/receive 子句的实用函数。
注意
Erlang 编译器公共接口的文档可以在模块
compile
中找到。此模块是编译器的内部组成部分。其 API 不能保证在不同版本之间保持兼容性。
语法树在模块 cerl
中定义。
摘要
函数
如果列表中任何抽象子句是全捕获子句,则返回 true
,否则返回 false
。
尝试将守卫表达式简化为单个常量值(如果可能)。
如果抽象子句是全捕获子句,则返回 true
,否则返回 false
。
将模式与表达式匹配。
类似于 match/2
,但是将模式序列与表达式序列匹配。
等效于 reduce(Cs, [])。
如果可能,选择单个子句,否则减少可选择子句的列表。
类型
函数
如果列表中任何抽象子句是全捕获子句,则返回 true
,否则返回 false
。
有关详细信息,请参阅 is_catchall/1
。
注意:Clauses
中的每个节点都必须具有类型 clause
。
另请参阅: is_catchall/1
。
尝试将守卫表达式简化为单个常量值(如果可能)。
如果守卫表达式 Expr
总是产生常量值 Term
,则返回的值为 {value, Term}
,否则为 none
。
请注意,虽然守卫表达式应该只产生布尔值,但此函数不保证 Term
为 true
或 false
。还要注意,只递归检查诸如 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
。
将模式与表达式匹配。
如果不可能匹配,则返回的值为 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/2
,但是将模式序列与表达式序列匹配。
为 Exprs
传递空列表等效于传递一个与 Patterns
长度相同的 any
原子列表。
另请参阅: match/2
。
-spec reduce([cerl:c_clause()]) -> {true, {cerl:c_clause(), bindings()}} | {false, [cerl:c_clause()]}.
等效于 reduce(Cs, [])。
-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}
,其中 NewClauses
是 Clauses
中在消除不可选择的子句后保留的条目列表,并保留相对顺序。
另请参阅: eval_guard/1
, match/2
, match_list/2
。