The Lex
interface provides procedures for reading strings,
booleans, integers, and floating-point numbers from an input
stream. Similar functionality on text strings is available
from the Scan
interface.
INTERFACEEach of the procedures in this interface reads a specified prefix of the characters in the reader passed to the procedure, and leaves the reader positioned immediately after that prefix, perhaps at end-of-file. Each procedure may callLex ; IMPORT FloatMode, Rd, Word, Long; FROM Thread IMPORT Alerted; EXCEPTION Error; CONST Blanks = SET OF CHAR{ ' ', '\t', '\n', '\r', '\013' (* vertical tab *), '\f'}; NonBlanks = SET OF CHAR{'!' .. '~'};
Rd.UngetChar
after its
final call on Rd.GetChar
.
PROCEDURE Scan( rd: Rd.T; READONLY cs: SET OF CHAR := NonBlanks): TEXT RAISES {Rd.Failure, Alerted};
Read the longest prefix ofrd
composed of characters incs
and return that prefix as aTEXT
.
PROCEDURE Skip( rd: Rd.T; READONLY cs: SET OF CHAR := Blanks) RAISES {Rd.Failure, Alerted};
Read the longest prefix ofrd
composed of characters incs
and discard it.
Whenever a specification of one of the procedures mentions skipping blanks, this is equivalent to performing the call
Skip(rd, Blanks)
.
PROCEDURE Match(rd: Rd.T; t: TEXT) RAISES {Error, Rd.Failure, Alerted};
Read the longest prefix ofrd
that is also a prefix oft
. RaiseError
if that prefix is not, in fact, equal to all oft
.
PROCEDURE Bool(rd: Rd.T): BOOLEAN RAISES {Error, Rd.Failure, Alerted};
Read a boolean from rd
and return its value.
Bool
skips blanks, then reads the longest prefix of rd
that is
a prefix of a Boolean
in the following grammar:
Boolean = "F" "A" "L" "S" "E" | "T" "R" "U" "E".The case of letters in a
Boolean
is not significant. If the
prefix read from rd
is an entire Boolean
, Bool
returns that
boolean; else it raises Error
.
PROCEDURE Int(rd: Rd.T; defaultBase: [2..16] := 10) : INTEGER RAISES {Error, FloatMode.Trap, Rd.Failure, Alerted}; PROCEDURE Unsigned(rd: Rd.T; defaultBase: [2..16] := 16) : Word.T RAISES {Error, FloatMode.Trap, Rd.Failure, Alerted}; PROCEDURE LongInt(rd: Rd.T; defaultBase: [2..16] := 10) : LONGINT RAISES {Error, FloatMode.Trap, Rd.Failure, Alerted}; PROCEDURE LongUnsigned(rd: Rd.T; defaultBase: [2..16] := 16) : Long.T RAISES {Error, FloatMode.Trap, Rd.Failure, Alerted};
Read a number from rd
and return its value.
Each procedure skips blanks, then reads the longest prefix of
rd
that is a prefix of a Number
as defined by the grammar below. If
defaultBase
exceeds 10, then the procedure scans for a
BigBaseNum
; otherwise it scans for a SmallBaseNum
. The effect
of this rule is that the letters 'a' through 'f' and 'A' through
'F' stop the scan unless either the defaultBase
or the explicitly
provided base exceeds 10. Unsigned
omits the scan for a Sign
.
Number = [Sign] (SmallBaseNum | BigBaseNum). SmallBaseNum = DecVal | BasedInt. BigBaseNum = HexVal | BasedInt. BasedInt = SmallBase "_" DecVal | BigBase "_" HexVal. DecVal = Digit {Digit}. HexVal = HexDigit {HexDigit}. Sign = "+" | "-". SmallBase = "2" | "3" | ... | "10". BigBase = "11" | "12" | ... | "16". Digit = "0" | "1" | ... | "9". HexDigit = Digit | "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f".If the prefix read from
rd
is an entire Number
(as described
above), the corresponding number is returned; else Error
is
raised.
If an explicit base is given with an underscore, it is interpreted
in decimal. In this case, the digits in DecVal
or HexVal
are
interpreted in the explicit base, else they are interpreted in the
defaultBase
.
Both procedures may raise FloatMode.Trap(IntOverflow)
. They
raise Error
if some digit in the value part is not a legal digit
in the chosen base.
PROCEDURE Real(rd: Rd.T): REAL RAISES {Error, FloatMode.Trap, Rd.Failure, Alerted}; PROCEDURE LongReal(rd: Rd.T): LONGREAL RAISES {Error, FloatMode.Trap, Rd.Failure, Alerted}; PROCEDURE Extended(rd: Rd.T): EXTENDED RAISES {Error, FloatMode.Trap, Rd.Failure, Alerted};
Read a real number from rd
and return its value.
Each procedure skips blanks, then reads the longest prefix of
rd
that is a prefix of a floating-decimal number Float
in the
grammar:
Float = [Sign] FloVal [Exp]. FloVal = {Digit} (Digit | Digit "." | "." Digit) {Digit}. Exp = Marker [Sign] Digit {Digit}. Marker = ("E" | "e" | "D" | "d" | "X" | "x").where
Sign
and Digit
are as defined above. If the prefix read
from rd
is an entire Float
, that Float
is converted to a
REAL
, LONGREAL
, or EXTENDED
using the routine FromDecimal
in the appropriate instance of the Float
generic interface; else
Error
is raised. Note that the exponent of Float
can be
introduced with any of the six characters 'e'
, 'E'
, 'd'
,
'D'
, 'x'
, or 'X'
, independent of the target type of the
conversion.
On IEEE implementations, the syntax for Float
is extended as
follows:
Float = [Sign] FloVal [Exp] | [Sign] IEEEVal. IEEEVal = "I" "N" "F" "I" "N" "I" "T" "Y" | "I" "N" F" | "N" "A" "N".The case of letters in an
IEEEVal
is not significant. The
FloatMode.Trap
exception may be raised with any of the arguments
Overflow
, Underflow
, or Inexact
.
END Lex.