[ Term I/O | The ECLiPSe Built-In Predicates | Reference Manual | Alphabetic Index ]

# read_annotated(+Stream, -Term)

Read a whole term in ECLiPSe syntax from the input stream Stream, and return a descriptive terms with type and source annotations

Stream
  Integer (stream number) or Atom (reserved or user-defined symbolic stream name).
Term
  Prolog term or variable.

## 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 a descriptor containing all information about the term, plus additional type and source annotations.

The structure of the descriptive terms is as follows:

    	:- export struct(annotated_term(
    		term,			% var, atomic or compound
    		type,			% term type (see below)
    		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		term is a string or a char_code list
        anonymous		term is an anonymous variable
        var(NameAtom)	term is a variable with the given name
        compound		term is compound (with annotated subterms)

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 from/to fields of an annotated term describe a "source position" of the term. Every term/subterm is represented by one (sometimes two consecutive) tokens in the source, defined as follows:

- atoms, strings and unsigned numbers are represented by their corresponding IDENTIFIER, NUMBER or STRING token.
- signed numbers are represented by two consecutive tokens (sign+number)
- compound terms in canonical notation are represented by two consecutive tokens (functor and opening parenthesis)
- compound terms in operator syntax are represented by the operator's IDENTIFIER token
- lists:

  a proper list [a,b] has subterms

      	[a,b]	represented by the [ token,
      	[b]	represented by the , token,
      	[]	represented by the ] token,
      	a	represented by itself,
      	b	represented by itself.

  a general list [a,b|T] has subterms

        	[a,b|T]	represented by the [ token,
        	[b|T]	represented by the , token,
        	T	represented by itself,
        	a	represented by itself,
        	b	represented by itself.

  Note that the | and ] tokens do not represent any term.
- special notations:

  X[Args]

      	subscript(X, [...]) represented by the [ token,
      	X,Args	represented by itself,

  X{Args}

        	'with attributes'(X,[Args]) represented by { token,
        	X,Args	represented by themselves

  a{Args}

      	with(a,[Args])	represented by the { token
        	a,Args	represented by themselves

  X(Args)

        	apply(X,[Args])	represented by the ( token
        	X,Args	represented by themselves

  In all these cases, the commas represent nothing.

The source position of a term is the union of the source positions of the representing tokens.

No macro expansions are performed by this primitive.

If only end of file is read, the event 190 is raised and the default handler unifies Term with the atom end_of_file.

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

### Modes and Determinism

- read_annotated(+, -) is semidet

### 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 an integer.
(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,X).
     33.

    X = annotated_term(33, integer, 0, 2)
    Yes (0.00s cpu)

    ?- read_annotated(input,X).
     foo(bar).

    X = annotated_term(foo(annotated_term(bar, atom, 8, 11)), compound, 4, 8)
    Yes (0.00s cpu)

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

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

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

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

## See Also

read / 1, readvar / 3, read_token / 2, read_token / 3, expand_macros / 2