erl_parse.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,387 行 · 第 1/5 页

ERL
1,387
字号
    {'fun',Line,{clauses,check_clauses(Cs, 'fun', Arity)}}.check_clauses(Cs, Name, Arity) ->     mapl(fun ({clause,L,N,As,G,B}) when N =:= Name, length(As) =:= Arity ->		 {clause,L,As,G,B};	     ({clause,L,_N,_As,_G,_B}) ->		 return_error(L, "head mismatch") end, Cs).build_try(L,Es,Scs,{Ccs,As}) ->    {'try',L,Es,Scs,Ccs,As}.%% mapl(F,List)%% an alternative map which always maps from left to right%% and makes it possible to interrupt the mapping with throw on%% the first occurence from left as expected.%% can be removed when the jam machine (and all other machines)%% uses the standardized (Erlang 5.0) evaluation order (from left to right)mapl(F, [H|T]) ->	V = F(H),	[V | mapl(F,T)];mapl(_, []) ->	[].%% normalise(AbsTerm)%% abstract(Term)%%  Convert between the abstract form of a term and a term.normalise({char,_,C}) -> C;normalise({integer,_,I}) -> I;normalise({float,_,F}) -> F;normalise({atom,_,A}) -> A;normalise({string,_,S}) -> S;normalise({nil,_}) -> [];normalise({bin,_,Fs}) ->    {value, B, _} =	eval_bits:expr_grp(Fs, [],			   fun(E, _) ->				   {value, normalise(E), []}			   end, [], true),    B;normalise({cons,_,Head,Tail}) ->    [normalise(Head)|normalise(Tail)];normalise({tuple,_,Args}) ->    list_to_tuple(normalise_list(Args));%% Atom dot-notation, as in 'foo.bar.baz'normalise({record_field,_,_,_}=A) ->    case package_segments(A) of	error -> erlang:fault({badarg, A});	As -> list_to_atom(packages:concat(As))    end;%% Special case for unary +/-.normalise({op,_,'+',{char,_,I}}) -> I;normalise({op,_,'+',{integer,_,I}}) -> I;normalise({op,_,'+',{float,_,F}}) -> F;normalise({op,_,'-',{char,_,I}}) -> -I;		%Weird, but compatible!normalise({op,_,'-',{integer,_,I}}) -> -I;normalise({op,_,'-',{float,_,F}}) -> -F;normalise(X) -> erlang:fault({badarg, X}).normalise_list([H|T]) ->    [normalise(H)|normalise_list(T)];normalise_list([]) ->    [].abstract(T) when is_integer(T) -> {integer,0,T};abstract(T) when is_float(T) -> {float,0,T};abstract(T) when is_atom(T) -> {atom,0,T};abstract([]) -> {nil,0};abstract(B) when is_binary(B) ->    {bin, 0, lists:map(fun(Byte) ->			       {bin_element, 0,				{integer, 0, Byte}, default, default}		       end,		       binary_to_list(B))};abstract([C|T]) when is_integer(C), 0 =< C, C < 256 ->    abstract_string(T, [C]);abstract([H|T]) ->    {cons,0,abstract(H),abstract(T)};abstract(Tuple) when is_tuple(Tuple) ->    {tuple,0,abstract_list(tuple_to_list(Tuple))}.abstract_string([C|T], String) when is_integer(C), 0 =< C, C < 256 ->    abstract_string(T, [C|String]);abstract_string([], String) ->    {string, 0, lists:reverse(String)};abstract_string(T, String) ->    not_string(String, abstract(T)).not_string([C|T], Result) ->    not_string(T, {cons, 0, {integer, 0, C}, Result});not_string([], Result) ->    Result.abstract_list([H|T]) ->    [abstract(H)|abstract_list(T)];abstract_list([]) ->    [].%%% abstract/2 keeps the line numberabstract(T, Line) when is_integer(T) -> {integer,Line,T};abstract(T, Line) when is_float(T) -> {float,Line,T};abstract(T, Line) when is_atom(T) -> {atom,Line,T};abstract([], Line) -> {nil,Line};abstract(B, Line) when is_binary(B) ->    {bin, Line, lists:map(fun(Byte) ->			       {bin_element, Line,				{integer, Line, Byte}, default, default}		       end,		       binary_to_list(B))};abstract([C|T], Line) when is_integer(C), 0 =< C, C < 256 ->    abstract_string(T, [C], Line);abstract([H|T], Line) ->    {cons,Line,abstract(H, Line),abstract(T, Line)};abstract(Tuple, Line) when is_tuple(Tuple) ->    {tuple,Line,abstract_list(tuple_to_list(Tuple), Line)}.abstract_string([C|T], String, Line) when is_integer(C), 0 =< C, C < 256 ->    abstract_string(T, [C|String], Line);abstract_string([], String, Line) ->    {string, Line, lists:reverse(String)};abstract_string(T, String, Line) ->    not_string(String, abstract(T, Line), Line).not_string([C|T], Result, Line) ->    not_string(T, {cons, Line, {integer, Line, C}, Result}, Line);not_string([], Result, _Line) ->    Result.abstract_list([H|T], Line) ->    [abstract(H, Line)|abstract_list(T, Line)];abstract_list([], _Line) ->    [].%% tokens(AbsTerm) -> [Token]%% tokens(AbsTerm, More) -> [Token]%%  Generate a list of tokens representing the abstract term.tokens(Abs) ->    tokens(Abs, []).tokens({char,L,C}, More) -> [{char,L,C}|More];tokens({integer,L,N}, More) -> [{integer,L,N}|More];tokens({float,L,F}, More) -> [{float,L,F}|More];tokens({atom,L,A}, More) -> [{atom,L,A}|More];tokens({var,L,V}, More) -> [{var,L,V}|More];tokens({string,L,S}, More) -> [{string,L,S}|More];tokens({nil,L}, More) -> [{'[',L},{']',L}|More];tokens({cons,L,Head,Tail}, More) ->    [{'[',L}|tokens(Head, tokens_tail(Tail, More))];tokens({tuple,L,[]}, More) ->    [{'{',L},{'}',L}|More];tokens({tuple,L,[E|Es]}, More) ->    [{'{',L}|tokens(E, tokens_tuple(Es, line(E), More))].tokens_tail({cons,L,Head,Tail}, More) ->    [{',',L}|tokens(Head, tokens_tail(Tail, More))];tokens_tail({nil,L}, More) ->    [{']',L}|More];tokens_tail(Other, More) ->    L = line(Other),    [{'|',L}|tokens(Other, [{']',L}|More])].tokens_tuple([E|Es], Line, More) ->    [{',',Line}|tokens(E, tokens_tuple(Es, line(E), More))];tokens_tuple([], Line, More) ->    [{'}',Line}|More].%% Give the relative precedences of operators.inop_prec('=') -> {150,100,100};inop_prec('!') -> {150,100,100};inop_prec('orelse') -> {160,150,150};inop_prec('andalso') -> {200,160,160};inop_prec('==') -> {300,200,300};inop_prec('/=') -> {300,200,300};inop_prec('=<') -> {300,200,300};inop_prec('<') -> {300,200,300};inop_prec('>=') -> {300,200,300};inop_prec('>') -> {300,200,300};inop_prec('=:=') -> {300,200,300};inop_prec('=/=') -> {300,200,300};inop_prec('++') -> {400,300,300};inop_prec('--') -> {400,300,300};inop_prec('+') -> {400,400,500};inop_prec('-') -> {400,400,500};inop_prec('bor') -> {400,400,500};inop_prec('bxor') -> {400,400,500};inop_prec('bsl') -> {400,400,500};inop_prec('bsr') -> {400,400,500};inop_prec('or') -> {400,400,500};inop_prec('xor') -> {400,400,500};inop_prec('*') -> {500,500,600};inop_prec('/') -> {500,500,600};inop_prec('div') -> {500,500,600};inop_prec('rem') -> {500,500,600};inop_prec('band') -> {500,500,600};inop_prec('and') -> {500,500,600};inop_prec('#') -> {800,700,800};inop_prec(':') -> {900,800,900};inop_prec('.') -> {900,900,1000}.preop_prec('catch') -> {0,100};preop_prec('+') -> {600,700};preop_prec('-') -> {600,700};preop_prec('bnot') -> {600,700};preop_prec('not') -> {600,700};preop_prec('#') -> {700,800}.func_prec() -> {800,700}.max_prec() -> 1000.-file("/ldisk/daily_build/otp_prebuild_r11b.2007-06-11_19/otp_src_R11B-5/bootstrap/lib/parsetools/include/yeccpre.hrl", 0).%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id $%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The parser generator will insert appropriate declarations before this line.%parse(Tokens) ->    yeccpars0(Tokens, false).parse_and_scan({F, A}) -> % Fun or {M, F}    yeccpars0([], {F, A});parse_and_scan({M, F, A}) ->    yeccpars0([], {{M, F}, A}).format_error(Message) ->    case io_lib:deep_char_list(Message) of	true ->	    Message;	_ ->	    io_lib:write(Message)    end.% To be used in grammar files to throw an error message to the parser% toplevel. Doesn't have to be exported!-compile({nowarn_unused_function,{return_error,2}}).return_error(Line, Message) ->    throw({error, {Line, ?MODULE, Message}}).yeccpars0(Tokens, MFA) ->    try yeccpars1(Tokens, MFA, 0, [], [])    catch         throw: {error, {_Line, ?MODULE, _M}} = Error ->                    Error % probably from return_error/1    end.% Don't change yeccpars1/6 too much, it is called recursively by yeccpars2/8!yeccpars1([Token | Tokens], Tokenizer, State, States, Vstack) ->    yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens,	      Tokenizer);yeccpars1([], {F, A}, State, States, Vstack) ->    case apply(F, A) of        {ok, Tokens, _Endline} ->	    yeccpars1(Tokens, {F, A}, State, States, Vstack);        {eof, _Endline} ->            yeccpars1([], false, State, States, Vstack);        {error, Descriptor, _Endline} ->            {error, Descriptor}    end;yeccpars1([], false, State, States, Vstack) ->    yeccpars2(State, '$end', States, Vstack, {'$end', 999999}, [], false).

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?