文档章节

The Abstract Format

hncscwc
 hncscwc
发布于 2014/06/16 18:20
字数 954
阅读 63
收藏 0
点赞 0
评论 0

1. 模块声明及属性

(1). 模块的申明

-module(test).
{attribute, LINE, module, test}.
(2). 函数的导出
-export([start/0, start/1]).
{attribute, LINE, export, [{start,1}, {start,2}]}.
(3). 函数的导入
-export(io, [format/2]).
{attribute, LINE, import, {io, [{format, 2}]}}.

(4). 记录定义
-reocrd(state, {sock, recv_len}).
{attribute, LINE, record, {state, [{record_field, LINE, {atom, LINE, socket}},
                                   {record_field, LINE, {atom, LINE, recv_len}}]}}.
(5). 其他属性地定义
-author("hncscwc").
{attribute, LINE, author, "hncscwc"}.
2. 模式
(1). 变量
V
{var, LINE, 'V'}
(2). 元组
{A, B, C}
{tuple, LINE, [Rep(A), Rep(B), Rep(C)]}
例如:
{ok, "info", Data}
{tuple, Line, [{atom, Line, ok}, {string, LINE, "info"}, {var, LINE, 'Data'}]}
(3). 空列表
[]
{nil, LINE}
(4). 列表
[A|B]
{cons, LINE, Rep(A), Rep(B)}
同理
[A,B,C] == [A|[B,C]] == [A|[B|[C]]] == [A|[B|[C|[]]]]
{cons, LINE, Rep(A),
             {cons, LINE, Rep(B),
                          {cons, LINE, Rep(C),
                                       {nil, LINE}}}}
例如:
[ok, "info", Info]
{cons, Line, {atom, Line, ok},
             {cons, Line, {string, LINE, "info"},
                          {cons, Line, {var, LINE, 'Info'},
                                       {nil, LINE}}}}

(5). binary

<<P1:Size1/TSL1, ..., Pk:Sizek/TSLk>>
{bin, LINE, [{bin_element, LINE, Rep(P1), Rep(Size1), Rep(TSL1)},
             ...
             {bin_element, LINE, Rep(Pk), Rep(Sizek), Rep(TSLk)}]}
注意: 缺省用default替代, 另外Rep(TSL) 形式为 [TSL]
例如:
<<156:32/big, 1, Info/binary>>
{bin, LINE, [{bin_element, LINE, {integer, LINE, 156}, {integer,LINE,32}, [big]},
             {bin_element, LINE, {integer, LINE, 1},default, default,},
             {bin_element, LINE, {var, LINE, 'Info'}, default, [binary]}]}
(6). record赋值
#Name{Field1=P1, ..., Fieldk=Pk}
{record, LINE, Name, [{record_field, LINE, Rep(Field1), Rep(P1)},
                      ...,
                      {record_field, LINE, Rep(Fieldk), Rep(Pk)}]}
例如:
#state{sock = Socket, recv_len = 4}
{record, LINE, state, [{record_field, LINE, {atom, LINE, sock}, {var, LINE, 'Socket'}},
                       {record_field, LINE, {aotm, LINE, recv_len}, {integer, LINE, 4}]}
(7). record取值
#Name.Field
{record_index, LINE, Name, Rep(Field)}
例如:
#state.sock
{record_index, LINE, state, {atom, LINE, sock}}
(8). record
Val#Name.Field
{record_field, LINE, Rep(Val), Name, Rep(Field)}
例如:
State#state.sock
{record_field, LINE, {var, LINE, 'State'}, state, {atom, LINE, sock}}
(9). 函数
1) Name/Arity
{'fun', LINE, {function, Name, Arity}}.
例如:
F = fun start/2
{match, LINE, {var, LINE, 'F'}, {'fun', LINE, {function, start, 2}}}


2) Module:Name/Arity
{'fun', LINE, {function, Rep(Module), Rep(Name), Rep(Arity)}}
例如:
F = lists:nth/2
{match, LINE, {var, LINE, 'F'},{'fun', LINE, {function, {atom, LINE, lists}, {atom, LINE, nth}, {integer, LINE, 2}}}}

3) 匿名
{'fun', LINE, {clauses, [Rep(F1),Rep(F2),...,Rep(Fk)]}}
例如:
F = fun() -> ok end.
{match, LINE, {var, LINE, 'F'}, {'fun', LINE, {clauses, [{clause, LINE, [],[], [{atom, LINE, ok}]}]}}}
3. 表达式

(1) = 操作

A = V
{match, LINE, Rep(P), Rep(V)}
例如:
Info = "hello world"
{match, LINE, {var, LINE, 'Info'}, {string, LINE, "hello world"}}
(2) P1 Op P2
{op, LINE, Op, Rep(P1), Rep(P2)}
例如: Var >= 10
{op, LINE, '>=', {var, LINE, 'Var'}, {integer, LINE, 10}}
(3) FA
Function(A1, A2, ... Ak)
{call, LINE, Rep(Function), [Rep(A1), ..., Rep(Ak)]}
例如:
format("~p~n", [Info]).
{call, Line, {atom, LINE, format}, [{string, LINE, "~p~n"}, {cons, LINE, {var, LINE, 'Info'}, {nil, LINE}}]}
(4)  MFA
Module:Function(A1, A2,... Ak).
{call, LINE, {remote, LINE, Rep(Module), Rep(Function)}, [Rep(A1), Rep(A2)]}.
例如:
lager:error("~p~n", [Info]).
{call, LINE, {remote, LINE, {atom, LINE, lager}, {atom, LINE, error}},
             [{string, LINE, "~p~n"}, {cons, LINE, {var, LINE, 'Info'}, {nil, LINE}}]}
(5) catch
catch V
{'catch', LINE, Rep(V)}
例如:
catch Info = "hello world"
{'catch', LINE, {match, LINE, {var, LINE, 'Info'}, {string, LINE, "hello world"}}}
(6) case
case Express of
    C1;
    C2;
    ...
    Ck
end
{'case', LINE, Rep(Express), [Rep(C1), Rep(C2),... Rep(Ck)]}
4. 语句
(1) P -> B   P表示一个模式, B为实际执行语句 常见于case/if语句
{clause, LINE, [Rep(P)], [], [Rep(B)]}
例如:
debug ->
    lager:debug("~p~n", [Info])

{clause, LINE, [{atom, LINE, debug}], [], 
               [{call, LINE, {remote, LINE, {atom, LINE, lager}, {atom, LINE, error}},
                             [{string, LINE, "~p~n"}, {cons, LINE, {var, LINE, 'Info'}, {nil, LINE}}]}]}
(2) P when G -> B   P表示一个模式匹配, G表示一个断言, B为执行语句
{clause, LINE, [Rep(P)], [Rep(G)], [Rep(B)]}
(3). (P1, P2, ..., Pk) -> B   Pk表示一个模式, B为实际执行语句, 常见于函数
{clause, LINE, [Rep(P1),Rep(P2),..., Rep(Pk)], [], [Rep(B)]}
例如
(Level, Info) ->
    lager:Level("~p~n", [Info])

{clause, LINE, [{var, LINE, 'Level'}, {var, LINE, 'Info'}], [], 
               [{call, LINE, {remote, LINE, {atom, LINE, lager}, {var, LINE, 'Level'}},
                             [{string, LINE, "~p~n"}, {cons, LINE, {var, LINE, 'Info'}, {nil, LINE}}]}]}
(4). (P1, P2, ..., Pk) when G1,G2,...,Gk -> B  Pk表示一个模式, G表示一个断言 B为实际执行语句, 常见于函数
{clause, LINE, [Rep(P1), Rep(P2), ..., Rep(Pk)], [[Rep(G1), Rep(G2), ... Rep(G3)]], [Rep(B)]}

(Level, Info) when Level >= 1, Level =< 3 ->
    lager:info("~p~n", [Info])

{clause, LINE, [{var, LINE, 'Var'}, {var, LINE, 'Info'}],
               [[{op, LINE, '>=', {var, LINE, 'Level'}, {integer, LINE, 1}},
                 {op, LINE, '=<', {var, LINE, 'Level'}, {integer, LINE, 3}}]],
               [{call, LINE, {remote, LINE, {atom, LINE, lager}, {atom, LINE, info}},
                             [{string, LINE, "~p~n"}, {cons, LINE, {var, LINE, 'Info'}, {nil, LINE}}]}]}
(5). (P1, P2, ..., Pk) when G1;G2;...;Gk -> B
{clause, LINE, [Rep(P1), Rep(P2), ..., Rep(Pk)], [[Rep(G1)], [Rep(G2)], ... [Rep(G3)]], [Rep(B)]}



© 著作权归作者所有

共有 人打赏支持
hncscwc
粉丝 64
博文 66
码字总数 76137
作品 0
杭州
程序员
Netty之Codec的Decoders和Encoders概述

Netty之Codec的Decoders和Encoders概述 A codec is made up of two parts: Decoder Encoder This should make it clear that the decoder is for inbound and the encoder is for outbound......

秋风醉了 ⋅ 2014/06/22 ⋅ 2

解析Erlang日志组件lager的lager_transform模块

使用 lager 的时候,在编译应用的时候,需要加入选项 {parsetransform, lagertransform} erlc 会在编译你的项目源代码的时候,把生成的 abstract format forms 交给 lagertransform 模块的 ...

智深 ⋅ 2013/03/19 ⋅ 2

csv文件定义:RFC 4180

INFORMATIONAL Network Working Group Y. Shafranovich Request for Comments: 4180 SolidMatrix Technologies, Inc. Category: Informational October 2005 Common Format and MIME Type fo......

余二五 ⋅ 2017/11/16 ⋅ 0

Java中Calendar的使用方法

package cn.outofmemory.codes.Date; import java.util.Calendar; import java.util.Date; public class CalendarDemo { public static void main(String[] args) { Calendar calendar=Calen......

张欢19933 ⋅ 2016/02/23 ⋅ 0

四则运算法则表延伸 - 工厂方法模式

工厂方法模式 简介 定义了一个创建对象的抽象方法,由子类决定要实例化的类 工厂方法的模式将对象的实例化推迟到子类 组成角色 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是...

草帽行者 ⋅ 2016/05/06 ⋅ 0

Hive中的ObjectInspector设计

ObjectInspector是Hive中一个咋一看比较令人困惑的概念,当初读Hive源代码时,花了很长时间才理解。 当读懂之后,发现ObjectInspector作用相当大,它解耦了数据使用和数据格式,从而提高了代...

choulanlan ⋅ 2016/11/25 ⋅ 0

Android处理java的date数据的问题

背景 直接在接口中转Date对象时候,Gson默认只会序列化/反序列化 Date().toString()后的字符串,类似 Oct 16, 2015 12:28:22 PM,使用gson解析后台返回的数据时,无意发现了一个问题,如果使...

我家有宝 ⋅ 2016/09/09 ⋅ 0

如何实现Java的接口

9.2 实现接口 接口的实现完全取决于具体的应用。从这一点讲,实现接口是“面向应用”的编程。利用接口,可以实现间接多重继承。接口本身也具有多重继承性。接口还可以用作参数类型。这一小节...

高永强 ⋅ 2009/07/17 ⋅ 0

[Erlang 0113] Elixir 编译流程梳理

注意:目前Elixir版本还不稳定,代码调整较大,本文随时失效 之前简单演示过如何从elixir ex代码生成并运行Erlang代码,下面仔细梳理一遍elixir文件的编译过程,书接上文,从elixir的代码切入,这一...

唐玄奘 ⋅ 01/03 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

DevOps 资讯 | PostgreSQL 的时代到来了吗 ?

PostgreSQL是对象-关系型数据库,BSD 许可证。拼读为"post-gress-Q-L"。 作者: Tony Baer 原文: Has the time finally come for PostgreSQL?(有删节) 近30年来 PostgreSQL 无疑是您从未听...

RiboseYim ⋅ 8分钟前 ⋅ 0

Cube、Cuboid 和 Cube Segment

1.Cube (或Data Cube),即数据立方体,是一种常用于数据分析与索引的技术;它可以对原始数据建立多维度索引。通过 Cube 对数据进行分析,可以大大加快数据的查询效率 2.Cuboid 在 Kylin 中特...

无精疯 ⋅ 46分钟前 ⋅ 0

github太慢

1:用浏览器访问 IPAddress.com or http://tool.chinaz.com 使用 IP Lookup 工具获得github.com和github.global.ssl.fastly.net域名的ip地址 2:/etc/hosts文件中添加如下格式(IP最好自己查一...

whoisliang ⋅ 48分钟前 ⋅ 0

非阻塞同步之 CAS

为解决线程安全问题,互斥同步相当于以时间换空间。多线程情况下,只有一个线程可以访问同步代码。这种同步也叫阻塞同步(Blocking Synchronization). 这种同步属于一种悲观并发策略。认为只...

长安一梦 ⋅ 59分钟前 ⋅ 0

云计算的选择悖论如何对待?

人们都希望在工作和生活中有所选择。但心理学家的调查研究表明,在多种选项中进行选择并不一定会使人们更快乐,甚至不会产生更好的决策。心理学家Barry Schwartz称之为“选择悖论”。云计算为...

linux-tao ⋅ 今天 ⋅ 0

Redis 注册为 Windows 服务

Redis 注册为 Windows 服务 redis 注册为 windows 服务相关命令 注册服务 redis-server.exe –service-install redis.windows.conf 删除服务 redis-server –service-uninstall 启动服务 re......

Os_yxguang ⋅ 今天 ⋅ 0

世界那么大,语言那么多,为什么选择Micropython,它的优势在哪?

最近国内MicroPython风靡程序界,是什么原因导致它这么火呢?是因为他功能强大,遵循Mit协议开源么? 错!因为使用它真的是太舒服了!!! Micropython的由来,这得益于Damien George这位伟大...

bodasisiter ⋅ 今天 ⋅ 0

docker 清理总结

杀死所有正在运行的容器 docker kill $(docker ps -a -q) 删除所有已经停止的容器(docker rm没有加-f参数,运行中的容器不会删掉) docker rm $(docker ps -a -q) 删除所有未打 dangling 标...

vvx1024 ⋅ 今天 ⋅ 0

关于学习

以前学车的时候,教练说了这样的一句话:如果一个人坐在车上一直学,一直学,反而不如大家轮流着学。因为一个人一直学,就没有给自己留空间来反思和改进。而轮流着学的时候大家下来之后思考上...

mskk ⋅ 今天 ⋅ 0

压缩工具之gzip-bzip2-xz

win下常见压缩工具:rar zip 7z linux下常见压缩工具:zip gz bz2 xz tar.gz tar.bz2 tar.xz gzip 不支持目录压缩 gzip 1.txt #压缩。执行后1.txt消失,生成1.txt.gz压缩文件 gzip -d 1.txt....

ZHENG-JY ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部