[m-rev.] for post-commit review: fix dead_proc_elim bug
Zoltan Somogyi
zs at csse.unimelb.edu.au
Wed Aug 8 15:04:05 AEST 2007
Fix an old bug described by this comment:
% Some eval methods cause the procedure implementation to include
% a global variable representing the root of the per-procedure call
% and answer tables. In some rare cases, the code of a tabled
% procedure may be dead, but other predicates (such as the
% predicate to reset the table) that refer to the global are
% still alive. In such cases, we cannot eliminate the tabled
% procedure itself, since doing so would also eliminate the
% definition of the global variable, leaving a dangling reference.
compiler/dead_proc_elim.m:
Fix the bug described above.
Fix some obsolete documentation and predicate names.
Introduce some new types that make the code easier to read.
Rename some ambiguous and/or obsolete function symbols.
compiler/*.m:
Conform to the changes in dead_proc_elim.m.
tests/valid/mercury_java_parser_dead_proc_elim_bug.m:
New test case for this bug.
tests/valid/Mmakefile:
Enable the new test case.
tests/valid/Mercury.options:
Get the new test case compiled to executable, not just to a .c file,
to give a chance for the link error to manifest itself.
Zoltan.
cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/dead_proc_elim.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dead_proc_elim.m,v
retrieving revision 1.122
diff -u -b -r1.122 dead_proc_elim.m
--- compiler/dead_proc_elim.m 8 Jun 2007 00:47:08 -0000 1.122
+++ compiler/dead_proc_elim.m 8 Aug 2007 05:01:10 -0000
@@ -29,13 +29,12 @@
:- import_module list.
:- import_module map.
-:- import_module maybe.
%-----------------------------------------------------------------------------%
:- type dead_proc_pass
- ---> warning_pass
- ; final_optimization_pass.
+ ---> dead_proc_warning_pass
+ ; dead_proc_final_optimization_pass.
% Eliminate dead procedures. If the first argument is `warning_pass',
% also warn about any user-defined procedures that are dead.
@@ -61,10 +60,14 @@
:- pred dead_pred_elim(module_info::in, module_info::out) is det.
:- type entity
- ---> proc(pred_id, proc_id)
- ; base_gen_info(module_name, string, int).
+ ---> entity_proc(pred_id, proc_id)
+ ; entity_type_ctor(module_name, string, int).
+
+:- type needed_map == map(entity, maybe_needed).
-:- type needed_map == map(entity, maybe(int)).
+:- type maybe_needed
+ ---> not_eliminable
+ ; maybe_eliminable(num_references :: int).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -87,6 +90,7 @@
:- import_module bool.
:- import_module int.
:- import_module io.
+:- import_module maybe.
:- import_module pair.
:- import_module queue.
:- import_module set.
@@ -97,7 +101,7 @@
%-----------------------------------------------------------------------------%
-% We deal with two kinds of entities, procedures and base_gen_info structures.
+% We deal with two kinds of entities, procedures and type_ctor_info structures.
%
% The algorithm has three main data structures:
%
@@ -110,14 +114,14 @@
% - a set of entities that have been examined.
%
% The needed map and the queue are both initialized with the ids of the
-% procedures and base_gen_info structures exported from the module.
+% procedures and type_ctor_info structures exported from the module.
% The algorithm then takes the ids of entities from the queue one at a time,
% and if the entity hasn't been examined before, examines the entity
% definition to find all mention of other entities. Their ids are then
% put into both the needed map and the queue.
%
% The final pass of the algorithm deletes from the HLDS any procedure
-% or base_gen_info structure whose id is not in the needed map.
+% or type_ctor_info structure whose id is not in the needed map.
:- type entity_queue == queue(entity).
:- type examined_set == set(entity).
@@ -157,7 +161,7 @@
dead_proc_initialize_init_fn_procs(FinalPreds, !Queue, !Needed),
module_info_get_type_ctor_gen_infos(!.ModuleInfo, TypeCtorGenInfos),
- dead_proc_initialize_base_gen_infos(TypeCtorGenInfos, !Queue, !Needed),
+ dead_proc_initialize_type_ctor_infos(TypeCtorGenInfos, !Queue, !Needed),
module_info_get_class_table(!.ModuleInfo, Classes),
module_info_get_instance_table(!.ModuleInfo, Instances),
@@ -185,8 +189,9 @@
dead_proc_initialize_procs(_PredId, [], !Queue, !Needed).
dead_proc_initialize_procs(PredId, [ProcId | ProcIds], !Queue, !Needed) :-
- svqueue.put(proc(PredId, ProcId), !Queue),
- svmap.set(proc(PredId, ProcId), no, !Needed),
+ Entity = entity_proc(PredId, ProcId),
+ svqueue.put(Entity, !Queue),
+ svmap.set(Entity, not_eliminable, !Needed),
dead_proc_initialize_procs(PredId, ProcIds, !Queue, !Needed).
% Add procedures exported to foreign language by a `:- pragma
@@ -201,8 +206,9 @@
!Queue, !Needed) :-
PragmaProc = pragma_exported_proc(_Lang, PredId, ProcId,
_ExportName, _Ctxt),
- svqueue.put(proc(PredId, ProcId), !Queue),
- svmap.set(proc(PredId, ProcId), no, !Needed),
+ Entity = entity_proc(PredId, ProcId),
+ svqueue.put(Entity, !Queue),
+ svmap.set(Entity, not_eliminable, !Needed),
dead_proc_initialize_pragma_exports(PragmaProcs, !Queue, !Needed).
% Add module initialisation/finalisation procedures to the queue and map
@@ -215,16 +221,17 @@
dead_proc_initialize_init_fn_procs([], !Queue, !Needed).
dead_proc_initialize_init_fn_procs([PPId | PPIds], !Queue, !Needed) :-
PPId = proc(PredId, ProcId),
- svqueue.put(proc(PredId, ProcId), !Queue),
- svmap.set(proc(PredId, ProcId), no, !Needed),
+ Entity = entity_proc(PredId, ProcId),
+ svqueue.put(Entity, !Queue),
+ svmap.set(Entity, not_eliminable, !Needed),
dead_proc_initialize_init_fn_procs(PPIds, !Queue, !Needed).
-:- pred dead_proc_initialize_base_gen_infos(list(type_ctor_gen_info)::in,
+:- pred dead_proc_initialize_type_ctor_infos(list(type_ctor_gen_info)::in,
entity_queue::in, entity_queue::out, needed_map::in, needed_map::out)
is det.
-dead_proc_initialize_base_gen_infos([], !Queue, !Needed).
-dead_proc_initialize_base_gen_infos([TypeCtorGenInfo | TypeCtorGenInfos],
+dead_proc_initialize_type_ctor_infos([], !Queue, !Needed).
+dead_proc_initialize_type_ctor_infos([TypeCtorGenInfo | TypeCtorGenInfos],
!Queue, !Needed) :-
TypeCtorGenInfo = type_ctor_gen_info(_TypeCtor, ModuleName, TypeName,
Arity, _Status, _HldsDefn, _Unify, _Compare),
@@ -245,13 +252,13 @@
% and hence no special preds will be eliminated.
semidet_succeed
->
- Entity = base_gen_info(ModuleName, TypeName, Arity),
+ Entity = entity_type_ctor(ModuleName, TypeName, Arity),
svqueue.put(Entity, !Queue),
- svmap.set(Entity, no, !Needed)
+ svmap.set(Entity, not_eliminable, !Needed)
;
true
),
- dead_proc_initialize_base_gen_infos(TypeCtorGenInfos, !Queue, !Needed).
+ dead_proc_initialize_type_ctor_infos(TypeCtorGenInfos, !Queue, !Needed).
:- pred dead_proc_initialize_class_methods(class_table::in,
instance_table::in, entity_queue::in, entity_queue::out,
@@ -274,7 +281,7 @@
% We need to keep the instance methods for all instances
% for optimization of method lookups.
(
- % This should never happen
+ % This should never happen.
PredProcIds = no
;
PredProcIds = yes(Ids),
@@ -295,8 +302,9 @@
get_class_interface_pred_proc(ClassProc, !Queue, !Needed) :-
ClassProc = hlds_class_proc(PredId, ProcId),
- svqueue.put(proc(PredId, ProcId), !Queue),
- svmap.set(proc(PredId, ProcId), no, !Needed).
+ Entity = entity_proc(PredId, ProcId),
+ svqueue.put(Entity, !Queue),
+ svmap.set(Entity, not_eliminable, !Needed).
%-----------------------------------------------------------------------------%
@@ -312,12 +320,12 @@
;
svset.insert(Entity, !Examined),
(
- Entity = proc(PredId, ProcId),
+ Entity = entity_proc(PredId, ProcId),
PredProcId = proc(PredId, ProcId),
dead_proc_examine_proc(PredProcId, ModuleInfo, !Queue, !Needed)
;
- Entity = base_gen_info(Module, Type, Arity),
- dead_proc_examine_base_gen_info(Module, Type, Arity,
+ Entity = entity_type_ctor(Module, Type, Arity),
+ dead_proc_examine_type_ctor_info(Module, Type, Arity,
ModuleInfo, !Queue, !Needed)
),
dead_proc_examine(!.Queue, !.Examined, ModuleInfo, !Needed)
@@ -328,15 +336,15 @@
%-----------------------------------------------------------------------------%
-:- pred dead_proc_examine_base_gen_info(module_name::in, string::in,
+:- pred dead_proc_examine_type_ctor_info(module_name::in, string::in,
arity::in, module_info::in, entity_queue::in, entity_queue::out,
needed_map::in, needed_map::out) is det.
-dead_proc_examine_base_gen_info(ModuleName, TypeName, Arity, ModuleInfo,
+dead_proc_examine_type_ctor_info(ModuleName, TypeName, Arity, ModuleInfo,
!Queue, !Needed) :-
module_info_get_type_ctor_gen_infos(ModuleInfo, TypeCtorGenInfos),
(
- find_base_gen_info(ModuleName, TypeName, Arity, TypeCtorGenInfos,
+ find_type_ctor_info(ModuleName, TypeName, Arity, TypeCtorGenInfos,
Refs)
->
dead_proc_examine_refs(Refs, !Queue, !Needed)
@@ -344,11 +352,11 @@
true
).
-:- pred find_base_gen_info(module_name::in, string::in,
+:- pred find_type_ctor_info(module_name::in, string::in,
arity::in, list(type_ctor_gen_info)::in, list(pred_proc_id)::out)
is semidet.
-find_base_gen_info(ModuleName, TypeName, TypeArity,
+find_type_ctor_info(ModuleName, TypeName, TypeArity,
[TypeCtorGenInfo | TypeCtorGenInfos], Refs) :-
(
TypeCtorGenInfo = type_ctor_gen_info(_TypeCtor, ModuleName,
@@ -356,7 +364,7 @@
->
Refs = [Unify, Compare]
;
- find_base_gen_info(ModuleName, TypeName, TypeArity, TypeCtorGenInfos,
+ find_type_ctor_info(ModuleName, TypeName, TypeArity, TypeCtorGenInfos,
Refs)
).
@@ -373,9 +381,9 @@
dead_proc_examine_refs([], !Queue, !Needed).
dead_proc_examine_refs([Ref | Refs], !Queue, !Needed) :-
Ref = proc(PredId, ProcId),
- Entity = proc(PredId, ProcId),
+ Entity = entity_proc(PredId, ProcId),
svqueue.put(Entity, !Queue),
- svmap.set(Entity, no, !Needed),
+ svmap.set(Entity, not_eliminable, !Needed),
dead_proc_examine_refs(Refs, !Queue, !Needed).
%-----------------------------------------------------------------------------%
@@ -448,43 +456,45 @@
dead_proc_examine_expr(generic_call(_,_,_,_), _, !Queue, !Needed).
dead_proc_examine_expr(plain_call(PredId, ProcId, _,_,_,_), CurrProc, !Queue,
!Needed) :-
- queue.put(!.Queue, proc(PredId, ProcId), !:Queue),
+ Entity = entity_proc(PredId, ProcId),
+ queue.put(!.Queue, Entity, !:Queue),
( proc(PredId, ProcId) = CurrProc ->
- % if it's reachable and recursive, then we can't
- % eliminate or inline it
- NewNotation = no,
- svmap.set(proc(PredId, ProcId), NewNotation, !Needed)
- ; map.search(!.Needed, proc(PredId, ProcId), OldNotation) ->
- (
- OldNotation = no,
- NewNotation = no
+ % If it's reachable and recursive, then we can't eliminate it
+ % or inline it.
+ NewNotation = not_eliminable,
+ svmap.set(Entity, NewNotation, !Needed)
+ ; map.search(!.Needed, Entity, OldNotation) ->
+ (
+ OldNotation = not_eliminable,
+ NewNotation = not_eliminable
;
- OldNotation = yes(Count),
- NewNotation = yes(Count + 1)
+ OldNotation = maybe_eliminable(Count),
+ NewNotation = maybe_eliminable(Count + 1)
),
- svmap.det_update(proc(PredId, ProcId), NewNotation, !Needed)
+ svmap.det_update(Entity, NewNotation, !Needed)
;
- NewNotation = yes(1),
- svmap.set(proc(PredId, ProcId), NewNotation, !Needed)
+ NewNotation = maybe_eliminable(1),
+ svmap.set(Entity, NewNotation, !Needed)
).
dead_proc_examine_expr(call_foreign_proc(_, PredId, ProcId, _, _, _, _),
_CurrProc, !Queue, !Needed) :-
- svqueue.put(proc(PredId, ProcId), !Queue),
- svmap.set(proc(PredId, ProcId), no, !Needed).
+ Entity = entity_proc(PredId, ProcId),
+ svqueue.put(Entity, !Queue),
+ svmap.set(Entity, not_eliminable, !Needed).
dead_proc_examine_expr(unify(_,_,_, Uni, _), _CurrProc, !Queue, !Needed) :-
(
Uni = construct(_, ConsId, _, _, _, _, _),
(
ConsId = pred_const(ShroudedPredProcId, _),
proc(PredId, ProcId) = unshroud_pred_proc_id(ShroudedPredProcId),
- Entity = proc(PredId, ProcId)
+ Entity = entity_proc(PredId, ProcId)
;
ConsId = type_ctor_info_const(Module, TypeName, Arity),
- Entity = base_gen_info(Module, TypeName, Arity)
+ Entity = entity_type_ctor(Module, TypeName, Arity)
)
->
svqueue.put(Entity, !Queue),
- svmap.set(Entity, no, !Needed)
+ svmap.set(Entity, not_eliminable, !Needed)
;
true
).
@@ -531,7 +541,7 @@
module_info_set_preds(PredTable, !ModuleInfo),
module_info_get_type_ctor_gen_infos(!.ModuleInfo, TypeCtorGenInfos0),
- dead_proc_eliminate_base_gen_infos(TypeCtorGenInfos0, !.Needed,
+ dead_proc_eliminate_type_ctor_infos(TypeCtorGenInfos0, !.Needed,
TypeCtorGenInfos),
module_info_set_type_ctor_gen_infos(TypeCtorGenInfos, !ModuleInfo),
(
@@ -607,7 +617,7 @@
% by this point managed to inline or specialize; this code should be
% called with `Pass = final_optimization_pass' only after inlining
% and specialization is complete).
- Pass = final_optimization_pass,
+ Pass = dead_proc_final_optimization_pass,
Status = status_opt_imported
->
Changed = yes,
@@ -660,10 +670,26 @@
Needed = ProcElimInfo ^ proc_elim_needed_map,
ModuleInfo = ProcElimInfo ^ proc_elim_module_info,
(
- % Keep the procedure if it is in the needed map
- % or if it is to be kept because it is exported.
- ( map.search(Needed, proc(PredId, ProcId), _)
- ; Keep = yes(ProcId)
+ (
+ % Keep the procedure if it is in the needed map.
+ map.search(Needed, entity_proc(PredId, ProcId), _)
+ ;
+ % Or if it is to be kept because it is exported.
+ Keep = yes(ProcId)
+ ;
+ % Or if its elimination could cause a link error.
+ % Some eval methods cause the procedure implementation to include
+ % a global variable representing the root of the per-procedure call
+ % and answer tables. In some rare cases, the code of a tabled
+ % procedure may be dead, but other predicates (such as the
+ % predicate to reset the table) that refer to the global are
+ % still alive. In such cases, we cannot eliminate the tabled
+ % procedure itself, since doing so would also eliminate the
+ % definition of the global variable, leaving a dangling reference.
+
+ map.lookup(!.ProcTable, ProcId, ProcInfo),
+ proc_info_get_eval_method(ProcInfo, EvalMethod),
+ eval_method_has_per_proc_tabling_pointer(EvalMethod) = yes
)
->
true
@@ -704,18 +730,18 @@
[option_is_set(warn_dead_procs, yes, [always(Pieces)])]),
Spec = error_spec(severity_warning, phase_dead_code, [Msg]).
-:- pred dead_proc_eliminate_base_gen_infos(list(type_ctor_gen_info)::in,
+:- pred dead_proc_eliminate_type_ctor_infos(list(type_ctor_gen_info)::in,
needed_map::in, list(type_ctor_gen_info)::out) is det.
-dead_proc_eliminate_base_gen_infos([], _Needed, []).
-dead_proc_eliminate_base_gen_infos([TypeCtorGenInfo0 | TypeCtorGenInfos0],
+dead_proc_eliminate_type_ctor_infos([], _Needed, []).
+dead_proc_eliminate_type_ctor_infos([TypeCtorGenInfo0 | TypeCtorGenInfos0],
Needed, TypeCtorGenInfos) :-
- dead_proc_eliminate_base_gen_infos(TypeCtorGenInfos0, Needed,
+ dead_proc_eliminate_type_ctor_infos(TypeCtorGenInfos0, Needed,
TypeCtorGenInfos1),
TypeCtorGenInfo0 = type_ctor_gen_info(_TypeCtor, ModuleName,
TypeName, Arity, _Status, _HldsDefn, _Unify, _Compare),
(
- Entity = base_gen_info(ModuleName, TypeName, Arity),
+ Entity = entity_type_ctor(ModuleName, TypeName, Arity),
map.search(Needed, Entity, _)
->
TypeCtorGenInfos = [TypeCtorGenInfo0 | TypeCtorGenInfos1]
@@ -796,8 +822,8 @@
:- pred dead_pred_elim_add_entity(entity::in, queue(pred_id)::in,
queue(pred_id)::out, set(pred_id)::in, set(pred_id)::out) is det.
-dead_pred_elim_add_entity(base_gen_info(_, _, _), !Queue, !Preds).
-dead_pred_elim_add_entity(proc(PredId, _), !Queue, !Preds) :-
+dead_pred_elim_add_entity(entity_type_ctor(_, _, _), !Queue, !Preds).
+dead_pred_elim_add_entity(entity_proc(PredId, _), !Queue, !Preds) :-
svqueue.put(PredId, !Queue),
svset.insert(PredId, !Preds).
@@ -835,9 +861,7 @@
\+ pred_info_get_import_status(PredInfo, status_opt_imported)
;
% Don't eliminate predicates declared in this module with a
- % `:- external' or `:- pragma base_relation' declaration.
- % magic.m will change the import_status to `exported' when it
- % generates the interface procedure for a base relation.
+ % `:- external' declaration.
module_info_get_name(ModuleInfo, PredModule)
;
% Don't eliminate <foo>_init_any/1 predicates; modes.m may
Index: compiler/inlining.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/inlining.m,v
retrieving revision 1.156
diff -u -b -r1.156 inlining.m
--- compiler/inlining.m 7 Aug 2007 07:09:56 -0000 1.156
+++ compiler/inlining.m 7 Aug 2007 17:21:16 -0000
@@ -284,7 +284,7 @@
pred_info_get_procedures(PredInfo, Procs),
map.lookup(Procs, ProcId, ProcInfo),
proc_info_get_goal(ProcInfo, CalledGoal),
- Entity = proc(PredId, ProcId),
+ Entity = entity_proc(PredId, ProcId),
% The heuristic represented by the following code could be improved.
(
@@ -293,7 +293,7 @@
;
CompoundThreshold > 0,
map.search(NeededMap, Entity, Needed),
- Needed = yes(NumUses),
+ Needed = maybe_eliminable(NumUses),
goal_size(CalledGoal, Size),
% The size increase due to inlining at a call site is not Size,
% but the difference between Size and the size of the call.
@@ -303,7 +303,7 @@
;
SingleUse = yes,
map.search(NeededMap, Entity, Needed),
- Needed = yes(NumUses),
+ Needed = maybe_eliminable(NumUses),
NumUses = 1
),
% Don't inline recursive predicates (unless explicitly requested).
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.445
diff -u -b -r1.445 mercury_compile.m
--- compiler/mercury_compile.m 25 Jul 2007 06:12:19 -0000 1.445
+++ compiler/mercury_compile.m 7 Aug 2007 17:13:27 -0000
@@ -3250,7 +3250,7 @@
maybe_write_string(Verbose, "% Warning about dead procedures...\n",
!IO),
maybe_flush_output(Verbose, !IO),
- dead_proc_elim(warning_pass, !.HLDS, _HLDS1, Specs),
+ dead_proc_elim(dead_proc_warning_pass, !.HLDS, _HLDS1, Specs),
maybe_write_string(Verbose, "% done.\n", !IO),
maybe_report_stats(Stats, !IO),
module_info_get_globals(!.HLDS, Globals),
@@ -3935,7 +3935,7 @@
maybe_write_string(Verbose, "% Eliminating dead procedures...\n", !IO),
maybe_flush_output(Verbose, !IO),
% Ignore any warning messages generated.
- dead_proc_elim(final_optimization_pass, !HLDS, _Specs),
+ dead_proc_elim(dead_proc_final_optimization_pass, !HLDS, _Specs),
maybe_write_string(Verbose, "% done.\n", !IO),
maybe_report_stats(Stats, !IO)
;
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
Index: mdbcomp/program_representation.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/program_representation.m,v
retrieving revision 1.22
diff -u -b -r1.22 program_representation.m
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
Index: tests/valid/Mercury.options
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/valid/Mercury.options,v
retrieving revision 1.37
diff -u -b -r1.37 Mercury.options
--- tests/valid/Mercury.options 30 May 2007 07:18:53 -0000 1.37
+++ tests/valid/Mercury.options 7 Aug 2007 17:41:18 -0000
@@ -79,6 +79,7 @@
MCFLAGS-mc_graph = --prop-mode-constraints
MCFLAGS-mc_hhf_nonlocals_bug = --prop-mode-constraints
MCFLAGS-mc_implied_modes = --prop-mode-constraints
+MCFLAGS-mercury_java_parser_dead_proc_elim_bug = --no-target-code-only
MCFLAGS-middle_rec_labels = --middle-rec
MCFLAGS-mostly_uniq_mode_inf = --infer-all
MCFLAGS-mpj6 = --infer-all
Index: tests/valid/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/valid/Mmakefile,v
retrieving revision 1.191
diff -u -b -r1.191 Mmakefile
--- tests/valid/Mmakefile 7 Aug 2007 10:03:51 -0000 1.191
+++ tests/valid/Mmakefile 7 Aug 2007 17:26:42 -0000
@@ -241,6 +241,7 @@
#
TABLE_PROGS=\
table_wrong_func_arity \
+ mercury_java_parser_dead_proc_elim_bug \
mercury_java_parser_follow_code_bug
# These tests only work in grades that support parallel conjunction.
Index: tests/valid/mercury_java_parser_dead_proc_elim_bug.m
===================================================================
RCS file: tests/valid/mercury_java_parser_dead_proc_elim_bug.m
diff -N tests/valid/mercury_java_parser_dead_proc_elim_bug.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/valid/mercury_java_parser_dead_proc_elim_bug.m 7 Aug 2007 17:29:34 -0000
@@ -0,0 +1,2124 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+%-----------------------------------------------------------------------------%
+%
+% This is a regression test. In versions of the compiler before 7 Aug 2007,
+% it used to cause a link error.
+%
+% Some eval methods cause the procedure implementation to include
+% a global variable representing the root of the per-procedure call
+% and answer tables. Since the code of a tabled procedure may
+% become dead after having been inlined in other procedures, and
+% that inlined code will refer to this global variable, we cannot
+% eliminate the procedure itself, since doing so would also
+% eliminate the definition of the global variable.
+%
+%-----------------------------------------------------------------------------%
+% mercury_java_parser_memoed.m
+% Ralph Becket <rafe at cs.mu.oz.au>
+% Mon Feb 21 09:42:40 EST 2005
+%
+% Java grammar taken from
+% http://java.sun.com/docs/books/jls/second_edition/html/syntax.doc.html
+% and converted to Mercury DCGs. And then corrected because the grammar
+% at the above page contains bugs...
+%
+% Usage: parse_java <filename> ...
+%
+% This implementation only recognises Java programs; it does not construct an
+% ADT or perform any kind of analysis. However, it has been written in a
+% style that should make it fairly easy to add construction of an ADT.
+%
+% To compile this as a packrat parser, uncomment all of the pragma memo
+% lines.
+%
+% To compile this as a partial packrat parser, uncomment all of the
+% pragma memo lines except those for literal/2, qualified_identifier/2, and
+% punct/2.
+%
+%-----------------------------------------------------------------------------%
+
+:- module mercury_java_parser_dead_proc_elim_bug.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module char.
+:- import_module exception.
+:- import_module int.
+:- import_module list.
+:- import_module pair.
+:- import_module std_util.
+:- import_module string.
+
+ % The parser "state". This is just the offset into the input string,
+ % which (depending on the version) may be passed around or stored in
+ % a C global variable.
+ %
+ % We do the latter to (a) avoid memoizing the input string if we are
+ % memoing any rules and (b) to obtain a fair timing comparison with the
+ % Rats! Java parser (www.cs.nyu.edu/rgrimm/xtc/rats.html).
+ %
+:- type ps == int.
+
+%-----------------------------------------------------------------------------%
+
+main(!IO) :-
+ io.command_line_arguments(Args, !IO),
+ list.foldl(parse_file, Args, !IO).
+
+:- pred parse_file(string::in, io::di, io::uo) is det.
+
+parse_file(Filename, !IO) :-
+ global_table_reset(!IO),
+ io.write_string(Filename, !IO),
+ io.see(Filename, _, !IO),
+ io.read_file_as_string(Result, !IO),
+ ( if Result = ok(Str) then
+ promise_pure ( impure set_input_string(Str),
+ ( if compilation_unit(0, _)
+ then
+ io.print(" parsed successfully\n", !IO)
+ else
+ io.print(" failed to parse\n", !IO)
+ )
+ )
+ else
+ throw(Result)
+ ).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+% Low-level predicates.
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+
+:- pragma foreign_decl("C", "
+
+ MR_String input_string = NULL;
+ MR_Word input_length = (MR_Word) 0;
+
+").
+
+%-----------------------------------------------------------------------------%
+
+:- impure pred set_input_string(string::in) is det.
+
+:- pragma foreign_proc("C",
+ set_input_string(Str::in),
+ [will_not_call_mercury],
+"
+ input_string = Str;
+ input_length = strlen(Str);
+").
+
+%-----------------------------------------------------------------------------%
+
+:- semipure pred input_string_and_length(string::out, int::out) is det.
+
+:- pragma foreign_proc("C",
+ input_string_and_length(Str::out, Length::out),
+ [will_not_call_mercury, promise_semipure],
+"
+ Str = input_string;
+ Length = input_length;
+").
+
+
+%-----------------------------------------------------------------------------%
+
+:- pred current_offset(int::out, int::in, int::out) is det.
+
+current_offset(Offset, Offset, Offset).
+
+%-----------------------------------------------------------------------------%
+
+:- pred eof(ps::in, ps::out) is semidet.
+
+eof(Offset, Offset) :-
+ promise_pure ( semipure input_string_and_length(_Str, Length),
+ Offset = Length
+ ).
+
+%-----------------------------------------------------------------------------%
+
+ % XXX These are really semipure, but I'm being naughty and promising them
+ % to be pure because I don't want to pollute my code with impurity
+ % annotations.
+ %
+ % XXX Also, I do not check for negative offsets. I probably should.
+ %
+:- pred char(char::out, ps::in, ps::out) is semidet.
+
+char(Char, Offset, Offset + 1) :-
+ promise_pure ( semipure input_string_and_length(Str, Length),
+ Offset < Length,
+ Char = Str ^ unsafe_elem(Offset)
+ ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred input_substring(int::in, int::in, string::out,
+ ps::in, ps::out) is semidet.
+
+input_substring(Start, End, Substring, Offset, Offset) :-
+ promise_pure ( semipure input_string_and_length(Str, Length),
+ End =< Length,
+ Substring = unsafe_substring(Str, Start, End - Start)
+ ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred match_string(string::in, int::in, int::out) is semidet.
+
+match_string(MatchStr, Offset, Offset + N) :-
+ promise_pure ( semipure input_string_and_length(Str, Length),
+ N = length(MatchStr),
+ Offset + N =< Length,
+ match_string_2(0, N, MatchStr, Offset, Str)
+ ).
+
+:- pred match_string_2(int::in, int::in, string::in, int::in, string::in)
+ is semidet.
+
+match_string_2(I, N, MatchStr, Offset, Str) :-
+ ( if I < N then
+ MatchStr ^ unsafe_elem(I) = Str ^ unsafe_elem(Offset + I),
+ match_string_2(I + 1, N, MatchStr, Offset, Str)
+ else
+ true
+ ).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+% Utility predicates.
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- pred optional_det(
+ pred(ps, ps):: in(pred(in, out) is semidet),
+ ps::in, ps::out) is det.
+
+optional_det(P) -->
+ ( if P then
+ []
+ else
+ []
+ ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred zero_or_more_det(
+ pred(ps, ps)::in(pred(in, out) is semidet),
+ ps::in, ps::out) is det.
+
+zero_or_more_det(P) -->
+ ( if P then
+ zero_or_more_det(P)
+ else
+ []
+ ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred one_or_more(
+ pred(ps, ps)::in(pred(in, out) is semidet),
+ ps::in, ps::out) is semidet.
+
+one_or_more(P) -->
+ P,
+ zero_or_more_det(P).
+
+%-----------------------------------------------------------------------------%
+
+:- pred brackets(string::in,
+ pred(ps, ps)::in(pred(in, out) is semidet),
+ string::in, ps::in, ps::out) is semidet.
+
+brackets(L, P, R) -->
+ punct(L),
+ P,
+ punct(R).
+
+:- pred brackets_detarg(string::in,
+ pred(ps, ps)::in(pred(in, out) is det),
+ string::in, ps::in, ps::out) is semidet.
+
+brackets_detarg(L, P, R) -->
+ punct(L),
+ P,
+ punct(R).
+
+%-----------------------------------------------------------------------------%
+
+:- pred seq(
+ pred(ps, ps)::in(pred(in, out) is semidet),
+ pred(ps, ps)::in(pred(in, out) is semidet),
+ ps::in, ps::out) is semidet.
+
+:- pragma inline(seq/4).
+
+seq(P, Q) -->
+ P,
+ Q.
+
+%-----------------------------------------------------------------------------%
+
+:- pred comma_separated_list(
+ pred(ps, ps)::in(pred(in, out) is semidet),
+ ps::in, ps::out) is semidet.
+
+comma_separated_list(P) -->
+ P,
+ zero_or_more_det(seq(punct(","), P)).
+
+%-----------------------------------------------------------------------------%
+
+:- pred whitespace(ps::in, ps::out) is semidet.
+
+whitespace -->
+ ( if char(C1), { char.is_whitespace(C1) } then
+ whitespace
+ else if char('/'), char('/') then
+ skip_to_eol,
+ whitespace
+ else if char('/'), char('*') then
+ skip_to_end_of_trad_comment,
+ whitespace
+ else
+ []
+ ).
+
+:- pred skip_to_eol(ps::in, ps::out) is semidet.
+
+skip_to_eol -->
+ char(C),
+ ( if { C = ('\n') } then
+ []
+ else
+ skip_to_eol
+ ).
+
+:- pred skip_to_end_of_trad_comment(ps::in, ps::out) is semidet.
+
+skip_to_end_of_trad_comment -->
+ ( if char('*'), char('/') then
+ []
+ else
+ char(_),
+ skip_to_end_of_trad_comment
+ ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred punct(string::in, ps::in, ps::out) is semidet.
+
+punct(Punct) -->
+ match_string(Punct),
+ whitespace.
+
+%-----------------------------------------------------------------------------%
+
+:- pred keyword(string::in, ps::in, ps::out) is semidet.
+
+keyword(Keyword) -->
+ match_string(Keyword),
+ not(java_identifier_part),
+ whitespace.
+
+%-----------------------------------------------------------------------------%
+
+:- pred keyword(string::in,
+ pred(ps, ps)::in(pred(in, out) is semidet),
+ ps::in, ps::out) is semidet.
+
+keyword(Keyword, P) -->
+ match_string(Keyword),
+ not(java_identifier_part),
+ whitespace,
+ P.
+
+%-----------------------------------------------------------------------------%
+
+:- pred java_identifier( /*string::out,*/ ps::in, ps::out)
+ is semidet.
+
+
+java_identifier/*(Identifier)*/ -->
+% current_offset(Start),
+ java_identifier_start,
+ zero_or_more_det(java_identifier_part),
+% current_offset(End),
+% input_substring(Start, End, Identifier),
+ whitespace.
+
+:- pred java_identifier_start(ps::in, ps::out) is semidet.
+
+java_identifier_start -->
+ char(C),
+ { char.is_alpha_or_underscore(C) ; C = ('$') }.
+
+:- pred java_identifier_part(ps::in, ps::out) is semidet.
+
+java_identifier_part -->
+ char(C),
+ { char.is_alnum_or_underscore(C) ; C = ('$') }.
+
+%-----------------------------------------------------------------------------%
+
+:- pred floating_point_literal(ps::in, ps::out) is semidet.
+
+floating_point_literal -->
+ ( if
+ optional_det(digits(10)),
+ char('.'),
+ digits(10)
+ then
+ optional_det(exponent_part),
+ optional_det(float_type_suffix)
+ else
+ digits(10),
+ ( if exponent_part then
+ optional_det(float_type_suffix)
+ else
+ float_type_suffix
+ )
+ ).
+
+:- pred exponent_part(ps::in, ps::out) is semidet.
+
+exponent_part -->
+ char(C),
+ { C = ('E') ; C = ('e') },
+ optional_det(sign),
+ one_or_more(digit(10)).
+
+:- pred sign(ps::in, ps::out) is semidet.
+
+sign -->
+ char(C),
+ { C = ('+') ; C = ('-') }.
+
+:- pred float_type_suffix(ps::in, ps::out) is semidet.
+
+float_type_suffix -->
+ char(C),
+ { C = ('F') ; C = ('f') ; C = ('D') ; C = ('d') }.
+
+%-----------------------------------------------------------------------------%
+
+:- pred integer_literal(ps::in, ps::out) is semidet.
+
+integer_literal -->
+ ( if
+ hex_literal
+ then
+ []
+ else if
+ oct_literal
+ then
+ []
+ else
+ dec_literal
+ ).
+
+:- pred hex_literal(ps::in, ps::out) is semidet.
+
+hex_literal -->
+ char('0'),
+ char('x'),
+ digits(16),
+ optional_det(integer_type_suffix).
+
+:- pred oct_literal(ps::in, ps::out) is semidet.
+
+oct_literal -->
+ char('0'),
+ digits(8),
+ optional_det(integer_type_suffix).
+
+:- pred dec_literal(ps::in, ps::out) is semidet.
+
+dec_literal -->
+ ( if char('0') then
+ not digit(16)
+ else
+ digits(10)
+ ),
+ optional_det(integer_type_suffix).
+
+:- pred integer_type_suffix(ps::in, ps::out) is semidet.
+
+integer_type_suffix -->
+ char(C),
+ { C = ('L') ; C = ('l') }.
+
+:- pred digits(int::in, ps::in, ps::out) is semidet.
+
+digits(Base) -->
+ one_or_more(digit(Base)).
+
+:- pred digit(int::in, ps::in, ps::out) is semidet.
+
+digit(Base) -->
+ char(C),
+ { char.digit_to_int(C, D), D < Base }.
+
+%-----------------------------------------------------------------------------%
+
+:- pred character_literal(ps::in, ps::out) is semidet.
+
+character_literal -->
+ char('\''),
+ not char('\''),
+ possibly_escaped_char,
+ char('\'').
+
+:- pred possibly_escaped_char(ps::in, ps::out) is semidet.
+
+possibly_escaped_char -->
+ char(C1),
+ ( if
+ { C1 = ('\\') }
+ then
+ ( if
+ digits(8)
+ then
+ []
+ else if
+ char('u'),
+ one_or_more(digits(16)) then
+ []
+ else
+ char(C2),
+ { member(C2,
+ [('b'), ('t'), ('n'), ('f'), ('r'), ('\"'), ('\''), ('\\')]) }
+ )
+ else
+ []
+ ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred string_literal(ps::in, ps::out) is semidet.
+
+string_literal -->
+ char('\"'),
+ zero_or_more_det(string_char),
+ char('\"').
+
+:- pred string_char(ps::in, ps::out) is semidet.
+
+string_char -->
+ not(char('"')),
+ possibly_escaped_char.
+
+%-----------------------------------------------------------------------------%
+
+:- pred boolean_literal(ps::in, ps::out) is semidet.
+
+boolean_literal -->
+ ( if
+ keyword("true")
+ then
+ []
+ else
+ keyword("false")
+ ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred null_literal(ps::in, ps::out) is semidet.
+
+null_literal -->
+ keyword("null").
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+% Taken from
+% http://java.sun.com/docs/books/jls/second_edition/html/syntax.doc.html
+
+% _________________________________________________________________
+%
+% [5]Contents | [6]Prev | [7]Next | [8]Index Java Language Specification
+% Second Edition
+%
+% [9]Copyright 2000 Sun Microsystems, Inc. All rights reserved
+% Please send any comments or corrections to the [10]JLS team
+
+% Syntax
+% _________________________________________________________________
+%
+% This chapter presents a grammar for the Java programming language.
+%
+% The grammar presented piecemeal in the preceding chapters is much
+% better for exposition, but it is not ideally suited as a basis for a
+% parser. The grammar presented in this chapter is the basis for the
+% reference implementation.
+%
+% The grammar below uses the following BNF-style conventions:
+%
+% * [x] denotes zero or one occurrences of x.
+% * {x} denotes zero or more occurrences of x.
+% * x | y means one of either x or y.
+
+% Identifier:
+% IDENTIFIER
+%
+% QualifiedIdentifier:
+% Identifier { . Identifier }
+
+:- pred qualified_identifier(ps::in, ps::out) is semidet.
+
+qualified_identifier -->
+ java_identifier,
+ zero_or_more_det(dot_java_identifier).
+
+:- pred dot_java_identifier(ps::in, ps::out) is semidet.
+
+dot_java_identifier -->
+ punct("."),
+ java_identifier.
+
+% Literal:
+% IntegerLiteral
+% FloatingPointLiteral
+% CharacterLiteral
+% StringLiteral
+% BooleanLiteral
+% NullLiteral
+
+:- pred literal(ps::in, ps::out) is semidet.
+
+literal -->
+ ( if
+ floating_point_literal
+ then
+ []
+ else if
+ integer_literal
+ then
+ []
+ else if
+ character_literal
+ then
+ []
+ else if
+ string_literal
+ then
+ []
+ else if
+ boolean_literal
+ then
+ []
+ else
+ null_literal
+ ),
+ whitespace.
+
+% Expression:
+% Expression1 [AssignmentOperator Expression1]]
+% XXX I think that should be
+% Expression1 {AssignmentOperator Expression1}
+
+:- pred expression(ps::in, ps::out) is semidet.
+
+expression -->
+ expression1,
+ zero_or_more_det(assignment_operator_expression1).
+
+:- pred assignment_operator_expression1(ps::in, ps::out)
+ is semidet.
+
+assignment_operator_expression1 -->
+ assignment_operator,
+ expression1.
+
+% AssignmentOperator:
+% =
+% +=
+% -=
+% *=
+% /=
+% &=
+% |=
+% ^=
+% %=
+% <<=
+% >>=
+% >>>=
+
+:- pred assignment_operator(ps::in, ps::out) is semidet.
+
+assignment_operator -->
+ ( if
+ punct("=")
+ then
+ []
+ else if
+ punct("+=")
+ then
+ []
+ else if
+ punct("-=")
+ then
+ []
+ else if
+ punct("*=")
+ then
+ []
+ else if
+ punct("/=")
+ then
+ []
+ else if
+ punct("&=")
+ then
+ []
+ else if
+ punct("|=")
+ then
+ []
+ else if
+ punct("^=")
+ then
+ []
+ else if
+ punct("%=")
+ then
+ []
+ else if
+ punct("<<=")
+ then
+ []
+ else if
+ punct(">>=")
+ then
+ []
+ else
+ punct(">>>=")
+ ).
+
+% Type:
+% Identifier { . Identifier } BracketsOpt
+% BasicType
+
+:- pred java_type(ps::in, ps::out) is semidet.
+
+java_type -->
+ ( if
+ qualified_identifier,
+ brackets_opt
+ then
+ []
+ else
+ basic_type
+ ).
+
+% StatementExpression:
+% Expression
+
+:- pred statement_expression(ps::in, ps::out) is semidet.
+
+statement_expression -->
+ expression.
+
+% ConstantExpression:
+% Expression
+
+:- pred constant_expression(ps::in, ps::out) is semidet.
+
+constant_expression -->
+ expression.
+
+% Expression1:
+% Expression2 [Expression1Rest]
+
+:- pred expression1(ps::in, ps::out) is semidet.
+
+expression1 -->
+ expression2,
+ optional_det(expression1_rest).
+
+% Expression1Rest:
+% [ ? Expression : Expression1]
+
+:- pred expression1_rest(ps::in, ps::out) is semidet.
+
+expression1_rest -->
+ punct("?"),
+ expression,
+ punct(":"),
+ expression1.
+
+% Expression2 :
+% Expression3 [Expression2Rest]
+
+:- pred expression2(ps::in, ps::out) is semidet.
+
+expression2 -->
+ expression3,
+ optional_det(expression2_rest).
+
+% Expression2Rest:
+% {Infixop Expression3}
+% Expression3 instanceof Type
+% XXX The Expression3 here must be wrong...
+% XXX And {Infixop Expression3} should be allowed after Type.
+
+:- pred expression2_rest(ps::in, ps::out) is semidet.
+
+expression2_rest -->
+ ( if
+ keyword("instanceof"),
+ java_type,
+ optional_det(expression2_rest)
+ then
+ []
+ else
+ zero_or_more_det(infix_op_expression3),
+ { semidet_succeed }
+ ).
+
+:- pred infix_op_expression3(ps::in, ps::out) is semidet.
+
+infix_op_expression3 -->
+ infix_op,
+ expression3.
+
+% Infixop:
+% ||
+% &&
+% |
+% ^
+% &
+% ==
+% !=
+% <
+% >
+% <=
+% >=
+% <<
+% >>
+% >>>
+% +
+% -
+% *
+% /
+% %
+
+:- pred infix_op(ps::in, ps::out) is semidet.
+
+infix_op -->
+ ( if
+ punct("||")
+ then
+ []
+ else if
+ punct("&&")
+ then
+ []
+ else if
+ punct("|")
+ then
+ []
+ else if
+ punct("^")
+ then
+ []
+ else if
+ punct("&")
+ then
+ []
+ else if
+ punct("==")
+ then
+ []
+ else if
+ punct("!=")
+ then
+ []
+ else if
+ punct("<=")
+ then
+ []
+ else if
+ punct(">=")
+ then
+ []
+ else if
+ punct("<<")
+ then
+ []
+ else if
+ punct(">>>")
+ then
+ []
+ else if
+ punct(">>")
+ then
+ []
+ else if
+ punct("<")
+ then
+ []
+ else if
+ punct(">")
+ then
+ []
+ else if
+ punct("+")
+ then
+ []
+ else if
+ punct("-")
+ then
+ []
+ else if
+ punct("*")
+ then
+ []
+ else if
+ punct("/")
+ then
+ []
+ else
+ punct("%")
+ ).
+
+% Expression3:
+% PrefixOp Expression3
+% ( Expr | Type ) Expression3
+% Primary {Selector} {PostfixOp}
+
+:- pred expression3(ps::in, ps::out) is semidet.
+
+expression3 -->
+ ( if
+ prefix_op,
+ expression3
+ then
+ []
+ else if
+ brackets(
+ "(",
+ expression_or_java_type,
+ ")"),
+ expression3
+ then
+ []
+ else
+ primary,
+ zero_or_more_det(selector),
+ zero_or_more_det(postfix_op)
+ ).
+
+:- pred expression_or_java_type(ps::in, ps::out) is semidet.
+
+expression_or_java_type -->
+ ( if
+ java_type
+ then
+ []
+ else
+ expression
+ ).
+
+% Primary:
+% ( Expression )
+% this [Arguments]
+% super SuperSuffix
+% Literal
+% new Creator
+% Identifier { . Identifier }[ IdentifierSuffix]
+% BasicType BracketsOpt .class
+% void.class
+
+:- pred primary(ps::in, ps::out) is semidet.
+
+primary -->
+ ( if
+ brackets(
+ "(",
+ expression,
+ ")")
+ then
+ []
+ else if
+ keyword("this"),
+ optional_det(arguments)
+ then
+ []
+ else if
+ keyword("super"),
+ super_suffix
+ then
+ []
+ else if
+ keyword("new"),
+ creator
+ then
+ []
+ else if
+ keyword("void"),
+ punct("."),
+ keyword("class")
+ then
+ []
+ else if
+ basic_type,
+ brackets_opt,
+ punct("."),
+ keyword("class")
+ then
+ []
+ else if
+ literal
+ then
+ []
+ else
+ qualified_identifier,
+ optional_det(identifier_suffix)
+ ).
+
+% XXX I don't understand how to read this rule:
+%
+% IdentifierSuffix:
+% [ ( ] BracketsOpt . class | Expression ])
+% Arguments
+% . ( class | this | super Arguments | new InnerCreator )
+
+:- pred identifier_suffix(ps::in, ps::out) is semidet.
+
+identifier_suffix -->
+ ( if
+ brackets_opt,
+ punct("."),
+ ( if
+ keyword("class")
+ then
+ []
+ else
+ expression
+ )
+ then
+ []
+ else if
+ arguments
+ then
+ []
+ else
+ punct("."),
+ ( if
+ keyword("class")
+ then
+ []
+ else if
+ keyword("this")
+ then
+ []
+ else if
+ keyword("super"),
+ arguments
+ then
+ []
+ else
+ keyword("new"),
+ inner_creator
+ )
+ ).
+
+% PrefixOp:
+% ,
+% --
+% !
+% ~
+% +
+% -
+
+:- pred prefix_op(ps::in, ps::out) is semidet.
+
+prefix_op -->
+ ( if
+ punct("++")
+ then
+ []
+ else if
+ punct("--")
+ then
+ []
+ else if
+ punct("!")
+ then
+ []
+ else if
+ punct("~")
+ then
+ []
+ else if
+ punct("+")
+ then
+ []
+ else
+ punct("-")
+ ).
+
+% PostfixOp:
+% ,
+% --
+
+:- pred postfix_op(ps::in, ps::out) is semidet.
+
+postfix_op -->
+ ( if
+ punct("++")
+ then
+ []
+ else
+ punct("--")
+ ).
+
+% Selector:
+% . Identifier [Arguments]
+% . this
+% . super SuperSuffix
+% . new InnerCreator
+% [ Expression ]
+
+:- pred selector(ps::in, ps::out) is semidet.
+
+selector -->
+ ( if
+ brackets(
+ "[",
+ expression,
+ "]")
+ then
+ []
+ else
+ punct("."),
+ ( if
+ keyword("this")
+ then
+ []
+ else if
+ keyword("super"),
+ super_suffix
+ then
+ []
+ else if
+ keyword("new"),
+ inner_creator
+ then
+ []
+ else
+ java_identifier,
+ optional_det(arguments)
+ )
+ ).
+
+% SuperSuffix:
+% Arguments
+% . Identifier [Arguments]
+
+:- pred super_suffix(ps::in, ps::out) is semidet.
+
+super_suffix -->
+ ( if
+ arguments
+ then
+ []
+ else
+ punct("."),
+ java_identifier,
+ optional_det(arguments)
+ ).
+
+% BasicType:
+% byte
+% short
+% char
+% int
+% long
+% float
+% double
+% boolean
+
+:- pred basic_type(ps::in, ps::out) is semidet.
+
+basic_type -->
+ ( if
+ punct("byte")
+ then
+ []
+ else if
+ punct("short")
+ then
+ []
+ else if
+ punct("char")
+ then
+ []
+ else if
+ punct("int")
+ then
+ []
+ else if
+ punct("long")
+ then
+ []
+ else if
+ punct("float")
+ then
+ []
+ else if
+ punct("double")
+ then
+ []
+ else
+ punct("boolean")
+ ).
+
+% Arguments:
+% ( [Expression { , Expression }] )
+
+:- pred arguments(ps::in, ps::out) is semidet.
+
+arguments -->
+ brackets_detarg(
+ "(",
+ optional_det(comma_separated_list(expression)),
+ ")").
+
+% BracketsOpt:
+% {[]}
+
+:- pred brackets_opt(ps::in, ps::out) is det.
+
+brackets_opt -->
+ zero_or_more_det(empty_brackets).
+
+:- pred empty_brackets(ps::in, ps::out) is semidet.
+
+empty_brackets -->
+ punct("["),
+ punct("]").
+
+% Creator:
+% QualifiedIdentifier ( ArrayCreatorRest | ClassCreatorRest )
+
+:- pred creator(ps::in, ps::out) is semidet.
+
+creator -->
+ qualified_identifier,
+ creator_rest.
+
+:- pred creator_rest(ps::in, ps::out) is semidet.
+
+creator_rest -->
+ ( if
+ array_creator_rest
+ then
+ []
+ else
+ class_creator_rest
+ ).
+
+% InnerCreator:
+% Identifier ClassCreatorRest
+
+:- pred inner_creator(ps::in, ps::out) is semidet.
+
+inner_creator -->
+ java_identifier,
+ class_creator_rest.
+
+% XXX I don't understand how to read this rule:
+%
+% ArrayCreatorRest:
+% [ ( ] BracketsOpt ArrayInitializer | Expression ] {[ Expression ]} BracketsOpt )
+
+:- pred array_creator_rest(ps::in, ps::out) is semidet.
+
+array_creator_rest -->
+ one_or_more(
+ brackets_detarg(
+ "[",
+ optional_det(expression),
+ "]")),
+ optional_det(array_initializer).
+
+% ClassCreatorRest:
+% Arguments [ClassBody]
+
+:- pred class_creator_rest(ps::in, ps::out) is semidet.
+
+class_creator_rest -->
+ arguments,
+ optional_det(class_body).
+
+% ArrayInitializer:
+% { [VariableInitializer {, VariableInitializer} [,]] }
+
+:- pred array_initializer(ps::in, ps::out) is semidet.
+
+array_initializer -->
+ brackets_detarg(
+ "{",
+ optional_det(array_initializer_body),
+ "}").
+
+:- pred array_initializer_body(ps::in, ps::out) is semidet.
+
+array_initializer_body -->
+ comma_separated_list(variable_initializer),
+ optional_det(punct(",")).
+
+% VariableInitializer:
+% ArrayInitializer
+% Expression
+
+:- pred variable_initializer(ps::in, ps::out) is semidet.
+
+variable_initializer -->
+ ( if
+ array_initializer
+ then
+ []
+ else
+ expression
+ ).
+
+% ParExpression:
+% ( Expression )
+
+:- pred par_expression(ps::in, ps::out) is semidet.
+
+par_expression -->
+ brackets(
+ "(",
+ expression,
+ ")").
+
+% Block:
+% { BlockStatements }
+
+:- pred block(ps::in, ps::out) is semidet.
+
+block -->
+ brackets_detarg(
+ "{",
+ block_statements,
+ "}").
+
+% BlockStatements:
+% { BlockStatement }
+
+:- pred block_statements(ps::in, ps::out) is det.
+
+block_statements -->
+ zero_or_more_det(block_statement).
+
+% BlockStatement :
+% LocalVariableDeclarationStatement
+% ClassOrInterfaceDeclaration
+% [Identifier :] Statement
+
+:- pred block_statement(ps::in, ps::out) is semidet.
+
+block_statement -->
+ ( if
+ local_variable_declaration_statement
+ then
+ []
+ else if
+ class_or_interface_declaration
+ then
+ []
+ else
+ optional_det(label),
+ statement
+ ).
+
+:- pred label(ps::in, ps::out) is semidet.
+
+label -->
+ java_identifier,
+ punct(":").
+
+% LocalVariableDeclarationStatement:
+% [final] Type VariableDeclarators ;
+% XXX I think this is wrong: [final] should be ModifiersOpt, surely?
+
+:- pred local_variable_declaration_statement(ps::in, ps::out)
+ is semidet.
+
+local_variable_declaration_statement -->
+ modifiers_opt,
+ java_type,
+ variable_declarators,
+ punct(";").
+
+% Statement:
+% Block
+% if ParExpression Statement [else if Statement]
+% for ( ForInitOpt ; [Expression] ; ForUpdateOpt ) Statement
+% while ParExpression Statement
+% do Statement while ParExpression ;
+% try Block ( Catches | [Catches] finally Block )
+% switch ParExpression { SwitchBlockStatementGroups }
+% synchronized ParExpression Block
+% return [Expression] ;
+% throw Expression ;
+% break [Identifier]
+% continue [Identifier]
+% ;
+% ExpressionStatement
+% Identifier : Statement
+
+:- pred statement(ps::in, ps::out) is semidet.
+
+statement -->
+ ( if
+ block
+ then
+ []
+ else if
+ keyword("if"),
+ par_expression,
+ statement,
+ optional_det(else_statement)
+ then
+ []
+ else if
+ keyword("for"),
+ punct("("),
+ optional_det(for_init),
+ punct(";"),
+ optional_det(expression),
+ punct(";"),
+ optional_det(for_update),
+ punct(")"),
+ statement
+ then
+ []
+ else if
+ keyword("while"),
+ par_expression,
+ statement
+ then
+ []
+ else if
+ keyword("do"),
+ statement,
+ keyword("while"),
+ par_expression,
+ punct(";")
+ then
+ []
+ else if
+ keyword("try"),
+ block,
+ catches_finally
+ then
+ []
+ else if
+ keyword("switch"),
+ par_expression,
+ brackets_detarg(
+ "{",
+ switch_block_statement_groups,
+ "}")
+ then
+ []
+ else if
+ keyword("synchronized"),
+ par_expression,
+ block
+ then
+ []
+ else if
+ keyword("return"),
+ optional_det(expression),
+ punct(";")
+ then
+ []
+ else if
+ keyword("throw"),
+ expression,
+ punct(";")
+ then
+ []
+ else if
+ keyword("break"),
+ optional_det(java_identifier),
+ punct(";")
+ then
+ []
+ else if
+ keyword("continue"),
+ optional_det(java_identifier),
+ punct(";")
+ then
+ []
+ else if
+ punct(";")
+ then
+ []
+ else if
+ expression,
+ punct(";")
+ then
+ []
+ else
+ java_identifier,
+ punct(":"),
+ statement
+ ).
+
+:- pred else_statement(ps::in, ps::out) is semidet.
+
+else_statement -->
+ keyword("else"),
+ statement.
+
+:- pred catches_finally(ps::in, ps::out) is semidet.
+
+catches_finally -->
+ ( if
+ catches,
+ optional_det(finally_block)
+ then
+ []
+ else
+ finally_block
+ ).
+
+:- pred finally_block(ps::in, ps::out) is semidet.
+
+finally_block -->
+ keyword("finally"),
+ block.
+
+% Catches:
+% CatchClause {CatchClause}
+
+:- pred catches(ps::in, ps::out) is semidet.
+
+catches -->
+ one_or_more(catch_clause).
+
+% CatchClause:
+% catch ( FormalParameter ) Block
+
+:- pred catch_clause(ps::in, ps::out) is semidet.
+
+catch_clause -->
+ keyword("catch"),
+ brackets(
+ "(",
+ formal_parameter,
+ ")"),
+ block.
+
+% SwitchBlockStatementGroups:
+% { SwitchBlockStatementGroup }
+
+:- pred switch_block_statement_groups(ps::in, ps::out) is det.
+
+switch_block_statement_groups -->
+ zero_or_more_det(switch_block_statement_group).
+
+% SwitchBlockStatementGroup:
+% SwitchLabel BlockStatements
+
+:- pred switch_block_statement_group(ps::in, ps::out) is semidet.
+
+switch_block_statement_group -->
+ switch_label,
+ block_statements.
+
+% SwitchLabel:
+% case ConstantExpression :
+% default:
+
+:- pred switch_label(ps::in, ps::out) is semidet.
+
+switch_label -->
+ ( if
+ keyword("case"),
+ constant_expression,
+ punct(":")
+ then
+ []
+ else
+ keyword("default"),
+ punct(":")
+ ).
+
+% MoreStatementExpressions:
+% { , StatementExpression }
+%
+% ForInit:
+% StatementExpression MoreStatementExpressions
+% [final] Type VariableDeclarators
+
+:- pred for_init(ps::in, ps::out) is semidet.
+
+for_init -->
+ ( if
+ comma_separated_list(for_init_statement_expression)
+ then
+ []
+ else
+ optional_det(keyword("final")),
+ java_type,
+ variable_declarators
+ ).
+
+:- pred for_init_statement_expression(ps::in, ps::out) is semidet.
+
+for_init_statement_expression -->
+ ( if
+ java_type,
+ java_identifier,
+ equals_variable_initializer
+ then
+ []
+ else
+ statement_expression
+ ).
+
+% ForUpdate:
+% StatementExpression MoreStatementExpressions
+
+:- pred for_update(ps::in, ps::out) is semidet.
+
+for_update -->
+ comma_separated_list(statement_expression).
+
+% ModifiersOpt:
+% { Modifier }
+
+:- pred modifiers_opt(ps::in, ps::out) is det.
+
+modifiers_opt -->
+ zero_or_more_det(modifier).
+
+% Modifier:
+% public
+% protected
+% private
+% static
+% abstract
+% final
+% native
+% synchronized
+% transient
+% volatile
+% strictfp
+
+:- pred modifier(ps::in, ps::out) is semidet.
+
+modifier -->
+ ( if
+ keyword("public")
+ then
+ []
+ else if
+ keyword("protected")
+ then
+ []
+ else if
+ keyword("private")
+ then
+ []
+ else if
+ keyword("static")
+ then
+ []
+ else if
+ keyword("abstract")
+ then
+ []
+ else if
+ keyword("final")
+ then
+ []
+ else if
+ keyword("native")
+ then
+ []
+ else if
+ keyword("synchronized")
+ then
+ []
+ else if
+ keyword("transient")
+ then
+ []
+ else if
+ keyword("volatile")
+ then
+ []
+ else
+ keyword("strictfp")
+ ).
+
+% VariableDeclarators:
+% VariableDeclarator { , VariableDeclarator }
+
+:- pred variable_declarators(ps::in, ps::out) is semidet.
+
+variable_declarators -->
+ comma_separated_list(variable_declarator).
+
+% ConstantDeclaratorsRest:
+% ConstantDeclaratorRest { , ConstantDeclarator }
+
+:- pred constant_declarators_rest(ps::in, ps::out) is semidet.
+
+constant_declarators_rest -->
+ comma_separated_list(constant_declarator_rest).
+
+% VariableDeclarator:
+% Identifier VariableDeclaratorRest
+
+:- pred variable_declarator(ps::in, ps::out) is semidet.
+
+variable_declarator -->
+ java_identifier,
+ variable_declarator_rest.
+
+% ConstantDeclarator:
+% Identifier ConstantDeclaratorRest
+
+:- pred constant_declarator(ps::in, ps::out) is semidet.
+
+:- pragma memo(constant_declarator/2, [allow_reset,
+ specified([addr, output])]).
+
+constant_declarator -->
+ java_identifier,
+ constant_declarator_rest.
+
+% VariableDeclaratorRest:
+% BracketsOpt [ = VariableInitializer]
+
+:- pred variable_declarator_rest(ps::in, ps::out) is det.
+
+variable_declarator_rest -->
+ brackets_opt,
+ optional_det(equals_variable_initializer).
+
+:- pred equals_variable_initializer(ps::in, ps::out) is semidet.
+
+equals_variable_initializer -->
+ punct("="),
+ variable_initializer.
+
+% ConstantDeclaratorRest:
+% BracketsOpt = VariableInitializer
+
+:- pred constant_declarator_rest(ps::in, ps::out) is semidet.
+
+constant_declarator_rest -->
+ brackets_opt,
+ punct("="),
+ variable_initializer.
+
+% VariableDeclaratorId:
+% Identifier BracketsOpt
+
+:- pred variable_declarator_id(ps::in, ps::out) is semidet.
+
+variable_declarator_id -->
+ java_identifier,
+ brackets_opt.
+
+% CompilationUnit:
+% [package QualifiedIdentifier ; ] {ImportDeclaration} {TypeDeclaration}
+
+:- pred compilation_unit(ps::in, ps::out) is semidet.
+
+compilation_unit -->
+ whitespace,
+ optional_det(package_declaration),
+ zero_or_more_det(import_declaration),
+ zero_or_more_det(type_declaration),
+ eof.
+
+:- pred package_declaration(ps::in, ps::out) is semidet.
+
+package_declaration -->
+ keyword("package"),
+ qualified_identifier,
+ punct(";").
+
+% ImportDeclaration:
+% import Identifier { . Identifier } [ . * ] ;
+
+:- pred import_declaration(ps::in, ps::out) is semidet.
+
+import_declaration -->
+ keyword("import"),
+ qualified_identifier,
+ optional_det(dot_star),
+ punct(";").
+
+:- pred dot_star(ps::in, ps::out) is semidet.
+
+dot_star -->
+ punct("."),
+ punct("*").
+
+% TypeDeclaration:
+% ClassOrInterfaceDeclaration
+
+:- pred type_declaration(ps::in, ps::out) is semidet.
+
+type_declaration -->
+ class_or_interface_declaration.
+
+% ClassOrInterfaceDeclaration:
+% ModifiersOpt (ClassDeclaration | InterfaceDeclaration)
+
+:- pred class_or_interface_declaration(ps::in, ps::out)
+ is semidet.
+
+class_or_interface_declaration -->
+ modifiers_opt,
+ ( if
+ class_declaration
+ then
+ []
+ else
+ interface_declaration
+ ).
+
+% ClassDeclaration:
+% class Identifier [extends Type] [implements TypeList] ClassBody
+
+:- pred class_declaration(ps::in, ps::out) is semidet.
+
+class_declaration -->
+ keyword("class"),
+ java_identifier,
+ optional_det(keyword("extends", java_type)),
+ optional_det(keyword("implements", java_type_list)),
+ class_body.
+
+% InterfaceDeclaration:
+% interface Identifier [extends TypeList] InterfaceBody
+
+:- pred interface_declaration(ps::in, ps::out) is semidet.
+
+interface_declaration -->
+ keyword("interface"),
+ java_identifier,
+ optional_det(keyword("extends", java_type_list)),
+ interface_body.
+
+% TypeList:
+% Type { , Type}
+
+:- pred java_type_list(ps::in, ps::out) is semidet.
+
+java_type_list -->
+ comma_separated_list(java_type).
+
+% ClassBody:
+% { {ClassBodyDeclaration} }
+
+:- pred class_body(ps::in, ps::out) is semidet.
+
+class_body -->
+ brackets_detarg(
+ "{",
+ zero_or_more_det(class_body_declaration),
+ "}").
+
+% InterfaceBody:
+% { {InterfaceBodyDeclaration} }
+
+:- pred interface_body(ps::in, ps::out) is semidet.
+
+interface_body -->
+ brackets_detarg(
+ "{",
+ zero_or_more_det(interface_body_declaration),
+ "}").
+
+% ClassBodyDeclaration:
+% ;
+% [static] Block
+% ModifiersOpt MemberDecl
+
+:- pred class_body_declaration(ps::in, ps::out) is semidet.
+
+class_body_declaration -->
+ ( if
+ punct(";")
+ then
+ []
+ else if
+ optional_det(keyword("static")),
+ block
+ then
+ []
+ else
+ modifiers_opt,
+ member_decl
+ ).
+
+% MemberDecl:
+% MethodOrFieldDecl
+% void Identifier MethodDeclaratorRest
+% Identifier ConstructorDeclaratorRest
+% ClassOrInterfaceDeclaration
+
+:- pred member_decl(ps::in, ps::out) is semidet.
+
+member_decl -->
+ ( if
+ class_or_interface_declaration
+ then
+ []
+ else if
+ method_or_field_decl
+ then
+ []
+ else if
+ keyword("void"),
+ java_identifier,
+ method_declarator_rest
+ then
+ []
+ else
+ java_identifier,
+ constructor_declarator_rest
+ ).
+
+% MethodOrFieldDecl:
+% Type Identifier MethodOrFieldRest
+
+:- pred method_or_field_decl(ps::in, ps::out) is semidet.
+
+method_or_field_decl -->
+ java_type,
+ java_identifier,
+ method_or_field_rest.
+
+% MethodOrFieldRest:
+% VariableDeclaratorRest
+% MethodDeclaratorRest
+% XXX First should be
+% VariableDeclaratorRest [',' VariableDeclarators]
+
+:- pred method_or_field_rest(ps::in, ps::out) is semidet.
+
+method_or_field_rest -->
+ ( if
+ method_declarator_rest
+ then
+ []
+ else
+ variable_declarator_rest,
+ ( if punct(",") then
+ variable_declarators
+ else
+ []
+ )
+ ).
+
+% InterfaceBodyDeclaration:
+% ;
+% ModifiersOpt InterfaceMemberDecl
+
+:- pred interface_body_declaration(ps::in, ps::out) is semidet.
+
+interface_body_declaration -->
+ ( if
+ punct(";")
+ then
+ []
+ else
+ modifiers_opt,
+ interface_member_decl
+ ).
+
+% InterfaceMemberDecl:
+% InterfaceMethodOrFieldDecl
+% void Identifier VoidInterfaceMethodDeclaratorRest
+% ClassOrInterfaceDeclaration
+
+:- pred interface_member_decl(ps::in, ps::out) is semidet.
+
+interface_member_decl -->
+ ( if
+ interface_method_or_field_decl
+ then
+ []
+ else if
+ keyword("void"),
+ java_identifier,
+ void_interface_method_declarator_rest
+ then
+ []
+ else
+ class_or_interface_declaration
+ ).
+
+% InterfaceMethodOrFieldDecl:
+% Type Identifier InterfaceMethodOrFieldRest
+
+:- pred interface_method_or_field_decl(ps::in, ps::out)
+ is semidet.
+
+interface_method_or_field_decl -->
+ java_type,
+ java_identifier,
+ interface_method_or_field_rest.
+
+% InterfaceMethodOrFieldRest:
+% ConstantDeclaratorsRest ;
+% InterfaceMethodDeclaratorRest
+
+:- pred interface_method_or_field_rest(ps::in, ps::out)
+ is semidet.
+
+interface_method_or_field_rest -->
+ ( if
+ constant_declarator_rest
+ then
+ []
+ else
+ interface_method_declarator_rest
+ ).
+
+% MethodDeclaratorRest:
+% FormalParameters BracketsOpt [throws QualifiedIdentifierList] ( MethodBody | ; )
+
+:- pred method_declarator_rest(ps::in, ps::out) is semidet.
+
+method_declarator_rest -->
+ formal_parameters,
+ brackets_opt,
+ optional_det(throws_qualified_identifier_list),
+ method_body_or_semicolon.
+
+:- pred method_body_or_semicolon(ps::in, ps::out) is semidet.
+
+method_body_or_semicolon -->
+ ( if
+ method_body
+ then
+ []
+ else
+ punct(";")
+ ).
+
+% VoidMethodDeclaratorRest:
+% FormalParameters [throws QualifiedIdentifierList] ( MethodBody | ; )
+
+:- pred void_method_declarator_rest(ps::in, ps::out) is semidet.
+
+void_method_declarator_rest -->
+ formal_parameters,
+ optional_det(throws_qualified_identifier_list),
+ method_body_or_semicolon.
+
+% InterfaceMethodDeclaratorRest:
+% FormalParameters BracketsOpt [throws QualifiedIdentifierList] ;
+
+:- pred interface_method_declarator_rest(ps::in, ps::out)
+ is semidet.
+
+interface_method_declarator_rest -->
+ formal_parameters,
+ brackets_opt,
+ optional_det(throws_qualified_identifier_list),
+ punct(";").
+
+% VoidInterfaceMethodDeclaratorRest:
+% FormalParameters [throws QualifiedIdentifierList] ;
+
+:- pred void_interface_method_declarator_rest(ps::in, ps::out)
+ is semidet.
+
+void_interface_method_declarator_rest -->
+ formal_parameters,
+ optional_det(throws_qualified_identifier_list),
+ punct(";").
+
+% ConstructorDeclaratorRest:
+% FormalParameters [throws QualifiedIdentifierList] MethodBody
+
+:- pred constructor_declarator_rest(ps::in, ps::out) is semidet.
+
+constructor_declarator_rest -->
+ formal_parameters,
+ optional_det(throws_qualified_identifier_list),
+ method_body.
+
+:- pred throws_qualified_identifier_list(ps::in, ps::out)
+ is semidet.
+
+throws_qualified_identifier_list -->
+ keyword("throws"),
+ qualified_identifier_list.
+
+% QualifiedIdentifierList:
+% QualifiedIdentifier { , QualifiedIdentifier}
+
+:- pred qualified_identifier_list(ps::in, ps::out) is semidet.
+
+qualified_identifier_list -->
+ comma_separated_list(qualified_identifier).
+
+% FormalParameters:
+% ( [FormalParameter { , FormalParameter}] )
+
+:- pred formal_parameters(ps::in, ps::out) is semidet.
+
+formal_parameters -->
+ brackets_detarg(
+ "(",
+ optional_det(comma_separated_list(formal_parameter)),
+ ")").
+
+% FormalParameter:
+% [final] Type VariableDeclaratorId
+
+:- pred formal_parameter(ps::in, ps::out) is semidet.
+
+formal_parameter -->
+ optional_det(keyword("final")),
+ java_type,
+ variable_declarator_id.
+
+% MethodBody:
+% Block
+
+:- pred method_body(ps::in, ps::out) is semidet.
+
+method_body -->
+ block.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- pred global_table_reset(io::di, io::uo) is det.
+
+global_table_reset(!IO) :-
+ table_reset_for_constant_declarator_2(!IO),
+ true.
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list