22
22
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
25
%% Author contact: richardc@it.uu.se
25
%% Author contact: carlsson.richard@gmail.com
29
26
%% =====================================================================
32
29
start spec func_type utype_list utype_tuple utypes utype ptypes ptype
33
nutype function_name where_defs defs def typedef etype throws qname ref
34
aref mref lref pref var_list vars fields field.
30
nutype function_name where_defs defs defs2 def typedef etype
31
throws qname ref aref mref lref pref var_list vars fields field
32
futype_list bin_base_type bin_unit_type.
37
atom float integer var string start_spec start_typedef start_throws
35
atom float integer var an_var string start_spec start_typedef start_throws
40
38
'(' ')' ',' '.' '->' '{' '}' '[' ']' '|' '+' ':' '::' '=' '/' '//' '*'
39
'#' 'where' '<<' '>>' '..' '...'.
52
50
qname -> qname '.' atom: [tok_val('$3') | '$1'].
54
52
spec -> func_type where_defs:
55
#t_spec{type = '$1', defs = lists:reverse('$2')}.
53
#t_spec{type = '$1', defs = '$2'}.
56
54
spec -> function_name func_type where_defs:
57
#t_spec{name = '$1', type = '$2', defs = lists:reverse('$3')}.
55
#t_spec{name = '$1', type = '$2', defs = '$3'}.
59
57
where_defs -> 'where' defs: '$2'.
60
58
where_defs -> defs: '$1'.
68
66
%% Paired with line number, for later error reporting
69
utype_list -> '(' ')' : {[], tok_line('$1')}.
70
67
utype_list -> '(' utypes ')' : {lists:reverse('$2'), tok_line('$1')}.
72
utype_tuple -> '{' '}' : [].
69
futype_list -> utype_list : '$1'.
70
futype_list -> '(' '...' ')' : {[#t_var{name = '...'}], tok_line('$1')}.
73
72
utype_tuple -> '{' utypes '}' : lists:reverse('$2').
75
74
%% Produced in reverse order.
75
utypes -> '$empty' : [].
76
76
utypes -> utype : ['$1'].
77
77
utypes -> utypes ',' utype : ['$3' | '$1'].
90
90
ptype -> var : #t_var{name = tok_val('$1')}.
91
91
ptype -> atom : #t_atom{val = tok_val('$1')}.
92
92
ptype -> integer: #t_integer{val = tok_val('$1')}.
93
ptype -> integer '..' integer: #t_integer_range{from = tok_val('$1'),
93
95
ptype -> float: #t_float{val = tok_val('$1')}.
94
96
ptype -> utype_tuple : #t_tuple{types = '$1'}.
95
97
ptype -> '[' ']' : #t_nil{}.
96
98
ptype -> '[' utype ']' : #t_list{type = '$2'}.
99
ptype -> '[' utype ',' '...' ']' : #t_nonempty_list{type = '$2'}.
97
100
ptype -> utype_list:
98
if length(element(1, '$1')) == 1 ->
101
if length(element(1, '$1')) == 1 ->
99
102
%% there must be exactly one utype in the list
100
103
hd(element(1, '$1'));
104
%% Replace last line when releasing next major release:
105
%% #t_paren{type = hd(element(1, '$1'))};
101
106
length(element(1, '$1')) == 0 ->
102
107
return_error(element(2, '$1'), "syntax error before: ')'");
104
109
return_error(element(2, '$1'), "syntax error before: ','")
106
ptype -> utype_list '->' ptype:
111
ptype -> futype_list '->' ptype:
107
112
#t_fun{args = element(1, '$1'), range = '$3'}.
108
113
ptype -> '#' atom '{' '}' :
109
114
#t_record{name = #t_atom{val = tok_val('$2')}}.
111
116
#t_record{name = #t_atom{val = tok_val('$2')},
112
117
fields = lists:reverse('$4')}.
113
118
ptype -> atom utype_list:
114
#t_type{name = #t_name{name = tok_val('$1')},
115
args = element(1, '$2')}.
116
ptype -> qname ':' atom utype_list :
119
case {tok_val('$1'), element(1, '$2')} of
121
%% Prefer '[]' before 'nil(). Due to
122
%% compatibility with Erlang types, which do not
123
%% separate '[]' from 'nil()'.
126
%% Prefer '[T]' before 'list(T). Due to
127
%% compatibility with Erlang types, which do not
128
%% separate '[T]' from 'list(T)'.
130
{'fun', [#t_fun{}=Fun]} ->
131
%% An incompatible change as compared to EDOc 0.7.6.6.
132
%% Due to compatibility with Erlang types.
135
#t_type{name = #t_name{name = function}};
137
#t_type{name = #t_name{name = Name},
140
ptype -> qname ':' atom utype_list :
117
141
#t_type{name = #t_name{module = qname('$1'),
118
142
name = tok_val('$3')},
119
143
args = element(1, '$4')}.
120
ptype -> '//' atom '/' qname ':' atom utype_list :
144
ptype -> '//' atom '/' qname ':' atom utype_list :
121
145
#t_type{name = #t_name{app = tok_val('$2'),
122
146
module = qname('$4'),
123
147
name = tok_val('$6')},
124
148
args = element(1, '$7')}.
149
ptype -> '<<' '>>' : #t_binary{}.
150
ptype -> '<<' bin_base_type '>>' : #t_binary{base_size = '$2'}.
151
ptype -> '<<' bin_unit_type '>>' : #t_binary{unit_size = '$2'}.
152
ptype -> '<<' bin_base_type ',' bin_unit_type '>>' :
153
#t_binary{base_size = '$2', unit_size = '$4'}.
155
bin_base_type -> an_var ':' integer: tok_val('$3').
157
bin_unit_type -> an_var ':' an_var '*' integer : tok_val('$5').
126
159
%% Produced in reverse order.
127
160
fields -> field : ['$1'].
130
163
field -> atom '=' utype :
131
164
#t_field{name = #t_atom{val = tok_val('$1')}, type = '$3'}.
133
%% Produced in reverse order.
134
166
defs -> '$empty' : [].
135
defs -> defs def : ['$2' | '$1'].
136
defs -> defs ',' def : ['$3' | '$1'].
167
defs -> def defs2 : ['$1' | lists:reverse('$2')].
169
%% Produced in reverse order.
170
defs2 -> '$empty' : [].
171
defs2 -> defs2 def : ['$2' | '$1'].
172
defs2 -> defs2 ',' def : ['$3' | '$1'].
138
174
def -> var '=' utype:
139
175
#t_def{name = #t_var{name = tok_val('$1')},
141
def -> atom var_list '=' utype:
142
#t_def{name = #t_type{name = #t_name{name = tok_val('$1')},
177
def -> atom '(' utypes ')' '=' utype:
178
build_def(tok_val('$1'), '$2', '$3', '$6').
146
180
var_list -> '(' ')' : [].
147
181
var_list -> '(' vars ')' : lists:reverse('$2').
153
187
typedef -> atom var_list where_defs:
154
188
#t_typedef{name = #t_name{name = tok_val('$1')},
156
defs = lists:reverse('$3')}.
157
191
typedef -> atom var_list '=' utype where_defs:
158
192
#t_typedef{name = #t_name{name = tok_val('$1')},
161
defs = lists:reverse('$5')}.
299
333
annotate(T, A) -> ?add_t_ann(T, A).
335
build_def(S, P, As, T) ->
338
#t_def{name = #t_type{name = #t_name{name = S},
339
args = lists:reverse(As)},
342
return_error(element(2, P), "variable expected after '('")
345
all_vars([#t_var{} | As]) ->
301
350
%% ---------------------------------------------------------------------
303
352
%% @doc EDoc type specification parsing. Parses the content of
379
428
{S1, S2} = edoc_lib:split_at_space(edoc_lib:strip_space(S)),
380
429
case edoc_lib:strip_space(S1) of
381
430
"" -> throw_error(parse_param, L);
383
432
Text = edoc_lib:strip_space(S2),
384
433
{list_to_atom(Name), edoc_wiki:parse_xml(Text, L)}
407
456
-spec throw_error(term(), erl_scan:line()) -> no_return().
409
throw_error({L, M, D}, _L0) ->
410
throw({error,L,{format_error,M,D}});
411
458
throw_error({parse_spec, E}, L) ->
412
459
throw_error({"specification", E}, L);
413
460
throw_error({parse_typedef, E}, L) ->
419
466
throw_error(parse_param, L) ->
420
467
throw({error, L, "missing parameter name"});
421
468
throw_error({Where, E}, L) when is_list(Where) ->
422
throw({error,L,{"unknown error parsing ~s: ~P.",[Where,E,15]}});
425
throw({error,L,{"unknown parse error: ~P.",[E,15]}}).
469
throw({error,L,{"unknown error parsing ~s: ~P.",[Where,E,15]}}).