aboutsummaryrefslogtreecommitdiffstats
path: root/lib/parsetools/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/parsetools/src')
-rw-r--r--lib/parsetools/src/leex.erl177
-rw-r--r--lib/parsetools/src/yecc.erl53
2 files changed, 145 insertions, 85 deletions
diff --git a/lib/parsetools/src/leex.erl b/lib/parsetools/src/leex.erl
index d0b4b9efe7..cdf20461d9 100644
--- a/lib/parsetools/src/leex.erl
+++ b/lib/parsetools/src/leex.erl
@@ -35,7 +35,7 @@
-export([compile/3,file/1,file/2,format_error/1]).
-import(lists, [member/2,reverse/1,sort/1,delete/2,
- keysort/2,keydelete/3,keyfind/3,
+ keysort/2,keydelete/3,
map/2,foldl/3,foreach/2,flatmap/2]).
-import(string, [substr/2,substr/3,span/2]).
-import(ordsets, [is_element/2,add_element/2,union/2]).
@@ -58,7 +58,7 @@
gfile=[], % Graph file
module, % Module name
opts=[], % Options
- posix=false, % POSIX regular expressions
+ % posix=false, % POSIX regular expressions
errors=[],
warnings=[]
}).
@@ -73,12 +73,15 @@
%%% Interface to erl_compile.
compile(Input0, Output0,
- #options{warning = WarnLevel, verbose=Verbose, includes=Includes}) ->
+ #options{warning = WarnLevel, verbose=Verbose, includes=Includes,
+ specific=Specific}) ->
Input = assure_extension(shorten_filename(Input0), ".xrl"),
Output = assure_extension(shorten_filename(Output0), ".erl"),
Includefile = lists:sublist(Includes, 1),
+ Werror = proplists:get_bool(warnings_as_errors, Specific),
Opts = [{scannerfile,Output},{includefile,Includefile},{verbose,Verbose},
- {report_errors,true},{report_warnings,WarnLevel > 0}],
+ {report_errors,true},{report_warnings,WarnLevel > 0},
+ {warnings_as_errors, Werror}],
case file(Input, Opts) of
{ok, _} ->
ok;
@@ -107,10 +110,15 @@ file(File, Opts0) ->
St = try
{ok,REAs,Actions,Code,St2} = parse_file(St1),
{DFA,DF} = make_dfa(REAs, St2),
- St3 = out_file(St2, DFA, DF, Actions, Code),
- case lists:member(dfa_graph, St3#leex.opts) of
- true -> out_dfa_graph(St3, DFA, DF);
- false -> St3
+ case werror(St2) of
+ false ->
+ St3 = out_file(St2, DFA, DF, Actions, Code),
+ case lists:member(dfa_graph, St3#leex.opts) of
+ true -> out_dfa_graph(St3, DFA, DF);
+ false -> St3
+ end;
+ true ->
+ St2
end
catch #leex{}=St4 ->
St4
@@ -131,8 +139,8 @@ format_error({regexp,E})->
"unterminated " ++ Cs;
{illegal_char,Cs} ->
"illegal character " ++ Cs;
- {posix_cc,What} ->
- ["illegal POSIX character class ",io_lib:write_string(What)];
+%% {posix_cc,What} ->
+%% ["illegal POSIX character class ",io_lib:write_string(What)];
{char_class,What} ->
["illegal character class ",io_lib:write_string(What)]
end,
@@ -163,7 +171,8 @@ options(Options0) when is_list(Options0) ->
(T) -> [T]
end, Options0),
options(Options, [scannerfile,includefile,report_errors,
- report_warnings,return_errors,return_warnings,
+ report_warnings,warnings_as_errors,
+ return_errors,return_warnings,
verbose,dfa_graph], [])
catch error: _ -> badarg
end;
@@ -217,6 +226,7 @@ default_option(dfa_graph) -> false;
default_option(includefile) -> [];
default_option(report_errors) -> true;
default_option(report_warnings) -> true;
+default_option(warnings_as_errors) -> false;
default_option(return_errors) -> false;
default_option(return_warnings) -> false;
default_option(scannerfile) -> [];
@@ -225,6 +235,7 @@ default_option(verbose) -> false.
atom_option(dfa_graph) -> {dfa_graph,true};
atom_option(report_errors) -> {report_errors,true};
atom_option(report_warnings) -> {report_warnings,true};
+atom_option(warnings_as_errors) -> {warnings_as_errors,true};
atom_option(return_errors) -> {return_errors,true};
atom_option(return_warnings) -> {return_warnings,true};
atom_option(verbose) -> {verbose,true};
@@ -251,19 +262,29 @@ leex_ret(St) ->
report_warnings(St),
Es = pack_errors(St#leex.errors),
Ws = pack_warnings(St#leex.warnings),
+ Werror = werror(St),
if
+ Werror ->
+ do_error_return(St, Es, Ws);
Es =:= [] ->
case member(return_warnings, St#leex.opts) of
true -> {ok, St#leex.efile, Ws};
false -> {ok, St#leex.efile}
end;
- true ->
- case member(return_errors, St#leex.opts) of
- true -> {error, Es, Ws};
- false -> error
- end
+ true ->
+ do_error_return(St, Es, Ws)
+ end.
+
+do_error_return(St, Es, Ws) ->
+ case member(return_errors, St#leex.opts) of
+ true -> {error, Es, Ws};
+ false -> error
end.
+werror(St) ->
+ St#leex.warnings =/= []
+ andalso member(warnings_as_errors, St#leex.opts).
+
pack_errors([{File,_} | _] = Es) ->
[{File, flatmap(fun({_,E}) -> [E] end, sort(Es))}];
pack_errors([]) ->
@@ -286,16 +307,26 @@ report_errors(St) ->
end, report_errors, St#leex.opts).
report_warnings(St) ->
- when_opt(fun () ->
- foreach(fun({File,{none,Mod,W}}) ->
- io:fwrite("~s: Warning: ~s\n",
- [File,Mod:format_error(W)]);
- ({File,{Line,Mod,W}}) ->
- io:fwrite("~s:~w: Warning: ~s\n",
- [File,Line,Mod:format_error(W)])
- end, sort(St#leex.warnings))
- end, report_warnings, St#leex.opts).
-
+ Werror = member(warnings_as_errors, St#leex.opts),
+ Prefix = case Werror of
+ true -> "";
+ false -> "Warning: "
+ end,
+ ReportWerror = Werror andalso member(report_errors, St#leex.opts),
+ ShouldReport = member(report_warnings, St#leex.opts) orelse ReportWerror,
+ when_bool(fun () ->
+ foreach(fun({File,{none,Mod,W}}) ->
+ io:fwrite("~s: ~s~s\n",
+ [File,Prefix,
+ Mod:format_error(W)]);
+ ({File,{Line,Mod,W}}) ->
+ io:fwrite("~s:~w: ~s~s\n",
+ [File,Line,Prefix,
+ Mod:format_error(W)])
+ end, sort(St#leex.warnings))
+ end, ShouldReport).
+
+-spec add_error(_, #leex{}) -> no_return().
add_error(E, St) ->
add_error(St#leex.xfile, E, St).
@@ -341,6 +372,12 @@ when_opt(Do, Opt, Opts) ->
false -> ok
end.
+when_bool(Do, Bool) ->
+ case Bool of
+ true -> Do();
+ false -> ok
+ end.
+
verbose_print(St, Format, Args) ->
when_opt(fun () -> io:fwrite(Format, Args) end, verbose, St#leex.opts).
@@ -644,14 +681,14 @@ re_repeat1([$*|Cs], Sn, S, St) -> re_repeat1(Cs, Sn, {kclosure,S}, St);
re_repeat1([$+|Cs], Sn, S, St) -> re_repeat1(Cs, Sn, {pclosure,S}, St);
re_repeat1([$?|Cs], Sn, S, St) -> re_repeat1(Cs, Sn, {optional,S}, St);
%% { only starts interval when ere is true, otherwise normal character.
-re_repeat1([${|Cs0], Sn, S, #leex{posix=true}=St) -> % $}
- case re_interval_range(Cs0) of
- {Min,Max,[$}|Cs1]} when is_integer(Min), is_integer(Max), Min =< Max ->
- re_repeat1(Cs1, Sn, {interval,S,Min,Max}, St);
- {Min,Max,[$}|Cs1]} when is_integer(Min), is_atom(Max) ->
- re_repeat1(Cs1, Sn, {interval,S,Min,Max}, St);
- {_,_,Cs1} -> parse_error({interval_range,string_between([${|Cs0], Cs1)})
- end;
+%% re_repeat1([${|Cs0], Sn, S, #leex{posix=true}=St) -> % $}
+%% case re_interval_range(Cs0) of
+%% {Min,Max,[$}|Cs1]} when is_integer(Min), is_integer(Max), Min =< Max ->
+%% re_repeat1(Cs1, Sn, {interval,S,Min,Max}, St);
+%% {Min,Max,[$}|Cs1]} when is_integer(Min), is_atom(Max) ->
+%% re_repeat1(Cs1, Sn, {interval,S,Min,Max}, St);
+%% {_,_,Cs1} -> parse_error({interval_range,string_between([${|Cs0], Cs1)})
+%% end;
re_repeat1(Cs, Sn, S, _) -> {S,Sn,Cs}.
%% re_single(Chars, SubNumber, State) -> {RegExp,SubNumber,Chars}.
@@ -733,7 +770,7 @@ special_char($|, _) -> true;
special_char($*, _) -> true;
special_char($+, _) -> true;
special_char($?, _) -> true;
-special_char(${, #leex{posix=true}) -> true; % Only when POSIX set
+%% special_char(${, #leex{posix=true}) -> true; % Only when POSIX set
special_char($\\, _) -> true;
special_char(_, _) -> false.
@@ -744,12 +781,12 @@ re_char_class([$]|Cs], St) -> % Must special case this.
re_char_class(Cs, [$]], St);
re_char_class(Cs, St) -> re_char_class(Cs, [], St).
-re_char_class("[:" ++ Cs0, Cc, #leex{posix=true}=St) ->
- %% POSIX char class only.
- case posix_cc(Cs0) of
- {Pcl,":]" ++ Cs1} -> re_char_class(Cs1, [{posix,Pcl}|Cc], St);
- {_,Cs1} -> parse_error({posix_cc,string_between(Cs0, Cs1)})
- end;
+%% re_char_class("[:" ++ Cs0, Cc, #leex{posix=true}=St) ->
+%% %% POSIX char class only.
+%% case posix_cc(Cs0) of
+%% {Pcl,":]" ++ Cs1} -> re_char_class(Cs1, [{posix,Pcl}|Cc], St);
+%% {_,Cs1} -> parse_error({posix_cc,string_between(Cs0, Cs1)})
+%% end;
re_char_class([C1|Cs0], Cc, St) when C1 =/= $] ->
case re_char(C1, Cs0) of
{Cf,[$-,C2|Cs1]} when C2 =/= $] ->
@@ -766,19 +803,19 @@ re_char_class(Cs, Cc, _) -> {reverse(Cc),Cs}. % Preserve order
%% posix_cc(String) -> {PosixClass,RestString}.
%% Handle POSIX character classes.
-posix_cc("alnum" ++ Cs) -> {alnum,Cs};
-posix_cc("alpha" ++ Cs) -> {alpha,Cs};
-posix_cc("blank" ++ Cs) -> {blank,Cs};
-posix_cc("cntrl" ++ Cs) -> {cntrl,Cs};
-posix_cc("digit" ++ Cs) -> {digit,Cs};
-posix_cc("graph" ++ Cs) -> {graph,Cs};
-posix_cc("lower" ++ Cs) -> {lower,Cs};
-posix_cc("print" ++ Cs) -> {print,Cs};
-posix_cc("punct" ++ Cs) -> {punct,Cs};
-posix_cc("space" ++ Cs) -> {space,Cs};
-posix_cc("upper" ++ Cs) -> {upper,Cs};
-posix_cc("xdigit" ++ Cs) -> {xdigit,Cs};
-posix_cc(Cs) -> parse_error({posix_cc,substr(Cs, 1, 5)}).
+%% posix_cc("alnum" ++ Cs) -> {alnum,Cs};
+%% posix_cc("alpha" ++ Cs) -> {alpha,Cs};
+%% posix_cc("blank" ++ Cs) -> {blank,Cs};
+%% posix_cc("cntrl" ++ Cs) -> {cntrl,Cs};
+%% posix_cc("digit" ++ Cs) -> {digit,Cs};
+%% posix_cc("graph" ++ Cs) -> {graph,Cs};
+%% posix_cc("lower" ++ Cs) -> {lower,Cs};
+%% posix_cc("print" ++ Cs) -> {print,Cs};
+%% posix_cc("punct" ++ Cs) -> {punct,Cs};
+%% posix_cc("space" ++ Cs) -> {space,Cs};
+%% posix_cc("upper" ++ Cs) -> {upper,Cs};
+%% posix_cc("xdigit" ++ Cs) -> {xdigit,Cs};
+%% posix_cc(Cs) -> parse_error({posix_cc,substr(Cs, 1, 5)}).
escape_char($n) -> $\n; % \n = LF
escape_char($r) -> $\r; % \r = CR
@@ -797,24 +834,24 @@ escape_char(C) -> C. % Pass it straight through
%% Int, -> Int,any
%% Int1,Int2 -> Int1,Int2
-re_interval_range(Cs0) ->
- case re_number(Cs0) of
- {none,Cs1} -> {none,none,Cs1};
- {N,[$,|Cs1]} ->
- case re_number(Cs1) of
- {none,Cs2} -> {N,any,Cs2};
- {M,Cs2} -> {N,M,Cs2}
- end;
- {N,Cs1} -> {N,none,Cs1}
- end.
+%% re_interval_range(Cs0) ->
+%% case re_number(Cs0) of
+%% {none,Cs1} -> {none,none,Cs1};
+%% {N,[$,|Cs1]} ->
+%% case re_number(Cs1) of
+%% {none,Cs2} -> {N,any,Cs2};
+%% {M,Cs2} -> {N,M,Cs2}
+%% end;
+%% {N,Cs1} -> {N,none,Cs1}
+%% end.
-re_number([C|Cs]) when C >= $0, C =< $9 ->
- re_number(Cs, C - $0);
-re_number(Cs) -> {none,Cs}.
+%% re_number([C|Cs]) when C >= $0, C =< $9 ->
+%% re_number(Cs, C - $0);
+%% re_number(Cs) -> {none,Cs}.
-re_number([C|Cs], Acc) when C >= $0, C =< $9 ->
- re_number(Cs, 10*Acc + (C - $0));
-re_number(Cs, Acc) -> {Acc,Cs}.
+%% re_number([C|Cs], Acc) when C >= $0, C =< $9 ->
+%% re_number(Cs, 10*Acc + (C - $0));
+%% re_number(Cs, Acc) -> {Acc,Cs}.
string_between(Cs1, Cs2) ->
substr(Cs1, 1, length(Cs1)-length(Cs2)).
diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl
index 4119e2631b..354d56527d 100644
--- a/lib/parsetools/src/yecc.erl
+++ b/lib/parsetools/src/yecc.erl
@@ -133,12 +133,15 @@
%%% Interface to erl_compile.
compile(Input0, Output0,
- #options{warning = WarnLevel, verbose=Verbose, includes=Includes}) ->
+ #options{warning = WarnLevel, verbose=Verbose, includes=Includes,
+ specific=Specific}) ->
Input = shorten_filename(Input0),
Output = shorten_filename(Output0),
Includefile = lists:sublist(Includes, 1),
+ Werror = proplists:get_bool(warnings_as_errors, Specific),
Opts = [{parserfile,Output}, {includefile,Includefile}, {verbose,Verbose},
- {report_errors, true}, {report_warnings, WarnLevel > 0}],
+ {report_errors, true}, {report_warnings, WarnLevel > 0},
+ {warnings_as_errors, Werror}],
case file(Input, Opts) of
{ok, _OutFile} ->
ok;
@@ -278,8 +281,8 @@ options(Options0) when is_list(Options0) ->
(T) -> [T]
end, Options0),
options(Options, [file_attributes, includefile, parserfile,
- report_errors, report_warnings, return_errors,
- return_warnings, time, verbose], [])
+ report_errors, report_warnings, warnings_as_errors,
+ return_errors, return_warnings, time, verbose], [])
catch error: _ -> badarg
end;
options(Option) ->
@@ -333,6 +336,7 @@ default_option(includefile) -> [];
default_option(parserfile) -> [];
default_option(report_errors) -> true;
default_option(report_warnings) -> true;
+default_option(warnings_as_errors) -> false;
default_option(return_errors) -> false;
default_option(return_warnings) -> false;
default_option(time) -> false;
@@ -341,6 +345,7 @@ default_option(verbose) -> false.
atom_option(file_attributes) -> {file_attributes, true};
atom_option(report_errors) -> {report_errors, true};
atom_option(report_warnings) -> {report_warnings, true};
+atom_option(warnings_as_errors) -> {warnings_as_errors,true};
atom_option(return_errors) -> {return_errors, true};
atom_option(return_warnings) -> {return_warnings, true};
atom_option(time) -> {time, true};
@@ -409,12 +414,16 @@ infile(Parent, Infilex, Options) ->
{error, Reason} ->
add_error(St0#yecc.infile, none, {file_error, Reason}, St0)
end,
- case St#yecc.errors of
- [] -> ok;
+ case {St#yecc.errors, werror(St)} of
+ {[], false} -> ok;
_ -> _ = file:delete(St#yecc.outfile)
end,
Parent ! {self(), yecc_ret(St)}.
+werror(St) ->
+ St#yecc.warnings =/= []
+ andalso member(warnings_as_errors, St#yecc.options).
+
outfile(St0) ->
case file:open(St0#yecc.outfile, [write, delayed_write]) of
{ok, Outport} ->
@@ -777,17 +786,23 @@ yecc_ret(St0) ->
report_warnings(St),
Es = pack_errors(St#yecc.errors),
Ws = pack_warnings(St#yecc.warnings),
+ Werror = werror(St),
if
+ Werror ->
+ do_error_return(St, Es, Ws);
Es =:= [] ->
case member(return_warnings, St#yecc.options) of
true -> {ok, St#yecc.outfile, Ws};
false -> {ok, St#yecc.outfile}
end;
true ->
- case member(return_errors, St#yecc.options) of
- true -> {error, Es, Ws};
- false -> error
- end
+ do_error_return(St, Es, Ws)
+ end.
+
+do_error_return(St, Es, Ws) ->
+ case member(return_errors, St#yecc.options) of
+ true -> {error, Es, Ws};
+ false -> error
end.
check_expected(St0) ->
@@ -837,14 +852,22 @@ report_errors(St) ->
end.
report_warnings(St) ->
- case member(report_warnings, St#yecc.options) of
+ Werror = member(warnings_as_errors, St#yecc.options),
+ Prefix = case Werror of
+ true -> "";
+ false -> "Warning: "
+ end,
+ ReportWerror = Werror andalso member(report_errors, St#yecc.options),
+ case member(report_warnings, St#yecc.options) orelse ReportWerror of
true ->
foreach(fun({File,{none,Mod,W}}) ->
- io:fwrite(<<"~s: Warning: ~s\n">>,
- [File,Mod:format_error(W)]);
+ io:fwrite(<<"~s: ~s~s\n">>,
+ [File,Prefix,
+ Mod:format_error(W)]);
({File,{Line,Mod,W}}) ->
- io:fwrite(<<"~s:~w: Warning: ~s\n">>,
- [File,Line,Mod:format_error(W)])
+ io:fwrite(<<"~s:~w: ~s~s\n">>,
+ [File,Line,Prefix,
+ Mod:format_error(W)])
end, sort(St#yecc.warnings));
false ->
ok