DIRECTORY Rope USING [ROPE]; CedarScanner: CEDAR DEFINITIONS = BEGIN OPEN Rope; TokenKind: TYPE = { tokenERROR, -- token.msg describes the scanning error tokenID, -- an identifier or reserved word tokenINT, -- an INT literal tokenREAL, -- a REAL literal tokenROPE, -- a ROPE literal tokenCHAR, -- a CHAR literal tokenATOM, -- an ATOM literal tokenSINGLE, -- a single-character token tokenDOUBLE, -- a double-character token tokenCOMMENT, -- a comment tokenEOF -- the end-of-file marker }; Token: TYPE = RECORD [start: INT, next: INT, kind: TokenKind, msg: ROPE]; GetProc: TYPE = PROC [data: REF, index: INT] RETURNS [CHAR]; GetClosure: TYPE = RECORD[proc: GetProc, data: REF _ NIL]; GetToken: PROC [get: GetClosure, index: INT] RETURNS [token: Token]; RealFromToken: PROC [get: GetClosure, token: Token] RETURNS [REAL]; IntFromToken: PROC [get: GetClosure, token: Token] RETURNS [INT]; CharFromToken: PROC [get: GetClosure, token: Token] RETURNS [CHAR]; SingleFromToken: PROC [get: GetClosure, token: Token] RETURNS [CHAR]; RopeFromToken: PROC [get: GetClosure, token: Token] RETURNS [ROPE]; AtomFromToken: PROC [get: GetClosure, token: Token] RETURNS [ATOM]; ContentsFromToken: PROC [get: GetClosure, token: Token] RETURNS [ROPE]; WrongKind: ERROR; IntegerOverflow: ERROR; END. òMesaScanner.mesa Russ Atkinson, August 27, 1982 12:50 pm Last Edited by: Teitelman, December 20, 1982 4:21 pm start gives the 1st char pos of the token next gives the char pos immediately after the token (length = next - size) msg # NIL only for kind = tokenERROR type of user proc used to get characters NUL should be returned to indicate fetch beyond end ability to randomly access characters is assumed gets a token given a character source and a starting position the current errors (in token.msg) are: "invalid escape code" "invalid octal constant" "invalid character code" "end-of-file in string literal" "invalid atom" "invalid character" takes a Token into a REAL (parses the literal) signals WrongKind if token.kind # tokenREAL other errors may be propagated from Real.ReadReal takes a Token into a INT (parses the literal) error WrongKind if token.kind # tokenINT error IntegerOverflow if decimal and number > LAST[INT] error IntegerOverflow if octal and number > LAST[LONG CARDINAL] takes a Token into a CHAR (parses the literal) signals WrongKind if token.kind # tokenCHAR takes a Token into a CHAR signals WrongKind if token.kind # tokenSINGLE takes a Token into a ROPE (parses the literal) signals WrongKind if token.kind # tokenROPE takes a Token into a ATOM (parses the literal) signals WrongKind if token.kind # tokenATOM gets the contents of the token as a ROPE can be used on any token raised when attempting to parse the wrong kind of literal raised when attempting to parse an excessive integer ÊA˜J˜Jšœ™Jšœ'™'Jšœ4™4J˜šÏk ˜ Jšœœœ˜J˜—JšÐbl œœ ˜J˜šœœœ˜J˜—J˜šÏn œœ˜Jšœ Ïc)˜5Jšœ  "˜+Jšœ  ˜Jšœ  ˜Jšœ  ˜Jšœ  ˜Jšœ  ˜Jšœ  ˜(Jšœ  ˜(Jšœ  ˜Jšœ  ˜#šœ˜J˜——š Ÿœœœ œœœ˜IJšœ)™)Jšœ3™3Jšœ™Jšœ$™$J˜—šŸœœœœ œœœ˜