[ Term I/O | Reference Manual | Alphabetic Index ]

read_annotated(+Stream, -Term, -AnnTerm)

Read term with type and source position information
Stream
Stream handle or alias (atom)
Term
Variable or term
AnnTerm
Variable or term

Description

Reads the next input term (up to the end of file, or up to a fullstop) from from the input stream Stream, and returns this term as Term, and a descriptor AnnTerm. AnnTerm is structurally similar to Term and contains all information about the term, plus additional type information, variable names, and source position annotations for all subterms.

The structure of the descriptive terms is as follows:

        :- export struct(annotated_term(
                term,                   % var, atomic or compound
                type,                   % term type (see below)
                file,                   % source file name (atom)
                line,                   % source line (integer)
                from, to                % source position (integers)
                ...
        )).
    

The type-field describes the type of the parsed term and is one of the following:

    integer
    float
    rational
    breal
    atom
    string
    compound            term is compound (with annotated subterms)
    anonymous           term is a variable (was anonymous (_) in source)
    var(NameAtom)       term is a variable (with the given source name)
    var                 term is a variable (introduced by macro expansion)
    end_of_file         end of file was read (term is end_of_file)
These type names correspond to the ones used in type_of/2, except that they convey additional information about variables and end_of_file..

In the case of atomic terms and variables, the term-field simply contains the plain parsed term. For compound terms, the term-field contains a structure whose functor is the functor of the plain term, but whose arguments are annotated versions of the plain term arguments.

E.g. the source term

        3
is parsed as
        annotated_term(3, integer, ...)

The source term

        foo(bar, X, _, 3)
is parsed as
        annotated_term(foo(
            annotated_term(bar, atom, ...),
            annotated_term(X, var('X'), ...),
            annotated_term(_, anonymous, ...),
            annotated_term(3, integer, ...)),
        compound, ...)

The source term

        [1,2]
is parsed as
        annotated_term(.(
            annotated_term(1, integer, ...),
                annotated_term(.(
                        annotated_term(2, integer, ...),
                        annotated_term([], atom, ...)),
                    compound, ...)),
            compound, ...)

The file/line/from/to-fields of an annotated term describe the "source position" of the term. The fields contain:

file
The canonical file name of the source file (an atom), or the empty atom '' if the source is not a file or not known.
line
The line number in the source stream (positive integer).
from, to
The exact term position as integer offsets in the source stream, starting at from and ending at to-1.
The source position of a whole (sub)term is defined as the source position of the unique token (sometimes token pair) which represents that (sub)term. The representing token (pair) is defined as follows:

Terms that were read from source may be subject to macro expansion (see macro/3, expand_macros/2). In that case, term components that were introduced by the expansion may not have an exactly corresponding item in the source (but will usually inherit a meaningful, though not necessarily unique, source position). Moreover, variables that were newly introduced by the expansion have a type-field of 'var' without name information. Also, 'anonymous' variables may have more than one occurrence after expansion.

If only end of file is read, the event 190 is raised. The default handler unifies Term with an annotated term of the form annotated_term{term:end_of_file,type:end_of_file}, and the source location is the last position in the file.

The default action for syntax errors is to print a warning and fail.

Modes and Determinism

Modules

This predicate is sensitive to its module context (tool predicate, see @/2).

Fail Conditions

Fails if a syntax error was detected and no term could be read

Exceptions

(4) instantiation fault
Stream is not instantiated.
(5) type error
Stream is not an atom or a stream handle.
(190) end of file reached
End of file was encountered before reading any character.
(192) illegal stream mode
Stream is not an input stream.
(193) illegal stream specification
Stream is an illegal stream specification.
(198) reading past the file end
Trying to read even after the error 190 was raised.

Examples

?- read_annotated(input,T,AT).
 33.

T = 33
AT = annotated_term(33, integer, user, 1, 0, 2)
Yes (0.00s cpu)


?- read_annotated(input,T,AT).
 foo(bar).

T = foo(bar)
AT = annotated_term(foo(
            annotated_term(bar, atom, user, 2, 8, 11)
        ), compound, user, 2, 4, 8)
Yes (0.00s cpu)


?- read_annotated(input,X).
 a + 3.

T = a + 3
AT = annotated_term(
            annotated_term(a, atom, user, 3, 14, 15)
        +   annotated_term(3, integer, user, 3, 18, 19),
        compound, user, 3, 16, 17)
Yes (0.00s cpu)


?- read_annotated(input,X).
 [a,b].

T = [a, b]
AT = annotated_term([
            annotated_term(a, atom, user, 4, 22, 23)|
            annotated_term([
                    annotated_term(b, atom, user, 4, 24, 25)|
                    annotated_term([], atom, user, 4, 25, 26)
                ], compound, user, 4, 23, 24)
        ], compound, user, 4, 21, 22)
Yes (0.00s cpu)

See Also

read_annotated / 2, read / 1, read_term / 2, read_token / 2, read_token / 3, expand_macros / 2, macro / 3, type_of / 2