The Erlang Parser之erl_parse

这篇续前一篇,来介绍erl_parse这个重头模块。

先看看这个模块的三个重头方法:

parse_form(Tokens) -> {ok, AbsForm} | {error, ErrorInfo}

Types:

Tokens = [token()]
AbsForm = abstract_form()
ErrorInfo = error_info()
This function parses Tokens as if it were a form. It returns: //针对form

{ok, AbsForm}
The parsing was successful. AbsForm is the abstract form of the parsed form.

{error, ErrorInfo}
An error occurred.

parse_exprs(Tokens) -> {ok, ExprList} | {error, ErrorInfo}

Types:

Tokens = [token()]
ExprList = [abstract_expr()]
ErrorInfo = error_info()
This function parses Tokens as if it were a list of expressions. It returns: //针对list

{ok, ExprList}
The parsing was successful. ExprList is a list of the abstract forms of the parsed expressions.

{error, ErrorInfo}
An error occurred.

parse_term(Tokens) -> {ok, Term} | {error, ErrorInfo}

Types:

Tokens = [token()]
Term = term()
ErrorInfo = error_info()
This function parses Tokens as if it were a term. It returns: //针对term

{ok, Term}
The parsing was successful. Term is the Erlang term corresponding to the token list.

{error, ErrorInfo}
An error occurred.

 分别注意这三个方法是针对不同的tokens进行parse的。

下面给出两个例子

{ok, Tokens, EndLine} = erl_scan:string("test() -> ok.").
{ok,[{atom,1,test},
     {'(',1},
     {')',1},
     {'->',1},
     {atom,1,ok},
     {dot,1}],
    1}
erl_parse:parse_form(Tokens).
{ok,{function,1,test,0,[{clause,1,[],[],[{atom,1,ok}]}]}}

 

{ok, Tokens2, EndLine2} = erl_scan:string("[a,b,c].").
{ok,[{'[',1},
     {atom,1,a},
     {',',1},
     {atom,1,b},
     {',',1},
     {atom,1,c},
     {']',1},
     {dot,1}],
    1}
erl_parse:parse_exprs(Tokens2).
{ok,[{cons,1,
           {atom,1,a},
           {cons,1,{atom,1,b},{cons,1,{atom,1,c},{nil,1}}}}]}
erl_parse:parse_term(Tokens2).
{ok,[a,b,c]}

 再看看下面这个不常用的方法

tokens(AbsTerm) -> Tokens
tokens(AbsTerm, MoreTokens) -> Tokens

Types:

AbsTerm = abstract_expr()
MoreTokens = Tokens = [token()]
This function generates a list of tokens representing the abstract form AbsTerm of an expression. Optionally, it appends MoreTokens.

 例子

Expr.
{cons,1,
      {atom,1,a},
      {cons,1,{atom,1,b},{cons,1,{atom,1,c},{nil,1}}}}
erl_parse:tokens(Expr).
[{'[',1},
 {atom,1,a},
 {',',1},
 {atom,1,b},
 {',',1},
 {atom,1,c},
 {']',1}]

 其实就是把表达式重新解析成tokens格式

 给出别人写的一个demo

-module(file_2).
-export([compile/1]).
-spec file_2:compile(Code) -> {ok, Module} | {error} when
      Code:: string(),
      Module :: module().
compile(Code) ->
    {ok, M, Bin} = compile:forms(scan_tokens(Code)),
    case code:load_binary(M, "nofile", Bin) of
        {module, Module} ->
            {ok, Module};
        {error, _} ->
            {error}
    end.
scan_tokens(Code) ->
    case erl_scan:tokens([], Code, 1) of
        {done, {ok, Token, _}, Remain} ->
            {ok,Form} = erl_parse:parse_form(Token),
            [Form | scan_tokens(Remain)];
        {more, _} ->
            []
    end.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值