标签:style blog http color io os 使用 ar strong
Erlang Abstract Format并不难懂,只是枯燥一点罢了,如果把Abstract Format的文档翻译出来,其实就是Erlang教科书中语法入门的部分. Erlang Abstract Format实际上是用Erlang代码的AST,下面通过一些真切的实例代码了解一下它的一些细节.
首先,Erlang Abstract Format里面包含一些概念,我会在下面的描述中把涉及到的概念字体加粗.请注意概念之间的层次关系.Erlang代码本身使用非常扁平的module组织,每一个module是由一系列forms组成的.这些forms分成两大类:attributes和函数声明 见下图.

attributes相对比较简单,我们先从一个只有attributes没有任何函数声明的module开始
-module(k). -compile(export_all). -compile({parse_transform,print_form}). -export([test/0]). -url("http://cnblogs.com/me-sa/"). -record(student,{class,id}). -record(player,{id=0,name=[],level}).
[{attribute,1,file,{"k.erl",1}},
{attribute,1,module,k},
{attribute,2,compile,export_all},
{attribute,4,export,[{test,0}]},
{attribute,5,url,"http://cnblogs.com/me-sa/"},
{attribute,6,record,
{student,[{record_field,6,{atom,6,class}},
{record_field,6,{atom,6,id}}]}},
{attribute,7,record,
{player,[{record_field,7,{atom,7,id},{integer,7,0}},
{record_field,7,{atom,7,name},{nil,7}},
{record_field,7,{atom,7,level}}]}},
{eof,10}]

-module(a). -compile(export_all). -export([test/0]). -record(student,{class,id}). -record(player,{id=0,name=[],level}). test()-> "hello world!". test(a,[1,2]) -> "a:[1,2]"; test(12.5,100)-> "test". test([]) -> empty; test(abc) -> "atom test". foo(a)-> {b,100}. bar({1,2},12)-> [1,2,3,4,5,6]. k(Num) when Num >1000 -> bigger_than_100; k(Num) -> whatever. call(1000)-> k(1000); call(1002)-> erlang:now().
[{attribute,1,file,{"a.erl",1}},
{attribute,1,module,a},
{attribute,2,compile,export_all},
{attribute,4,export,[{test,0}]},
{attribute,6,record,
{student,
[{record_field,6,{atom,6,class}},{record_field,6,{atom,6,id}}]}},
{attribute,7,record,
{player,
[{record_field,7,{atom,7,id},{integer,7,0}},
{record_field,7,{atom,7,name},{nil,7}},
{record_field,7,{atom,7,level}}]}},
{function,10,test,0,[{clause,10,[],[],[{string,11,"hello world!"}]}]},
{function,13,test,2,
[{clause,13,
[{atom,13,a},
{cons,13,{integer,13,1},{cons,13,{integer,13,2},{nil,13}}}],
[],
[{string,14,"a:[1,2]"}]},
{clause,15,
[{float,15,12.5},{integer,15,100}],
[],
[{string,16,"test"}]}]},
{function,18,test,1,
[{clause,18,[{nil,18}],[],[{atom,19,empty}]},
{clause,20,[{atom,20,abc}],[],[{string,21,"atom test"}]}]},
{function,24,foo,1,
[{clause,24,
[{atom,24,a}],
[],
[{tuple,25,[{atom,25,b},{integer,25,100}]}]}]},
{function,27,bar,2,
[{clause,27,
[{tuple,27,[{integer,27,1},{integer,27,2}]},{integer,27,12}],
[],
[{cons,28,
{integer,28,1},
{cons,28,
{integer,28,2},
{cons,28,
{integer,28,3},
{cons,28,
{integer,28,4},
{cons,28,
{integer,28,5},
{cons,28,{integer,28,6},{nil,28}}}}}}}]}]},
{function,30,k,1,
[{clause,30,
[{var,30,‘Num‘}],
[[{op,30,‘>‘,{var,30,‘Num‘},{integer,30,1000}}]],
[{atom,31,bigger_than_100}]},
{clause,32,[{var,32,‘Num‘}],[],[{atom,33,whatever}]}]},
{function,36,call,1,
[{clause,36,
[{integer,36,1000}],
[],
[{call,37,{atom,37,k},[{integer,37,1000}]}]},
{clause,38,
[{integer,38,1002}],
[],
[{call,39,{remote,39,{atom,39,erlang},{atom,39,now}},[]}]}]},
{eof,41}]
|
1
2
3
|
{function,18,test,1, [{clause,18,[{nil,18}],[],[{atom,19,empty}]}, {clause,20,[{atom,20,abc}],[],[{string,21,"atom
test"}]}]}, |
|
1
2
3
4
5
6
7
8
9
10
|
Clojure
1.4.0user=>
(defn make_a_set ([x]
#{x}) ([x,y]
#{x,y}))#‘user/make_a_setuser=>
(make_a_set 12)#{12}user=>
(make_a_set 12 23)#{12
23}user=> |
[[{op,30,‘>‘,{var,30,‘Num‘},{integer,30,1000}}]].
|
1
2
3
4
5
6
7
8
9
10
|
7>
E= fun(Code)->
{_,Tokens,_}=erl_scan:string(Code),rp(erl_parse:parse_exprs(Tokens)) end.#Fun<erl_eval.6.80484245>8>
E("
A = lists:seq(1,10).").{ok,[{match,1, {var,1,‘A‘}, {call,1, {remote,1,{atom,1,lists},{atom,1,seq}}, [{integer,1,1},{integer,1,10}]}}]}ok10>
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
Eshell
V5.10.2 (abort with ^G)1>
E= fun(Code)->
{_,Tokens,_}=erl_scan:string(Code),rp(erl_parse:parse_exprs(Tokens)) end.#Fun<erl_eval.6.80484245>2>
E("[Item
|| Item<- [1,2,3,4],Item>2 ].").{ok,[{lc,1, {var,1,‘Item‘}, [{generate,1, {var,1,‘Item‘}, {cons,1, {integer,1,1}, {cons,1, {integer,1,2}, {cons,1,{integer,1,3},{cons,1,{integer,1,4},{nil,1}}}}}}, {op,1,‘>‘,{var,1,‘Item‘},{integer,1,2}}]}]}ok3> 7>
E= fun(Code)->
{_,Tokens,_}=erl_scan:string(Code),rp(erl_parse:parse_exprs(Tokens)) end.#Fun<erl_eval.6.80484245>8>
E("<<A:8,B/binary>>
= <<1,2,3,4>>.").{ok,[{match,1, {bin,1, [{bin_element,1,{var,1,‘A‘},{integer,1,8},default}, {bin_element,1,{var,1,‘B‘},default,[binary]}]}, {bin,1, [{bin_element,1,{integer,1,1},default,default}, {bin_element,1,{integer,1,2},default,default}, {bin_element,1,{integer,1,3},default,default}, {bin_element,1,{integer,1,4},default,default}]}}]}ok |
|
1
2
3
4
5
6
7
|
4>
E("[a,b,c,d].").{ok,[{cons,1, {atom,1,a}, {cons,1, {atom,1,b}, {cons,1,{atom,1,c},{cons,1,{atom,1,d},{nil,1}}}}}]}ok |

3> {ok, MTs, _} = erl_scan:string("-module(t)."). {ok,[{‘-‘,1}, {atom,1,module}, {‘(‘,1}, {atom,1,t}, {‘)‘,1}, {dot,1}], 1} 4> {ok, ETs, _} = erl_scan:string("-export([say/0])."). {ok,[{‘-‘,1}, {atom,1,export}, {‘(‘,1}, {‘[‘,1}, {atom,1,say}, {‘/‘,1}, {integer,1,0}, {‘]‘,1}, {‘)‘,1}, {dot,1}], 1} 5> {ok, FTs, _} = erl_scan:string("say() -> \"hello_world!!\"."). {ok,[{atom,1,say}, {‘(‘,1}, {‘)‘,1}, {‘->‘,1}, {string,1,"hello_world!!"}, {dot,1}], 1} 6> Forms= [begin {ok,R}=erl_parse:parse_form(Item),R end || Item<-[MTs,ETs,FTs]]. [{attribute,1,module,t}, {attribute,1,export,[{say,0}]}, {function,1,say,0, [{clause,1,[],[],[{string,1,"hello_world!!"}]}]}] 7> {ok, t, Bin} = compile:forms(Forms). {ok,t, <<70,79,82,49,0,0,1,224,66,69,65,77,65,116,111,109,0,0,0, 45,0,0,0,5,1,116,...>>} 8> code:load_binary(t,"nofile",Bin). {module,t} 9> t:say(). "hello_world!!" 10>


[Erlang 0110] Erlang Abstract Format , Part 1
标签:style blog http color io os 使用 ar strong
原文地址:http://blog.csdn.net/ligaorenvip/article/details/39226401