{ (* Revised extract of program by Peter Sestoft *) (* WHILElex.lex: lexer specification for a simple WHILE language *) open Lexing WHILEpar; exception LexicalError of string * int * int (* (message, loc1, loc2) *) fun lexerError lexbuf s = raise LexicalError (s, getLexemeStart lexbuf, getLexemeEnd lexbuf); (* Scan keywords as identifiers and use this function to distinguish them. *) (* If the set of keywords is large, use an auxiliary hashtable. *) fun keyword s = case s of "true" => TRUE | "false" => FALSE | "if" => IF | "THEN" => THEN | "ELSE" => ELSE | "while" => WHILE | "do" => DO | _ => VAR s; } rule Token = parse [` ` `\t` `\n` `\r`] { Token lexbuf } | [`0`-`9`]+ { case Int.fromString (getLexeme lexbuf) of NONE => lexerError lexbuf "internal error" | SOME i => INT i } | [`a`-`z``A`-`Z`][`a`-`z``A`-`Z``0`-`9`]* { keyword (getLexeme lexbuf) } | `+` { PLUS } | `-` { MINUS } | `*` { TIMES } | `&` { AND } | `!` { NEG } | `=` { EQ } | `<` { LT } | `(` { LPAR } | `)` { RPAR } | `;` { SEMI } | ":=" { ASS } | eof { EOF } | _ { lexerError lexbuf "Illegal symbol in input" } ;