<> <> <> 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]; <> <> <<(length = next - size)>> <> 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]; <> <> <<"invalid escape code">> <<"invalid octal constant">> <<"invalid character code">> <<"end-of-file in string literal">> <<"invalid atom">> <<"invalid character">> RealFromToken: PROC [get: GetClosure, token: Token] RETURNS [REAL]; <> <> <> IntFromToken: PROC [get: GetClosure, token: Token] RETURNS [INT]; <> <> < LAST[INT]>> < LAST[LONG CARDINAL]>> 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.