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.
INTERFACE Lex; IMPORT FloatMode, Rd, Word; FROM Thread IMPORT Alerted; EXCEPTION Error; CONST Blanks = SET OF CHAR{ ' ', '\t', '\n', '\r', '\013' (* vertical tab *), '\f'}; NonBlanks = SET OF CHAR{'!' .. '~'};
Each 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 call 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};
PROCEDURE Skip( rd: Rd.T; READONLY cs: SET OF CHAR := Blanks) RAISES {Rd.Failure, Alerted};
Read the longest prefix of rd composed of characters in cs 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 of rd that is also a prefix of t. Raise Error if that prefix is not, in fact, equal to all of t.
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};
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.
Read the longest prefix of rd composed of characters in cs and return that prefix as a TEXT.