Erlang 我对erl_parse:parse_form有什么错?
我编写了一个Hello World模块并成功编译了它。然后我试着通过使用erl_扫描和erl_解析来学习引擎盖下的东西Erlang 我对erl_parse:parse_form有什么错?,erlang,Erlang,我编写了一个Hello World模块并成功编译了它。然后我试着通过使用erl_扫描和erl_解析来学习引擎盖下的东西 -module(useless). -export([hello/0]). hello() -> io:format("hello world\n"). 然后我输入erls
-module(useless).
-export([hello/0]).
hello() -> io:format("hello world\n").
然后我输入erl
shell
{ok, S} = file:read_file("useless.erl").
及
它显然很好用。但是,当我尝试使用erl\u parse:parse\u form(T)时。
它给出了{error,{2,erl_parse,[“前面的语法错误:”,“-”]}
我做错了什么
编辑:
该模块很有帮助
也很酷。函数erl\u parse:parse\u form/1只在一种表单上工作。因此,您必须首先将erl_scan:string/1的结果拆分为各个表单 您可以使用erl_scan:tokens来实现这一点(此代码有效,但我不确定我是否正确使用了该函数):
-模块(无用)。
-出口([eval/1])。
评估(文件)->
{ok,B}=file:read_file(file),
表单=扫描(erl\U扫描:令牌([],二进制\U到\U列表(B),1),[]),
F=fun(X)->{ok,Y}=erl_parse:parse_form(X),Y end,
[F(X)| | X
扫描(erl|U扫描:令牌([],S,N),[T|Res]);
扫描(分辨率)->
列表:反向(Res)。
罗伯特建议使用erl_scan:tokens/3
的重入功能。
此函数上的文档不明确,我花了一些时间才理解初始字符串需要通过eof
关闭(如果不是,则tokens函数运行一个无止境的循环)
这是我终于想出的代码,希望能对别人有所帮助
eval(File)->
{ok, Data} = file:read_file(File),
String=erlang:binary_to_list(Data),
scan(String).
scan(String) when is_list(String)->
scan(String++eof,[]). %% appended eof
scan({done, Result, LeftOverChars},Acc)->
scan_done(Result,LeftOverChars,Acc);
scan({more, Continuation},Acc)->
scan(erl_scan:tokens(Continuation,[],1),Acc);
scan(String,Acc) when is_list(String)->
scan(erl_scan:tokens([],String,1),Acc).
scan_done({error,ErrorMsg,_Location},_LeftOverChars,_Acc)->
ErrorMsg;
scan_done({eof,Location},LeftOverChars,Acc)->
Acc;
scan_done({ok,Tokens,Location},LeftOverChars,Acc)->
case erl_parse:parse_form(Tokens) of
{ok,R}->scan(LeftOverChars,Acc++[R]);
{error,R}->scan(LeftOverChars,R)
end.
erl_scan:tokens/3
是可重入的,因此它可以处理以块的形式输入字符,并继续收集,直到获得所需的所有字符(最多一个“.”)。您不以这种方式使用它,但您使用它的方式是有效的。您可以做的一个改进是在{ok,Ts,line}中获取从erl\u scan:tokens
返回的行号
返回值,并在下一次调用erl\u scan:tokens
时使用该值。我根据Robert的建议修改了代码。希望它的效果更好:o)因为结果中的行号现在是正确的。
-module(useless).
-export([eval/1]).
eval(File) ->
{ok, B} = file:read_file(File),
Forms = scan(erl_scan:tokens([],binary_to_list(B),1),[]),
F = fun(X) -> {ok,Y} = erl_parse:parse_form(X), Y end,
[F(X) || X <- Forms].
scan({done,{ok,T,N},S},Res) ->
scan(erl_scan:tokens([],S,N),[T|Res]);
scan(_,Res) ->
lists:reverse(Res).
eval(File)->
{ok, Data} = file:read_file(File),
String=erlang:binary_to_list(Data),
scan(String).
scan(String) when is_list(String)->
scan(String++eof,[]). %% appended eof
scan({done, Result, LeftOverChars},Acc)->
scan_done(Result,LeftOverChars,Acc);
scan({more, Continuation},Acc)->
scan(erl_scan:tokens(Continuation,[],1),Acc);
scan(String,Acc) when is_list(String)->
scan(erl_scan:tokens([],String,1),Acc).
scan_done({error,ErrorMsg,_Location},_LeftOverChars,_Acc)->
ErrorMsg;
scan_done({eof,Location},LeftOverChars,Acc)->
Acc;
scan_done({ok,Tokens,Location},LeftOverChars,Acc)->
case erl_parse:parse_form(Tokens) of
{ok,R}->scan(LeftOverChars,Acc++[R]);
{error,R}->scan(LeftOverChars,R)
end.