Files
mercury/compiler/parse_error.m
Zoltan Somogyi f1df5d2dd1 Give parsing-related modules more meaningful names.
The mapping from the old to the new module names is:

    prog_io ->                  parse_module
    prog_io_dcg ->              parse_dcg_goal
    prog_io_error ->            parse_error
    prog_io_find ->             find_module
    prog_io_goal ->             parse_goal
    prog_io_inst_mode_defn ->   parse_inst_mode_defn
    prog_io_inst_mode_name ->   parse_inst_mode_name
    prog_io_iom ->              parse_types
    prog_io_item ->             parse_item
    prog_io_mutable ->          parse_mutable
    prog_io_pragma ->           parse_pragma
    prog_io_sym_name ->         parse_sym_name
    prog_io_type_defn ->        parse_type_defn
    prog_io_type_name ->        parse_type_name
    prog_io_typeclass ->        parse_class
    prog_io_util ->             parse_util
    prog_io_vars ->             parse_vars
    unparse ->                  parse_tree_to_term
2016-02-09 13:50:37 +11:00

125 lines
5.5 KiB
Mathematica

%-----------------------------------------------------------------------------e
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------e
% Copyright (C) 2014 The Mercury team.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%---------------------------------------------------------------------------%
:- module parse_tree.parse_error.
:- interface.
:- import_module set.
% This type represents the kinds of errors that can happen
% when we (attempt to) read in a Mercury module (which will be
% either a source file, or an interface file).
%
:- type read_module_error
---> rme_could_not_open_file
% We could not open the specified file.
; rme_unexpected_module_name
% The file starts with a module declaration for a module
% other than the one we expected.
; rme_no_module_decl_at_start
% The file does not start with a module declaration at all.
; rme_no_section_decl_at_start
% The module does not start with either an interface or an
% implementation section marker.
; rme_end_module_not_at_end_of_src
% The source code of a module has at least one term
% after the end_module marker for the main module.
; rme_unexpected_term_in_int_or_opt
% The interface or optimization file of a module has at least one
% term that is not expected in such a file.
; rme_could_not_read_term
; rme_could_not_parse_item
% When we attempted to read an item from the file, we got a failure
% either in the first stage of parsing (reading in a term), or
% the second stage of parsing (converting that term to an item).
% Since the rest of the compiler should not care whether parsing
% is done in one or two stages, it should treat both these errors
% the same. We distinguish them only for completeness.
; rme_bad_submodule_start
% We encountered a declaration for the starting of a submodule,
% but the name of the new submodule is not that can be immediately
% nested inside the current module.
% NOTE: This error can happen only for SUBmodules of the main
% module in the file. For the main module itself, we would generate
% the rme_unexpected_module_name error.
; rme_bad_module_end
% We encountered a declaration for the ending of a module,
% but the name of the ended module is not the name of the
% until-then-current module.
% NOTE: This error can happen both for the main module of the
% file and for its submodules.
; rme_warn_item_nothing.
% We encountered an item (such as a version number record for
% smart recompilation) that the parser turned into an item_nothing
% with a warning, and we have to turn that warning into an error
% because the option halt_at_warn is set.
% This type represents the set of errors that were encountered
% during an attempt to read in a Mercury module (source file or
% interface file).
%
% There are two kinds of tests that code will typically perform
% on values of this type.
%
% 1. Test whether the set is nonempty. (Are there any errors?)
% 2. Intersect the set with fatal_read_module_errors, and test whether
% the resulting set is nonempty. (Are there any FATAL errors?)
%
% In some places, we want just the first test, in some other places,
% we want just the second, and in yet a third set of places, we want both.
%
:- type read_module_errors == set(read_module_error).
% The set of errors that should stop the compiler from further processing
% of the read-in module.
%
:- func fatal_read_module_errors = set(read_module_error).
%---------------------------------------------------------------------------%
:- implementation.
:- import_module list.
fatal_read_module_errors = FatalErrors :-
% 1. We obviously cannot process the module if we could not read it.
%
% 2. If the module contains some bad ":- module" declarations, then
% the identity of the module that contains any items following
% such declarations will be in doubt. The compiler can guess the
% identity of the module intended by the programmer only by chance,
% and any mistake will typically lead to an avalanche of misleading
% errors.
%
% 3. If the module contains some bad ":- end_module" declarations,
% then the same is true for any items following those declarations.
%
% Items follow most ":- module" declarations, but not most ":- end_module"
% declarations, and if no items follow a bad ":- end_module" declaration,
% then the badness of the declaration has no further consequences.
% It would therefore be worthwhile making a distinction between bad
% ":- end_module" declarations that have items following them, and those
% that don't. Unfortunately, since each item is processed independently,
% that is not trivial to do.
FatalErrors = set.list_to_set([rme_could_not_open_file,
rme_bad_submodule_start, rme_bad_module_end]).
%---------------------------------------------------------------------------%
:- end_module parse_tree.parse_error.
%---------------------------------------------------------------------------%