16
16
-file("/clearcase/otp/erts/lib/parsetools/include/yeccpre.hrl", 0).
18
18
%% %CopyrightBegin%
20
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
20
%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
22
22
%% The contents of this file are subject to the Erlang Public License,
23
23
%% Version 1.1, (the "License"); you may not use this file except in
24
24
%% compliance with the License. You should have received a copy of the
25
25
%% Erlang Public License along with this software. If not, it can be
26
26
%% retrieved online at http://www.erlang.org/.
28
28
%% Software distributed under the License is distributed on an "AS IS"
29
29
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
30
30
%% the License for the specific language governing rights and limitations
31
31
%% under the License.
36
36
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37
37
% The parser generator will insert appropriate declarations before this line.%
39
-type(yecc_ret() :: {'error', _} | {'ok', _}).
39
-type yecc_ret() :: {'error', _} | {'ok', _}.
41
-spec(parse/1 :: (_) -> yecc_ret()).
41
-spec parse(Tokens :: list()) -> yecc_ret().
43
yeccpars0(Tokens, false).
43
yeccpars0(Tokens, {no_func, no_line}, 0, [], []).
45
-spec(parse_and_scan/1 ::
46
({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) ->
45
-spec parse_and_scan({function() | {atom(), atom()}, [_]}
46
| {atom(), atom(), [_]}) -> yecc_ret().
48
47
parse_and_scan({F, A}) -> % Fun or {M, F}
49
yeccpars0([], {F, A});
48
yeccpars0([], {{F, A}, no_line}, 0, [], []);
50
49
parse_and_scan({M, F, A}) ->
51
yeccpars0([], {{M, F}, A}).
50
yeccpars0([], {{{M, F}, A}, no_line}, 0, [], []).
53
-spec(format_error/1 :: (any()) -> [char() | list()]).
52
-spec format_error(any()) -> [char() | list()].
54
53
format_error(Message) ->
55
54
case io_lib:deep_char_list(Message) of
62
% To be used in grammar files to throw an error message to the parser
63
% toplevel. Doesn't have to be exported!
64
-compile({nowarn_unused_function,{return_error,2}}).
65
-spec(return_error/2 :: (integer(), any()) -> no_return()).
61
%% To be used in grammar files to throw an error message to the parser
62
%% toplevel. Doesn't have to be exported!
63
-compile({nowarn_unused_function, return_error/2}).
64
-spec return_error(integer(), any()) -> no_return().
66
65
return_error(Line, Message) ->
67
66
throw({error, {Line, ?MODULE, Message}}).
69
-define(CODE_VERSION, "1.3").
68
-define(CODE_VERSION, "1.4").
71
yeccpars0(Tokens, MFA) ->
72
try yeccpars1(Tokens, MFA, 0, [], [])
70
yeccpars0(Tokens, Tzr, State, States, Vstack) ->
71
try yeccpars1(Tokens, Tzr, State, States, Vstack)
75
74
Stacktrace = erlang:get_stacktrace(),
76
75
try yecc_error_type(Error, Stacktrace) of
77
{syntax_error, Token} ->
79
{missing_in_goto_table=Tag, Symbol, State} ->
80
Desc = {Symbol, State, Tag},
81
77
erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc},
83
79
catch _:_ -> erlang:raise(error, Error, Stacktrace)
85
throw: {error, {_Line, ?MODULE, _M}} = Error ->
86
Error % probably from return_error/2
81
%% Probably thrown from return_error/2:
82
throw: {error, {_Line, ?MODULE, _M}} = Error ->
89
yecc_error_type(function_clause, [{?MODULE,F,[State,_,_,_,Token,_,_]} | _]) ->
86
yecc_error_type(function_clause, [{?MODULE,F,ArityOrArgs} | _]) ->
90
87
case atom_to_list(F) of
92
{syntax_error, Token};
93
88
"yeccgoto_" ++ SymbolL ->
94
89
{ok,[{atom,_,Symbol}],_} = erl_scan:string(SymbolL),
95
{missing_in_goto_table, Symbol, State}
90
State = case ArityOrArgs of
94
{Symbol, State, missing_in_goto_table}
98
yeccpars1([Token | Tokens], Tokenizer, State, States, Vstack) ->
99
yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens,
101
yeccpars1([], {F, A}, State, States, Vstack) ->
97
yeccpars1([Token | Tokens], Tzr, State, States, Vstack) ->
98
yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens, Tzr);
99
yeccpars1([], {{F, A},_Line}, State, States, Vstack) ->
102
100
case apply(F, A) of
103
{ok, Tokens, _Endline} ->
104
yeccpars1(Tokens, {F, A}, State, States, Vstack);
106
yeccpars1([], false, State, States, Vstack);
101
{ok, Tokens, Endline} ->
102
yeccpars1(Tokens, {{F, A}, Endline}, State, States, Vstack);
104
yeccpars1([], {no_func, Endline}, State, States, Vstack);
107
105
{error, Descriptor, _Endline} ->
108
106
{error, Descriptor}
110
yeccpars1([], false, State, States, Vstack) ->
111
yeccpars2(State, '$end', States, Vstack, {'$end', 999999}, [], false).
108
yeccpars1([], {no_func, no_line}, State, States, Vstack) ->
110
yeccpars2(State, '$end', States, Vstack, yecc_end(Line), [],
112
yeccpars1([], {no_func, Endline}, State, States, Vstack) ->
113
yeccpars2(State, '$end', States, Vstack, yecc_end(Endline), [],
113
116
%% yeccpars1/7 is called from generated code.
116
119
%% yeccpars1/7 can be found by parsing the file without following
117
120
%% include directives. yecc will otherwise assume that an old
118
121
%% yeccpre.hrl is included (one which defines yeccpars1/5).
119
yeccpars1(State1, State, States, Vstack, Stack1, [Token | Tokens],
122
yeccpars1(State1, State, States, Vstack, Token0, [Token | Tokens], Tzr) ->
121
123
yeccpars2(State, element(1, Token), [State1 | States],
122
[Stack1 | Vstack], Token, Tokens, Tokenizer);
123
yeccpars1(State1, State, States, Vstack, Stack1, [], {F, A}) ->
125
{ok, Tokens, _Endline} ->
126
yeccpars1(State1, State, States, Vstack, Stack1, Tokens, {F, A});
128
yeccpars1(State1, State, States, Vstack, Stack1, [], false);
129
{error, Descriptor, _Endline} ->
132
yeccpars1(State1, State, States, Vstack, Stack1, [], false) ->
133
yeccpars2(State, '$end', [State1 | States], [Stack1 | Vstack],
134
{'$end', 999999}, [], false).
136
% For internal use only.
124
[Token0 | Vstack], Token, Tokens, Tzr);
125
yeccpars1(State1, State, States, Vstack, Token0, [], {{_F,_A}, _Line}=Tzr) ->
126
yeccpars1([], Tzr, State, [State1 | States], [Token0 | Vstack]);
127
yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, no_line}) ->
128
Line = yecctoken_end_location(Token0),
129
yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack],
130
yecc_end(Line), [], {no_func, Line});
131
yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, Line}) ->
132
yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack],
133
yecc_end(Line), [], {no_func, Line}).
135
%% For internal use only.
136
yecc_end({Line,_Column}) ->
141
yecctoken_end_location(Token) ->
143
{text, Str} = erl_scan:token_info(Token, text),
144
{line, Line} = erl_scan:token_info(Token, line),
145
Parts = re:split(Str, "\n"),
146
Dline = length(Parts) - 1,
147
Yline = Line + Dline,
148
case erl_scan:token_info(Token, column) of
150
Col = byte_size(lists:last(Parts)),
151
{Yline, Col + if Dline =:= 0 -> Column; true -> 1 end};
156
yecctoken_location(Token)
137
159
yeccerror(Token) ->
138
Text = case catch erl_scan:token_info(Token, text) of
140
_ -> yecctoken2string(Token)
142
Location = case catch erl_scan:token_info(Token, location) of
143
{location, Loc} -> Loc;
144
_ -> element(2, Token)
160
Text = yecctoken_to_string(Token),
161
Location = yecctoken_location(Token),
146
162
{error, {Location, ?MODULE, ["syntax error before: ", Text]}}.
164
yecctoken_to_string(Token) ->
165
case catch erl_scan:token_info(Token, text) of
167
_ -> yecctoken2string(Token)
170
yecctoken_location(Token) ->
171
case catch erl_scan:token_info(Token, location) of
172
{location, Loc} -> Loc;
173
_ -> element(2, Token)
148
176
yecctoken2string({atom, _, A}) -> io_lib:write(A);
149
177
yecctoken2string({integer,_,N}) -> io_lib:write(N);
150
178
yecctoken2string({float,_,F}) -> io_lib:write(F);
151
179
yecctoken2string({char,_,C}) -> io_lib:write_char(C);
152
180
yecctoken2string({var,_,V}) -> io_lib:format("~s", [V]);
153
181
yecctoken2string({string,_,S}) -> io_lib:write_unicode_string(S);
154
yecctoken2string({reserved_symbol, _, A}) -> io_lib:format("~w", [A]);
155
yecctoken2string({_Cat, _, Val}) -> io_lib:format("~w", [Val]);
182
yecctoken2string({reserved_symbol, _, A}) -> io_lib:write(A);
183
yecctoken2string({_Cat, _, Val}) -> io_lib:write(Val);
156
184
yecctoken2string({dot, _}) -> "'.'";
157
185
yecctoken2string({'$end', _}) ->
159
187
yecctoken2string({Other, _}) when is_atom(Other) ->
160
io_lib:format("~w", [Other]);
161
189
yecctoken2string(Other) ->
162
190
io_lib:write(Other).
268
298
yeccgoto_grammar(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
270
300
yeccpars2_3(S, '->', Ss, Stack, T, Ts, Tzr) ->
271
yeccpars1(S, 10, Ss, Stack, T, Ts, Tzr).
301
yeccpars1(S, 10, Ss, Stack, T, Ts, Tzr);
302
yeccpars2_3(_, _, _, _, T, _, _) ->
273
yeccpars2_4(_S, '$end', _Ss, Stack, _T, _Ts, _Tzr) ->
305
yeccpars2_4(_S, '$end', _Ss, Stack, _T, _Ts, _Tzr) ->
307
yeccpars2_4(_, _, _, _, T, _, _) ->
276
310
yeccpars2_5(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
277
311
yeccgoto_grammar(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
415
453
yeccgoto_rule(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
417
455
yeccpars2_30(S, dot, Ss, Stack, T, Ts, Tzr) ->
418
yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr).
456
yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr);
457
yeccpars2_30(_, _, _, _, T, _, _) ->
420
460
yeccpars2_31(S, dot, Ss, Stack, T, Ts, Tzr) ->
421
yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr).
461
yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr);
462
yeccpars2_31(_, _, _, _, T, _, _) ->
423
465
yeccpars2_32(S, string, Ss, Stack, T, Ts, Tzr) ->
424
466
yeccpars1(S, 32, Ss, Stack, T, Ts, Tzr);