Sather Home Page

Section 8.16.1.8:
$CURSOR

abstract class $CURSOR{ELT < $IS_EQ, STP < $STRING{ELT}}
Inheritance map
$IS_EQ $ELT $HASH $STRINGS $STRING{ELT}

Formal Definitions

This abstract class defines a state component which is a set of all instantiations of objects of any class sub-typing from this class in addition to the vdm model types used wherever this class name is used. Note that SAME has to be an instantiated class, not an abstract one.

types

SAME = object_type ;

$CURSOR_ELT_STP = set of object_type

STP = seq of ELT
state

multi : $CURSOR_ELT_STP
inv multi_types ==
forall obj in set multi_types & sub_type($CURSOR_ELT_STP,obj)
NOTE See the important note about vdm state in the notes on vdm-sl usage in this specification.

This abstract class defines the features of generic cursor scanning objects of all string/stream kinds.

The purpose of the cursor abstraction is to provide facilities to extract or pass over subsequences of a string (which are also called sequences or streams). This permits perfectly general scanning which depends only on the structure and content of the string, not its meaning. Since the associated string is not consumed by scanning, it is possible to perform test on contents/structure in order to 'synchronise' the program with the data content.

Reader Routines

Four reader routines are provided to permit access to some of the state of a cursor object. They do not, however, necessarily have to be implemented in that way.


advance

This feature is provided so that any single string element may be passed over during scanning - for example after testing for validity/presence.

advance
Formal Signature
advance(self : SAME)
Pre-condition
pre not has_error(self)
Post-condition
post has_error(self)
or index = index~ + 1

This feature advances the cursor to the next string element. If the cursor had already reached the end then has_error will return true.


advance

This feature is provided so that any single string element may be passed over during scanning - for example after testing for validity/presence. This differs from the above feature in that it also returns the cursor object itself.

advance : SAME
Formal Signature
advance2(self : SAME) res : SAME
Pre-condition
pre not has_error(self)
Post-condition
post res = self
and (has_error(self)
or index = index~ + 1)

This feature advances the cursor to the next string element. If the cursor had already reached the end then has_error will return true. The updated version of self is returned.


retract

This feature is provided to permit more than one look-ahead when scanning the buffer. it cannot be called when the cursor is at the beginning of the string or if a previous error has been detected.

retract
Formal Signature
retract(self : SAME)
Pre-condition
pre not has_error(self)
and index > 0
Post-condition
post index = index~ - 1

This feature retracts the cursor to point to the previous string element.


retract

This feature is provided in order to permit look ahead of more than one element when 'scanning'. In doing so it returns self.

retract : SAME
Formal Signature
retract2(self : SAME) res : SAME
Pre-condition
pre index > 0
Post-condition
post res = self
and index = index~ - 1

This feature retracts the cursor to point to the previous string element. It is an error if the current value of the cursor indicated the beginning of the string before this routine was called. The updated cursor is returned.


item

This feature is provided in order to permit the next item in the buffer to be inspected without being passed over. This is a look-ahead feature.

item : ELT
Formal Signature
item(self : SAME) res : ELT
Pre-condition
pre not is_done(self)
Post-condition
post res = self(index)

This routine returns the string element indicated by the current position of the cursor - or void if an error condition exists. The cursor is not advanced.


reassign

This routine is provided to enable the same cursor object to be used for another string buffer, starting at the beginning again.

reassign (
str : STP
)
Formal Signature
reassign(self : SAME, str : STP)
Pre-condition
pre len str > 0
Post-condition
post buffer = str
and index = 0
and not has_error(self)

This routine changes the contents of the buffer to which this cursor is pointing, so that the current element is the first. Any error condition is cleared.


clear

This feature clears the buffer, resets the index and clears any error condition.

clear
Formal Signature
clear(self : SAME)
Pre-condition
pre true
Post-condition
post buffer = []
and index = 0
and not has_error(self)

This feature resets the cursor to have an empty buffer with index reset and error condition cleared.


set_index

This feature is required to set the index of the cursor to the given value (provided, of course, that it is valid for the buffer size), clearing any error condition.

set_index (
new_posn : CARD
)
Formal Signature
set_index(self : SAME, new_posn : CARD)
Pre-condition
pre new_posn < STP.size(buffer)
Post-condition
post index = new_posn
and not has_error(self)

This routine resets the index position to new_posn, provided that that is a valid index for the buffer, then clears any end of buffer condition.


set_skip

This feature sets the element value which is to be associated with the skip routines until a subsequent use of this feature.

set_skip (
val : ELT
)
Formal Signature
set_skip(self : SAME, val : ELT)
Pre-condition
pre true
Post-condition
post skip_val = val

This routine sets the value of the element used in all skipping operations - until this is next set. The initial default value depends on the element class.


set_skip

This feature sets the element value which is to be associated with the skip routines until a subsequent use of this feature.The cursor is then returned.

set_skip (
val : ELT
)
Formal Signature
set_skip2(self : SAME, val : ELT) res : SAME
Pre-condition
pre true
Post-condition
post res = self
and skip_val = val

This routine sets the value of the element used in all skipping operations - until this is next set. Self is then returned.


skip_over

This feature moves the cursor past all elements which are the same as skip_val, leaving the cursor pointing to the first one which is not that value.

skip_over
Formal Signature
skip_over(self : SAME)
Pre-condition
pre true
Post-condition
post let head = buffer(1, ..., index~) in
let head ^ skipped = buffer(1, ..., index) in
(forall elem in set elems skipped &
elem = skip_val
and buffer(index + 1) <> skip_val)

This routine skips over all elements equal to skip_val, leaving the cursor indicating the first element which does not have that value after the starting index.


skip_over

This feature advances the cursor until the next element in the string is not equal to skip_val, returning self.

skip_over : SAME
Formal Signature
skip_over2(self : SAME) res : SAME
Pre-condition
pre true
Post-condition
post let head = buffer(1, ..., index~) in
let head ^ skipped = buffer(1, ..., index) in
(forall elem in set elems skipped &
elem = skip_val
and buffer(index + 1) <> skip_val)

and res = self

This routine advances the cursor until an element is found which differs from the skip value, Self is then returned.


skip_to

This feature moves the cursor past all elements which are different from skip_val, leaving the cursor pointing to the next occurrence of skip_val

skip_to
Formal Signature
skip_to(self : SAME)
Pre-condition
pre true
Post-condition
post let head = buffer(1, ..., index~) in
let head ^ skipped = buffer(1, ..., index) in
(forall elem in set elems skipped &
elem <> skip_val
and buffer(index + 1) = skip_val)

This routine skips up to the next occurrence of skip_val in the string leaving the cursor indicating that element.


skip_to

This feature moves the cursor up to the next occurrence of skip_val in the string, returning self.

skip_to : SAME
Formal Signature
skip_to2(self : SAME) res : SAME
Pre-condition
pre true
Post-condition
post let head = buffer(1, ..., index~) in
let head ^ skipped = buffer(1, ..., index) in
(forall elem in set elems skipped &
elem <> skip_val
and buffer(index + 1) = skip_val)

and res = self

This routine advances the cursor until the next occurrence of skip_val, returning self.


skip_to

This feature moves the cursor past all elements which are different from the argument, leaving the cursor pointing to the next occurrence of that value.

skip_to (
val : ELT
)
Formal Signature
skip_to3(self : SAME, val : ELT)
Pre-condition
pre true
Post-condition
post let head = buffer(1, ..., index~) in
let head ^ skipped = buffer(1, ..., index) in
(forall elem in set elems skipped &
elem <> val
and buffer(index + 1) = val)

This routine skips up to the next occurrence of val in the string, leaving the cursor indicating that element.


skip_to

This feature moves the cursor up to the next occurrence of the argument in the string, returning self.

skip_to (
val : ELT
) : SAME
Formal Signature
skip_to4(self : SAME, val : ELT) res : SAME
Pre-condition
pre true
Post-condition
post let head = buffer(1, ..., index~) in
let head ^ skipped = buffer(1, ..., index) in
(forall elem in set elems skipped &
elem <> val
and buffer(index + 1) = val)

and res = self

This routine advances the cursor until the next occurrence of of the argument value, returning self.


skip_block

This feature is provided to enable the skipping of any properly nested sub-string with the given start and finish delimiters. The cursor is positioned at the string element after the final finish-delimiter.

skip_block (
start_delimiter : ELT,
finish_delimiter : ELT
)
Formal Signature
skip_block(self : SAME, start, finish : ELT)
Pre-condition
pre true
Post-condition
post ((self(index~ + 1) = start)
and ((is_done
and has_error(self))
or (self(index) = finish)))
or has_error(self)

Providing that the next element in the string is equal to start_delimiter then this routine skips up to and over the next occurrence of finish_delimiter in the string. Should an occurrence of start_delimiter (not being equal to finish_delimiter) occur then this shall be called recursively. If the string is not properly nested or the finish delimiter is not found then an error has occurred.


is_value

This predicate is an alternative to testing an element directly and is of particular use when using scanning with a predicate argument.

is_value (
val : ELT
) : BOOL
Formal Signature
is_value(self : SAME, val : ELT) res : BOOL
Pre-condition
pre not has_error(self)
Post-condition
post res = (self(index + 1) = val)

This routine returns true if and only if the current string element has the value given as argument.


remaining

This feature returns the count of elements in the buffer which have not yet been scanned.

remaining : CARD
Formal Signature
remaining(self : SAME) : res : CARD
Pre-condition

Given that the string is finite and cannot be larger than the maximum number which can be represented in a program then the result is less than or equal to that value and the pre-condition must be true.

pre true
Post-condition
post res = STP.size(buffer) - index

This routine returns the count of elements in the string not yet scanned.


get_item

This feature is the scanning primitive for a cursor item. Successive calls scan the string item by item advancing the cursor one element for each call.

get_item : ELT
Formal Signature
get_item(self : SAME) res : ELT
Pre-condition
pre true
Post-condition
post res = self(index)

This routine returns the item currently indicated by the cursor (or void if the complete string has been scanned) and then advances the cursor. It is an error if the cursor cannot be advanced.


get_upto

This feature scans the string, passing over elements with the value skip_val until one is found which is not that value. The value returned is formed from the remainder of the string up to but not including the next occurrence of skip_val.

get_upto : STP
Formal Signature
get_upto(self : SAME) res : STP
Pre-condition
pre true
Post-condition
post let skipped : seq of ELT,
wanted : seq of ELT be st
skipped ^ wanted = self(index~, ..., index~) in
(forall elem in set elems skipped &
elem = skip_val)
and (forall elem in set elems wanted &
elem <> skip_val)
and (is_done
or (self(index + 1) = skip_val))

This routine scans the string from the current element, skipping until a value which is not the current value of skip_val is found, then up to the next occurrence of the current value of the skip_val, returning the string scanned not including the skip element found. It is not an error if the skip element is not detected before the end of the string.


get_upto

This feature scans the string, retrieving either count elements or until the remainder of the string is finished whichever occurs first.

get_upto (
count : CARD
) : STP
Formal Signature
get_upto2(self : SAME, count : CARD) res : STP
Pre-condition
pre true
Post-condition
post (count < remaining
and (index = index~ + count)
or (index = STP.size(buffer)))
and res = self(index~, ..., index)

This routine returns the string starting at the current element until either the given count is reached or the end of the string, whichever occurs first.


get_upto

This feature scans the string seeking for the given element value. If found then the string between the start index and the position reached is returned, otherwise an error condition is set.

get_upto (
elem : ELT
) : STP
Formal Signature
get_upto3(self : SAME, elem : ELT) res : STP
Pre-condition
pre true
Post-condition
post (self(index) = elem
and (res = self(index~, ..., index))
and forall elt in set elems res &

elt <> elem)
or has_error(self)

This routine returns the string starting at the current element until either the element with the value elem is reached or the end of the string, whichever occurs first. It is an error if elem is not detected before the end of the string. The contents of the value returned is not specified if an error has occurred.


get_remainder

This feature returns the unscanned portion of the buffer - which may be empty!

get_remainder : STP
Formal Signature
get_remainder(self : SAME) res : STP
Pre-condition
pre true
Post-condition
post index = STP.size(buffer)
and res = self(index~ + 1, ..., index)

This routine returns the remainder of the string starting at the current element. The empty sequence may be returned if all of the string has been scanned.


get_rest_upto

This feature returns the string sequence from the current position up to (but not including) the next occurrence of the given element or to the end of the buffer, whichever occurs first. Note that it is not an error if the given element is not found.

get_rest_upto (
val : ELT
) : STP
Formal Signature
get_rest_upto(self : SAME, elem : ELT) res : STP
Pre-condition
pre true
Post-condition
post res = self(index~, ..., index))
and forall elt in set elems res &
elt <> elem)
and (self(index) = elem
or is_done)

This routine returns the string starting at the current element until either the element with the value elem is reached or the end of the string, whichever occurs first. It is an error if elem is not detected before the end of the string. The contents of the value returned is not specified if an error has occurred.


get_block

This feature is provided to enable the user to retrieve any properly nested sub-string with the given start and finish delimiters. The cursor is positioned at the string element after the final finish-delimiter.

get_block (
start_delimiter : ELT,
finish_delimiter : ELT
) : STP
Formal Signature
get_block(self : SAME, start, finish : ELT) res : STP
Pre-condition
pre true
Post-condition
post (self(index) = start
and ((is_done
and has_error(self))
or (let startidx = index~ + 2,
endidx = index - 1 in
res = self(startidx, ..., endidx)
and self(index) = finish))
or has_error(self)

Providing that the next element in the string is equal to start_delimiter then this routine returns the sequence of elements after that element and up to the next occurrence of finish_delimiter in the string, the finish delimiter isadvanced over. Should an occurrence of start_delimiter (not being equal to finish_delimiter) occur then this shall be called recursively. If the string is not properly nested or the finish delimiter is not found then an error has occurred.


error

This feature is provided to give information on the kind of problem most recently detected while scanning. See the class definition for CURSOR_ERRORS to find the relevant semantic description.

error : CURSOR_ERRORS
Formal Signature
error(self : SAME) res : [CURSOR_ERRORS]
Pre-condition
pre true
Post-condition
post has_error(self)
or res = nil

This routine returns the error code associated with the most recent scanning error.


clear_error

This routine is provided to explicitly clear an error-condition in the cursor itself.

clear_error
Formal Signature
clear_error(self : SAME)
Pre-condition
pre true
Post-condition
post not has_error(self)

This routine resets the error status of the cursor.

has_error

This feature is a predicate which returns true only if an uncleared error has been detected while scannibg.

has_error : BOOL
Formal Signature
has_error(self : SAME) res : BOOL
Pre-condition
pre true
Post-condition
post res = (error(self) = nil)

This routine returns true if and only if an uncleared error has occurred during scanning.


Language Index Library Index String Index
Comments or enquiries should be made to Keith Hopper.
Page last modified: Friday, 24 November 2000.
Produced with Amaya