edoc_parser.erl

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

ERL
1,732
字号
-module(edoc_parser).-export([parse/1, parse_and_scan/1, format_error/1]).-file("edoc_parser.yrl", 200).%% ========================== -*-Erlang-*- =============================%% EDoc function specification parser, generated from the file%% "edoc_parser.yrl" by the Yecc parser generator.%%%% Copyright (C) 2002-2005 Richard Carlsson%%%% This library is free software; you can redistribute it and/or modify%% it under the terms of the GNU Lesser General Public License as%% published by the Free Software Foundation; either version 2 of the%% License, or (at your option) any later version.%%%% This library is distributed in the hope that it will be useful, but%% WITHOUT ANY WARRANTY; without even the implied warranty of%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU%% Lesser General Public License for more details.%%%% You should have received a copy of the GNU Lesser General Public%% License along with this library; if not, write to the Free Software%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307%% USA%% ====================================================================-export([parse_spec/2, parse_typedef/2, parse_throws/2, parse_ref/2,	 parse_see/2, parse_param/2]).-include("edoc_types.hrl").%% Multiple entry point hack:start_spec(Ts, L) -> run_parser(Ts, L, start_spec).start_typedef(Ts, L) -> run_parser(Ts, L, start_typedef).start_throws(Ts, L) -> run_parser(Ts, L, start_throws).start_ref(Ts, L) -> run_parser(Ts, L, start_ref).%% Error reporting fixrun_parser(Ts, L, Start) ->    case parse([{Start,L} | Ts]) of	{error, {999999,?MODULE,_}} ->	    What = case Start of		       start_spec -> "specification";		       start_typedef -> "type definition";		       start_throws -> "exception declaration";		       start_ref -> "reference"		   end,	    {error, {L,?MODULE,["unexpected end of ", What]}};	Other -> Other    end.%% Utility functions:tok_val(T) -> element(3, T).tok_line(T) -> element(2, T).qname([A]) ->    A;    % avoid unnecessary call to packages:concat/1.qname(List) ->    list_to_atom(packages:concat(lists:reverse(List))).union(Ts) ->    case Ts of	[T] -> T;	_ -> #t_union{types = lists:reverse(Ts)}    end.annotate(T, A) -> ?add_t_ann(T, A).    %% ---------------------------------------------------------------------%% @doc EDoc type specification parsing. Parses the content of%% <a href="overview-summary.html#ftag-spec">`@spec'</a> declarations.parse_spec(S, L) ->    case edoc_scanner:string(S, L) of	{ok, Ts, _} ->	    case start_spec(Ts, L) of		{ok, Spec} ->		    Spec;		{error, E} ->		    throw_error(E, L)	    end;	{error, E, _} ->	    throw_error(E, L)    end.%% ---------------------------------------------------------------------%% @doc EDoc type definition parsing. Parses the content of%% <a href="overview-summary.html#gtag-type">`@type'</a> declarations.parse_typedef(S, L) ->    {S1, S2} = edoc_lib:split_at_stop(S),    N = edoc_lib:count($\n, S1),    L1 = L + N,    Text = edoc_lib:strip_space(S2),    {parse_typedef_1(S1, L), edoc_wiki:parse_xml(Text, L1)}.parse_typedef_1(S, L) ->    case edoc_scanner:string(S, L) of	{ok, Ts, _} ->	    case start_typedef(Ts, L) of		{ok, T} ->		    T;		{error, E} ->		    throw_error({parse_typedef, E}, L)	    end;	{error, E, _} ->	    throw_error({parse_typedef, E}, L)    end.%% ---------------------------------------------------------------------%% @doc Parses a <a%% href="overview-summary.html#References">reference</a> to a module,%% package, function, type, or applicationparse_ref(S, L) ->    case edoc_scanner:string(S, L) of	{ok, Ts, _} ->	    case start_ref(Ts, L) of		{ok, T} ->		    T;		{error, E} ->		    throw_error({parse_ref, E}, L)	    end;	{error, E, _} ->	    throw_error({parse_ref, E}, L)    end.%% ---------------------------------------------------------------------%% @doc Parses the content of%% <a href="overview-summary.html#ftag-see">`@see'</a> references.parse_see(S, L) ->    {S1, S2} = edoc_lib:split_at_stop(S),    N = edoc_lib:count($\n, S1),    L1 = L + N,    Text = edoc_lib:strip_space(S2),    {parse_ref(S1, L), edoc_wiki:parse_xml(Text, L1)}.%% ---------------------------------------------------------------------%% @doc Parses the content of%% <a href="overview-summary.html#ftag-param">`@param'</a> tags.parse_param(S, L) ->    {S1, S2} = edoc_lib:split_at_space(edoc_lib:strip_space(S)),    case edoc_lib:strip_space(S1) of	"" -> throw_error(parse_param, L);	Name -> 	    Text = edoc_lib:strip_space(S2),	    {list_to_atom(Name), edoc_wiki:parse_xml(Text, L)}    end.%% ---------------------------------------------------------------------%% @doc EDoc exception specification parsing. Parses the content of%% <a href="overview-summary.html#ftag-throws">`@throws'</a> declarations.parse_throws(S, L) ->    case edoc_scanner:string(S, L) of	{ok, Ts, _} ->	    case start_throws(Ts, L) of		{ok, Spec} ->		    Spec;		{error, E} ->		    throw_error({parse_throws, E}, L)	    end;	{error, E, _} ->	    throw_error({parse_throws, E}, L)    end.%% ---------------------------------------------------------------------throw_error({L, M, D}, _L0) ->    throw({error,L,{format_error,M,D}});throw_error({parse_spec, E}, L) ->    throw_error({"specification", E}, L);throw_error({parse_typedef, E}, L) ->    throw_error({"type definition", E}, L);throw_error({parse_ref, E}, L) ->    throw_error({"reference", E}, L);throw_error({parse_throws, E}, L) ->    throw_error({"throws-declaration", E}, L);throw_error(parse_param, L) ->    throw({error, L, "missing parameter name"});throw_error({Where, E}, L) when is_list(Where) ->    throw({error,L,{"unknown error parsing ~s: ~P.",[Where,E,15]}});throw_error(E, L) ->    %% Just in case.    throw({error,L,{"unknown parse error: ~P.",[E,15]}}).-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).% For internal use only.yeccerror(Token) ->    {error,     {element(2, Token), ?MODULE,      ["syntax error before: ", yecctoken2string(Token)]}}.yecctoken2string({atom, _, A}) -> io_lib:write(A);yecctoken2string({integer,_,N}) -> io_lib:write(N);yecctoken2string({float,_,F}) -> io_lib:write(F);yecctoken2string({char,_,C}) -> io_lib:write_char(C);yecctoken2string({var,_,V}) -> io_lib:format('~s', [V]);yecctoken2string({string,_,S}) -> io_lib:write_string(S);yecctoken2string({reserved_symbol, _, A}) -> io_lib:format('~w', [A]);yecctoken2string({_Cat, _, Val}) -> io_lib:format('~w', [Val]);yecctoken2string({'dot', _}) -> io_lib:format('~w', ['.']);yecctoken2string({'$end', _}) ->    [];yecctoken2string({Other, _}) when is_atom(Other) ->    io_lib:format('~w', [Other]);yecctoken2string(Other) ->    io_lib:write(Other).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%-file("./edoc_parser.erl", 293).yeccpars2(0, start_ref, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 2, [0 | __Ss], [__T | __Stack]);yeccpars2(0, start_spec, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 3, [0 | __Ss], [__T | __Stack]);yeccpars2(0, start_throws, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 4, [0 | __Ss], [__T | __Stack]);yeccpars2(0, start_typedef, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 5, [0 | __Ss], [__T | __Stack]);yeccpars2(0, _, _, _, __T, _, _) -> yeccerror(__T);yeccpars2(1, '$end', _, __Stack, _, _, _) -> {ok, hd(__Stack)};yeccpars2(1, _, _, _, __T, _, _) -> yeccerror(__T);yeccpars2(2, '//', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 114, [2 | __Ss], [__T | __Stack]);yeccpars2(2, atom, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 115, [2 | __Ss], [__T | __Stack]);yeccpars2(2, _, _, _, __T, _, _) -> yeccerror(__T);yeccpars2(3, '(', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 34, [3 | __Ss], [__T | __Stack]);yeccpars2(3, atom, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 102, [3 | __Ss], [__T | __Stack]);yeccpars2(3, _, _, _, __T, _, _) -> yeccerror(__T);yeccpars2(4, '#', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 33, [4 | __Ss], [__T | __Stack]);yeccpars2(4, '(', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 34, [4 | __Ss], [__T | __Stack]);yeccpars2(4, '//', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 35, [4 | __Ss], [__T | __Stack]);yeccpars2(4, '[', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 36, [4 | __Ss], [__T | __Stack]);yeccpars2(4, atom, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 37, [4 | __Ss], [__T | __Stack]);yeccpars2(4, float, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 38, [4 | __Ss], [__T | __Stack]);yeccpars2(4, integer, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 39, [4 | __Ss], [__T | __Stack]);yeccpars2(4, var, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 40, [4 | __Ss], [__T | __Stack]);yeccpars2(4, '{', __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 41, [4 | __Ss], [__T | __Stack]);yeccpars2(4, _, _, _, __T, _, _) -> yeccerror(__T);yeccpars2(5, atom, __Ss, __Stack, __T, __Ts, __Tzr) -> yeccpars1(__Ts, __Tzr, 7, [5 | __Ss], [__T | __Stack]);yeccpars2(5, _, _, _, __T, _, _) -> yeccerror(__T);yeccpars2(6, __Cat, __Ss, __Stack, __T, __Ts, __Tzr) -> __NewStack = yeccpars2_6_(__Stack), __Nss = lists:nthtail(1, __Ss),

⌨️ 快捷键说明

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