summaryrefslogtreecommitdiff
path: root/lib/parsetools/include/leexinc.hrl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/parsetools/include/leexinc.hrl')
-rw-r--r--lib/parsetools/include/leexinc.hrl377
1 files changed, 204 insertions, 173 deletions
diff --git a/lib/parsetools/include/leexinc.hrl b/lib/parsetools/include/leexinc.hrl
index 8dfc42f479..a06584ff79 100644
--- a/lib/parsetools/include/leexinc.hrl
+++ b/lib/parsetools/include/leexinc.hrl
@@ -16,261 +16,269 @@
format_error({illegal,S}) -> ["illegal characters ",io_lib:write_string(S)];
format_error({user,S}) -> S.
-string(String) -> string(String, 1).
-
-string(String, Line) -> string(String, Line, String, []).
-
-%% string(InChars, Line, TokenChars, Tokens) ->
-%% {ok,Tokens,Line} | {error,ErrorInfo,Line}.
-%% Note the line number going into yystate, L0, is line of token
-%% start while line number returned is line of token end. We want line
-%% of token start.
-
-string([], L, [], Ts) -> % No partial tokens!
- {ok,yyrev(Ts),L};
-string(Ics0, L0, Tcs, Ts) ->
- case yystate(yystate(), Ics0, L0, 0, reject, 0) of
- {A,Alen,Ics1,L1} -> % Accepting end state
- string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts);
- {A,Alen,Ics1,L1,_S1} -> % Accepting transition state
- string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts);
- {reject,_Alen,Tlen,_Ics1,L1,_S1} -> % After a non-accepting state
- {error,{L0,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1};
- {A,Alen,Tlen,_Ics1,L1,_S1} ->
+%% string(InChars) ->
+%% string(InChars, Loc) ->
+%% {ok,Tokens,EndLoc} | {error,ErrorInfo,EndLoc}.
+%% Loc is the starting location of the token, while EndLoc is the first not scanned
+%% location. Location is either Line or {Line,Column}, depending on the "error_location" option.
+
+##str
+
+do_string([], L, C, [], Ts) -> % No partial tokens!
+ {ok,yyrev(Ts),{L,C}};
+do_string(Ics0, L0, C0, Tcs, Ts) ->
+ case yystate(yystate(), Ics0, L0, C0, 0, reject, 0) of
+ {A,Alen,Ics1,L1,_C1} -> % Accepting end state
+ C2 = adjust_col(Tcs, Alen, C0),
+ string_cont(Ics1, L1, C2, yyaction(A, Alen, Tcs, L0, C0), Ts);
+ {A,Alen,Ics1,L1,_C1,_S1} -> % Accepting transition state
+ C2 = adjust_col(Tcs, Alen, C0),
+ string_cont(Ics1, L1, C2, yyaction(A, Alen, Tcs, L0, C0), Ts);
+ {reject,_Alen,Tlen,_Ics1,_L1,_C1,_S1} -> % After a non-accepting state
+ {error,{{L0, C0} ,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},{L0, C0}};
+ {A,Alen,Tlen,_Ics1,L1, C1,_S1}->
Tcs1 = yysuf(Tcs, Alen),
L2 = adjust_line(Tlen, Alen, Tcs1, L1),
- string_cont(Tcs1, L2, yyaction(A, Alen, Tcs, L0), Ts)
+ C2 = adjust_col(Tcs, Alen, C1),
+ string_cont(Tcs1, L2, C2, yyaction(A, Alen, Tcs, L0,C0), Ts)
end.
-%% string_cont(RestChars, Line, Token, Tokens)
+%% string_cont(RestChars, Line, Col, Token, Tokens)
%% Test for and remove the end token wrapper. Push back characters
%% are prepended to RestChars.
--dialyzer({nowarn_function, string_cont/4}).
+-dialyzer({nowarn_function, string_cont/5}).
-string_cont(Rest, Line, {token,T}, Ts) ->
- string(Rest, Line, Rest, [T|Ts]);
-string_cont(Rest, Line, {token,T,Push}, Ts) ->
+string_cont(Rest, Line, Col, {token,T}, Ts) ->
+ do_string(Rest, Line, Col, Rest, [T|Ts]);
+string_cont(Rest, Line, Col, {token,T,Push}, Ts) ->
NewRest = Push ++ Rest,
- string(NewRest, Line, NewRest, [T|Ts]);
-string_cont(Rest, Line, {end_token,T}, Ts) ->
- string(Rest, Line, Rest, [T|Ts]);
-string_cont(Rest, Line, {end_token,T,Push}, Ts) ->
+ do_string(NewRest, Line, Col, NewRest, [T|Ts]);
+string_cont(Rest, Line, Col, {end_token,T}, Ts) ->
+ do_string(Rest, Line, Col, Rest, [T|Ts]);
+string_cont(Rest, Line, Col, {end_token,T,Push}, Ts) ->
NewRest = Push ++ Rest,
- string(NewRest, Line, NewRest, [T|Ts]);
-string_cont(Rest, Line, skip_token, Ts) ->
- string(Rest, Line, Rest, Ts);
-string_cont(Rest, Line, {skip_token,Push}, Ts) ->
+ do_string(NewRest, Line, Col, NewRest, [T|Ts]);
+string_cont(Rest, Line, Col, skip_token, Ts) ->
+ do_string(Rest, Line, Col, Rest, Ts);
+string_cont(Rest, Line, Col, {skip_token,Push}, Ts) ->
NewRest = Push ++ Rest,
- string(NewRest, Line, NewRest, Ts);
-string_cont(_Rest, Line, {error,S}, _Ts) ->
- {error,{Line,?MODULE,{user,S}},Line}.
+ do_string(NewRest, Line, Col, NewRest, Ts);
+string_cont(_Rest, Line, Col, {error,S}, _Ts) ->
+ {error,{{Line, Col},?MODULE,{user,S}},{Line,Col}}.
%% token(Continuation, Chars) ->
-%% token(Continuation, Chars, Line) ->
+%% token(Continuation, Chars, Loc) ->
%% {more,Continuation} | {done,ReturnVal,RestChars}.
%% Must be careful when re-entering to append the latest characters to the
%% after characters in an accept. The continuation is:
-%% {token,State,CurrLine,TokenChars,TokenLen,TokenLine,AccAction,AccLen}
+%% {token,State,CurrLine,CurrCol,TokenChars,TokenLen,TokenLine,TokenCol,AccAction,AccLen}
-token(Cont, Chars) -> token(Cont, Chars, 1).
+##tkn
-token([], Chars, Line) ->
- token(yystate(), Chars, Line, Chars, 0, Line, reject, 0);
-token({token,State,Line,Tcs,Tlen,Tline,Action,Alen}, Chars, _) ->
- token(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Action, Alen).
+do_token([], Chars, Line, Col) ->
+ token(yystate(), Chars, Line, Col, Chars, 0, Line, Col, reject, 0);
+do_token({token,State,Line,Col,Tcs,Tlen,Tline,Tcol,Action,Alen}, Chars, _, _) ->
+ token(State, Chars, Line, Col, Tcs ++ Chars, Tlen, Tline, Tcol, Action, Alen).
-%% token(State, InChars, Line, TokenChars, TokenLen, TokenLine,
+%% token(State, InChars, Line, Col, TokenChars, TokenLen, TokenLine, TokenCol
%% AcceptAction, AcceptLen) ->
%% {more,Continuation} | {done,ReturnVal,RestChars}.
%% The argument order is chosen to be more efficient.
-token(S0, Ics0, L0, Tcs, Tlen0, Tline, A0, Alen0) ->
- case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of
+token(S0, Ics0, L0, C0, Tcs, Tlen0, Tline, Tcol, A0, Alen0) ->
+ case yystate(S0, Ics0, L0, C0, Tlen0, A0, Alen0) of
%% Accepting end state, we have a token.
- {A1,Alen1,Ics1,L1} ->
- token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline));
+ {A1,Alen1,Ics1,L1,C1} ->
+ C2 = adjust_col(Tcs, Alen1, C1),
+ token_cont(Ics1, L1, C2, yyaction(A1, Alen1, Tcs, Tline,Tcol));
%% Accepting transition state, can take more chars.
- {A1,Alen1,[],L1,S1} -> % Need more chars to check
- {more,{token,S1,L1,Tcs,Alen1,Tline,A1,Alen1}};
- {A1,Alen1,Ics1,L1,_S1} -> % Take what we got
- token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline));
+ {A1,Alen1,[],L1,C1,S1} -> % Need more chars to check
+ {more,{token,S1,L1,C1,Tcs,Alen1,Tline,Tcol,A1,Alen1}};
+ {A1,Alen1,Ics1,L1,C1,_S1} -> % Take what we got
+ C2 = adjust_col(Tcs, Alen1, C1),
+ token_cont(Ics1, L1, C2, yyaction(A1, Alen1, Tcs, Tline,Tcol));
%% After a non-accepting state, maybe reach accept state later.
- {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check
- {more,{token,S1,L1,Tcs,Tlen1,Tline,A1,Alen1}};
- {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match
+ {A1,Alen1,Tlen1,[],L1,C1,S1} -> % Need more chars to check
+ {more,{token,S1,L1,C1,Tcs,Tlen1,Tline,Tcol,A1,Alen1}};
+ {reject,_Alen1,Tlen1,eof,L1,C1,_S1} -> % No token match
%% Check for partial token which is error.
- Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE,
+ Ret = if Tlen1 > 0 -> {error,{{Tline,Tcol},?MODULE,
%% Skip eof tail in Tcs.
- {illegal,yypre(Tcs, Tlen1)}},L1};
- true -> {eof,L1}
+ {illegal,yypre(Tcs, Tlen1)}},{L1,C1}};
+ true -> {eof,{L1,C1}}
end,
{done,Ret,eof};
- {reject,_Alen1,Tlen1,Ics1,L1,_S1} -> % No token match
- Error = {Tline,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}},
- {done,{error,Error,L1},Ics1};
- {A1,Alen1,Tlen1,_Ics1,L1,_S1} -> % Use last accept match
+ {reject,_Alen1,Tlen1,Ics1,_L1,_C1,_S1} -> % No token match
+ Error = {{Tline,Tcol},?MODULE,{illegal,yypre(Tcs, Tlen1+1)}},
+ {done,{error,Error,{Tline,Tcol}},Ics1};
+ {A1,Alen1,Tlen1,_Ics1,L1,_C1,_S1} -> % Use last accept match
Tcs1 = yysuf(Tcs, Alen1),
L2 = adjust_line(Tlen1, Alen1, Tcs1, L1),
- token_cont(Tcs1, L2, yyaction(A1, Alen1, Tcs, Tline))
+ C2 = C0 + Alen1,
+ token_cont(Tcs1, L2, C2, yyaction(A1, Alen1, Tcs, Tline, Tcol))
end.
-%% token_cont(RestChars, Line, Token)
+%% token_cont(RestChars, Line, Col, Token)
%% If we have a token or error then return done, else if we have a
%% skip_token then continue.
--dialyzer({nowarn_function, token_cont/3}).
+-dialyzer({nowarn_function, token_cont/4}).
-token_cont(Rest, Line, {token,T}) ->
- {done,{ok,T,Line},Rest};
-token_cont(Rest, Line, {token,T,Push}) ->
+token_cont(Rest, Line, Col, {token,T}) ->
+ {done,{ok,T,{Line,Col}},Rest};
+token_cont(Rest, Line, Col, {token,T,Push}) ->
NewRest = Push ++ Rest,
- {done,{ok,T,Line},NewRest};
-token_cont(Rest, Line, {end_token,T}) ->
- {done,{ok,T,Line},Rest};
-token_cont(Rest, Line, {end_token,T,Push}) ->
+ {done,{ok,T,{Line,Col}},NewRest};
+token_cont(Rest, Line, Col, {end_token,T}) ->
+ {done,{ok,T,{Line,Col}},Rest};
+token_cont(Rest, Line, Col, {end_token,T,Push}) ->
NewRest = Push ++ Rest,
- {done,{ok,T,Line},NewRest};
-token_cont(Rest, Line, skip_token) ->
- token(yystate(), Rest, Line, Rest, 0, Line, reject, 0);
-token_cont(Rest, Line, {skip_token,Push}) ->
+ {done,{ok,T,{Line,Col}},NewRest};
+token_cont(Rest, Line, Col, skip_token) ->
+ token(yystate(), Rest, Line, Col, Rest, 0, Line, Col, reject, 0);
+token_cont(Rest, Line, Col, {skip_token,Push}) ->
NewRest = Push ++ Rest,
- token(yystate(), NewRest, Line, NewRest, 0, Line, reject, 0);
-token_cont(Rest, Line, {error,S}) ->
- {done,{error,{Line,?MODULE,{user,S}},Line},Rest}.
+ token(yystate(), NewRest, Line, Col, NewRest, 0, Line, Col, reject, 0);
+token_cont(Rest, Line, Col, {error,S}) ->
+ {done,{error,{{Line, Col},?MODULE,{user,S}},{Line, Col}},Rest}.
-%% tokens(Continuation, Chars, Line) ->
+%% tokens(Continuation, Chars) ->
+%% tokens(Continuation, Chars, Loc) ->
%% {more,Continuation} | {done,ReturnVal,RestChars}.
%% Must be careful when re-entering to append the latest characters to the
%% after characters in an accept. The continuation is:
-%% {tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Tokens,AccAction,AccLen}
-%% {skip_tokens,State,CurrLine,TokenChars,TokenLen,TokenLine,Error,AccAction,AccLen}
+%% {tokens,State,CurrLine,CurrCol,TokenChars,TokenLen,TokenLine,TokenCur,Tokens,AccAction,AccLen}
+%% {skip_tokens,State,CurrLine,CurrCol,TokenChars,TokenLen,TokenLine,TokenCur,Error,AccAction,AccLen}
-tokens(Cont, Chars) -> tokens(Cont, Chars, 1).
+##tks
-tokens([], Chars, Line) ->
- tokens(yystate(), Chars, Line, Chars, 0, Line, [], reject, 0);
-tokens({tokens,State,Line,Tcs,Tlen,Tline,Ts,Action,Alen}, Chars, _) ->
- tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Ts, Action, Alen);
-tokens({skip_tokens,State,Line,Tcs,Tlen,Tline,Error,Action,Alen}, Chars, _) ->
- skip_tokens(State, Chars, Line, Tcs ++ Chars, Tlen, Tline, Error, Action, Alen).
+do_tokens([], Chars, Line, Col) ->
+ tokens(yystate(), Chars, Line, Col, Chars, 0, Line, Col, [], reject, 0);
+do_tokens({tokens,State,Line,Col,Tcs,Tlen,Tline,Tcol,Ts,Action,Alen}, Chars, _,_) ->
+ tokens(State, Chars, Line, Col, Tcs ++ Chars, Tlen, Tline, Tcol, Ts, Action, Alen);
+do_tokens({skip_tokens,State,Line, Col, Tcs,Tlen,Tline,Tcol,Error,Action,Alen}, Chars, _,_) ->
+ skip_tokens(State, Chars, Line, Col, Tcs ++ Chars, Tlen, Tline, Tcol, Error, Action, Alen).
-%% tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens,
+%% tokens(State, InChars, Line, Col, TokenChars, TokenLen, TokenLine, TokenCol,Tokens,
%% AcceptAction, AcceptLen) ->
%% {more,Continuation} | {done,ReturnVal,RestChars}.
-tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Ts, A0, Alen0) ->
- case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of
+tokens(S0, Ics0, L0, C0, Tcs, Tlen0, Tline, Tcol, Ts, A0, Alen0) ->
+ case yystate(S0, Ics0, L0, C0, Tlen0, A0, Alen0) of
%% Accepting end state, we have a token.
- {A1,Alen1,Ics1,L1} ->
- tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts);
+ {A1,Alen1,Ics1,L1,C1} ->
+ C2 = adjust_col(Tcs, Alen1, C1),
+ tokens_cont(Ics1, L1, C2, yyaction(A1, Alen1, Tcs, Tline, Tcol), Ts);
%% Accepting transition state, can take more chars.
- {A1,Alen1,[],L1,S1} -> % Need more chars to check
- {more,{tokens,S1,L1,Tcs,Alen1,Tline,Ts,A1,Alen1}};
- {A1,Alen1,Ics1,L1,_S1} -> % Take what we got
- tokens_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Ts);
+ {A1,Alen1,[],L1,C1,S1} -> % Need more chars to check
+ {more,{tokens,S1,L1,C1,Tcs,Alen1,Tline,Tcol,Ts,A1,Alen1}};
+ {A1,Alen1,Ics1,L1,C1,_S1} -> % Take what we got
+ C2 = adjust_col(Tcs, Alen1, C1),
+ tokens_cont(Ics1, L1, C2, yyaction(A1, Alen1, Tcs, Tline,Tcol), Ts);
%% After a non-accepting state, maybe reach accept state later.
- {A1,Alen1,Tlen1,[],L1,S1} -> % Need more chars to check
- {more,{tokens,S1,L1,Tcs,Tlen1,Tline,Ts,A1,Alen1}};
- {reject,_Alen1,Tlen1,eof,L1,_S1} -> % No token match
+ {A1,Alen1,Tlen1,[],L1,C1,S1} -> % Need more chars to check
+ {more,{tokens,S1,L1,C1,Tcs,Tlen1,Tline,Tcol,Ts,A1,Alen1}};
+ {reject,_Alen1,Tlen1,eof,L1,C1,_S1} -> % No token match
%% Check for partial token which is error, no need to skip here.
- Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE,
+ Ret = if Tlen1 > 0 -> {error,{{Tline,Tcol},?MODULE,
%% Skip eof tail in Tcs.
- {illegal,yypre(Tcs, Tlen1)}},L1};
- Ts == [] -> {eof,L1};
- true -> {ok,yyrev(Ts),L1}
+ {illegal,yypre(Tcs, Tlen1)}},{L1,C1}};
+ Ts == [] -> {eof,{L1,C1}};
+ true -> {ok,yyrev(Ts),{L1,C1}}
end,
{done,Ret,eof};
- {reject,_Alen1,Tlen1,_Ics1,L1,_S1} ->
+ {reject,_Alen1,Tlen1,_Ics1,L1,C1,_S1} ->
%% Skip rest of tokens.
- Error = {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}},
- skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error);
- {A1,Alen1,Tlen1,_Ics1,L1,_S1} ->
- Token = yyaction(A1, Alen1, Tcs, Tline),
+ Error = {{L1,C1},?MODULE,{illegal,yypre(Tcs, Tlen1+1)}},
+ skip_tokens(yysuf(Tcs, Tlen1+1), L1, C1, Error);
+ {A1,Alen1,Tlen1,_Ics1,L1,_C1,_S1} ->
+ Token = yyaction(A1, Alen1, Tcs, Tline,Tcol),
Tcs1 = yysuf(Tcs, Alen1),
L2 = adjust_line(Tlen1, Alen1, Tcs1, L1),
- tokens_cont(Tcs1, L2, Token, Ts)
+ C2 = C0 + Alen1,
+ tokens_cont(Tcs1, L2, C2, Token, Ts)
end.
-%% tokens_cont(RestChars, Line, Token, Tokens)
+%% tokens_cont(RestChars, Line, Column, Token, Tokens)
%% If we have an end_token or error then return done, else if we have
%% a token then save it and continue, else if we have a skip_token
%% just continue.
--dialyzer({nowarn_function, tokens_cont/4}).
+-dialyzer({nowarn_function, tokens_cont/5}).
-tokens_cont(Rest, Line, {token,T}, Ts) ->
- tokens(yystate(), Rest, Line, Rest, 0, Line, [T|Ts], reject, 0);
-tokens_cont(Rest, Line, {token,T,Push}, Ts) ->
+tokens_cont(Rest, Line, Col, {token,T}, Ts) ->
+ tokens(yystate(), Rest, Line, Col, Rest, 0, Line, Col, [T|Ts], reject, 0);
+tokens_cont(Rest, Line, Col, {token,T,Push}, Ts) ->
NewRest = Push ++ Rest,
- tokens(yystate(), NewRest, Line, NewRest, 0, Line, [T|Ts], reject, 0);
-tokens_cont(Rest, Line, {end_token,T}, Ts) ->
- {done,{ok,yyrev(Ts, [T]),Line},Rest};
-tokens_cont(Rest, Line, {end_token,T,Push}, Ts) ->
+ tokens(yystate(), NewRest, Line, Col, NewRest, 0, Line, Col, [T|Ts], reject, 0);
+tokens_cont(Rest, Line, Col, {end_token,T}, Ts) ->
+ {done,{ok,yyrev(Ts, [T]),{Line,Col}},Rest};
+tokens_cont(Rest, Line, Col, {end_token,T,Push}, Ts) ->
NewRest = Push ++ Rest,
- {done,{ok,yyrev(Ts, [T]),Line},NewRest};
-tokens_cont(Rest, Line, skip_token, Ts) ->
- tokens(yystate(), Rest, Line, Rest, 0, Line, Ts, reject, 0);
-tokens_cont(Rest, Line, {skip_token,Push}, Ts) ->
+ {done,{ok,yyrev(Ts, [T]),{Line, Col}},NewRest};
+tokens_cont(Rest, Line, Col, skip_token, Ts) ->
+ tokens(yystate(), Rest, Line, Col, Rest, 0, Line, Col, Ts, reject, 0);
+tokens_cont(Rest, Line, Col, {skip_token,Push}, Ts) ->
NewRest = Push ++ Rest,
- tokens(yystate(), NewRest, Line, NewRest, 0, Line, Ts, reject, 0);
-tokens_cont(Rest, Line, {error,S}, _Ts) ->
- skip_tokens(Rest, Line, {Line,?MODULE,{user,S}}).
+ tokens(yystate(), NewRest, Line, Col, NewRest, 0, Line, Col, Ts, reject, 0);
+tokens_cont(Rest, Line, Col, {error,S}, _Ts) ->
+ skip_tokens(Rest, Line, Col, {{Line,Col},?MODULE,{user,S}}).
-%%skip_tokens(InChars, Line, Error) -> {done,{error,Error,Line},Ics}.
+%% skip_tokens(InChars, Line, Col, Error) -> {done,{error,Error,{Line,Col}},Ics}.
%% Skip tokens until an end token, junk everything and return the error.
-skip_tokens(Ics, Line, Error) ->
- skip_tokens(yystate(), Ics, Line, Ics, 0, Line, Error, reject, 0).
+skip_tokens(Ics, Line, Col, Error) ->
+ skip_tokens(yystate(), Ics, Line, Col, Ics, 0, Line, Col, Error, reject, 0).
-%% skip_tokens(State, InChars, Line, TokenChars, TokenLen, TokenLine, Tokens,
+%% skip_tokens(State, InChars, Line, Col, TokenChars, TokenLen, TokenLine, TokenCol, Tokens,
%% AcceptAction, AcceptLen) ->
%% {more,Continuation} | {done,ReturnVal,RestChars}.
-skip_tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Error, A0, Alen0) ->
- case yystate(S0, Ics0, L0, Tlen0, A0, Alen0) of
- {A1,Alen1,Ics1,L1} -> % Accepting end state
- skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error);
- {A1,Alen1,[],L1,S1} -> % After an accepting state
- {more,{skip_tokens,S1,L1,Tcs,Alen1,Tline,Error,A1,Alen1}};
- {A1,Alen1,Ics1,L1,_S1} ->
- skip_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline), Error);
- {A1,Alen1,Tlen1,[],L1,S1} -> % After a non-accepting state
- {more,{skip_tokens,S1,L1,Tcs,Tlen1,Tline,Error,A1,Alen1}};
- {reject,_Alen1,_Tlen1,eof,L1,_S1} ->
- {done,{error,Error,L1},eof};
- {reject,_Alen1,Tlen1,_Ics1,L1,_S1} ->
- skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error);
- {A1,Alen1,Tlen1,_Ics1,L1,_S1} ->
- Token = yyaction(A1, Alen1, Tcs, Tline),
+skip_tokens(S0, Ics0, L0, C0, Tcs, Tlen0, Tline, Tcol, Error, A0, Alen0) ->
+ case yystate(S0, Ics0, L0, C0, Tlen0, A0, Alen0) of
+ {A1,Alen1,Ics1,L1, C1} -> % Accepting end state
+ skip_cont(Ics1, L1, C1, yyaction(A1, Alen1, Tcs, Tline, Tcol), Error);
+ {A1,Alen1,[],L1,C1, S1} -> % After an accepting state
+ {more,{skip_tokens,S1,L1,C1,Tcs,Alen1,Tline,Tcol,Error,A1,Alen1}};
+ {A1,Alen1,Ics1,L1,C1,_S1} ->
+ skip_cont(Ics1, L1, C1, yyaction(A1, Alen1, Tcs, Tline, Tcol), Error);
+ {A1,Alen1,Tlen1,[],L1,C1,S1} -> % After a non-accepting state
+ {more,{skip_tokens,S1,L1,C1,Tcs,Tlen1,Tline,Tcol,Error,A1,Alen1}};
+ {reject,_Alen1,_Tlen1,eof,L1,C1,_S1} ->
+ {done,{error,Error,{L1,C1}},eof};
+ {reject,_Alen1,Tlen1,_Ics1,L1,C1,_S1} ->
+ skip_tokens(yysuf(Tcs, Tlen1+1), L1, C1,Error);
+ {A1,Alen1,Tlen1,_Ics1,L1,C1,_S1} ->
+ Token = yyaction(A1, Alen1, Tcs, Tline, Tcol),
Tcs1 = yysuf(Tcs, Alen1),
L2 = adjust_line(Tlen1, Alen1, Tcs1, L1),
- skip_cont(Tcs1, L2, Token, Error)
+ skip_cont(Tcs1, L2, C1, Token, Error)
end.
-%% skip_cont(RestChars, Line, Token, Error)
+%% skip_cont(RestChars, Line, Col, Token, Error)
%% Skip tokens until we have an end_token or error then return done
%% with the original rror.
--dialyzer({nowarn_function, skip_cont/4}).
+-dialyzer({nowarn_function, skip_cont/5}).
-skip_cont(Rest, Line, {token,_T}, Error) ->
- skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0);
-skip_cont(Rest, Line, {token,_T,Push}, Error) ->
+skip_cont(Rest, Line, Col, {token,_T}, Error) ->
+ skip_tokens(yystate(), Rest, Line, Col, Rest, 0, Line, Col, Error, reject, 0);
+skip_cont(Rest, Line, Col, {token,_T,Push}, Error) ->
NewRest = Push ++ Rest,
- skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0);
-skip_cont(Rest, Line, {end_token,_T}, Error) ->
- {done,{error,Error,Line},Rest};
-skip_cont(Rest, Line, {end_token,_T,Push}, Error) ->
+ skip_tokens(yystate(), NewRest, Line, Col, NewRest, 0, Line, Col, Error, reject, 0);
+skip_cont(Rest, Line, Col, {end_token,_T}, Error) ->
+ {done,{error,Error,{Line,Col}},Rest};
+skip_cont(Rest, Line, Col, {end_token,_T,Push}, Error) ->
NewRest = Push ++ Rest,
- {done,{error,Error,Line},NewRest};
-skip_cont(Rest, Line, skip_token, Error) ->
- skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0);
-skip_cont(Rest, Line, {skip_token,Push}, Error) ->
+ {done,{error,Error,{Line,Col}},NewRest};
+skip_cont(Rest, Line, Col, skip_token, Error) ->
+ skip_tokens(yystate(), Rest, Line, Col, Rest, 0, Line, Col, Error, reject, 0);
+skip_cont(Rest, Line, Col, {skip_token,Push}, Error) ->
NewRest = Push ++ Rest,
- skip_tokens(yystate(), NewRest, Line, NewRest, 0, Line, Error, reject, 0);
-skip_cont(Rest, Line, {error,_S}, Error) ->
- skip_tokens(yystate(), Rest, Line, Rest, 0, Line, Error, reject, 0).
+ skip_tokens(yystate(), NewRest, Line, Col, NewRest, 0, Line, Col, Error, reject, 0);
+skip_cont(Rest, Line, Col, {error,_S}, Error) ->
+ skip_tokens(yystate(), Rest, Line, Col, Rest, 0, Line, Col, Error, reject, 0).
-compile({nowarn_unused_function, [yyrev/1, yyrev/2, yypre/2, yysuf/2]}).
@@ -292,21 +300,44 @@ adjust_line(T, A, [$\n|Cs], L) ->
adjust_line(T, A, [_|Cs], L) ->
adjust_line(T-1, A, Cs, L).
+%% adjust_col(Chars, AcceptLength, Col) -> NewCol
+%% Handle newlines, tabs and unicode chars.
+adjust_col(_, 0, Col) ->
+ Col;
+adjust_col([$\n | R], L, _) ->
+ adjust_col(R, L-1, 1);
+adjust_col([$\t | R], L, Col) ->
+ adjust_col(R, L-1, tab_forward(Col)+1);
+adjust_col([C | R], L, Col) when C>=0 andalso C=< 16#7F ->
+ adjust_col(R, L-1, Col+1);
+adjust_col([C | R], L, Col) when C>= 16#80 andalso C=< 16#7FF ->
+ adjust_col(R, L-1, Col+2);
+adjust_col([C | R], L, Col) when C>= 16#800 andalso C=< 16#FFFF ->
+ adjust_col(R, L-1, Col+3);
+adjust_col([C | R], L, Col) when C>= 16#10000 andalso C=< 16#10FFFF ->
+ adjust_col(R, L-1, Col+4).
+
+tab_forward(C) ->
+ D = C rem tab_size(),
+ A = tab_size()-D,
+ C+A.
+
+##tab_size
+
%% yystate() -> InitialState.
-%% yystate(State, InChars, Line, CurrTokLen, AcceptAction, AcceptLen) ->
-%% {Action, AcceptLen, RestChars, Line} |
-%% {Action, AcceptLen, RestChars, Line, State} |
-%% {reject, AcceptLen, CurrTokLen, RestChars, Line, State} |
-%% {Action, AcceptLen, CurrTokLen, RestChars, Line, State}.
+%% yystate(State, InChars, Line, Col, CurrTokLen, AcceptAction, AcceptLen) ->
+%% {Action, AcceptLen, RestChars, Line, Col} |
+%% {Action, AcceptLen, RestChars, Line, Col, State} |
+%% {reject, AcceptLen, CurrTokLen, RestChars, Line, Col, State} |
+%% {Action, AcceptLen, CurrTokLen, RestChars, Line, Col, State}.
%% Generated state transition functions. The non-accepting end state
%% return signal either an unrecognised character or end of current
%% input.
##dfa
-%% yyaction(Action, TokenLength, TokenChars, TokenLine) ->
+%% yyaction(Action, TokenLength, TokenChars, TokenLine, TokenCol) ->
%% {token,Token} | {end_token, Token} | skip_token | {error,String}.
%% Generated action function.
##actions
-