diff options
Diffstat (limited to 'lib/parsetools/include/leexinc.hrl')
-rw-r--r-- | lib/parsetools/include/leexinc.hrl | 377 |
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 - |