{ (* Exprlex.lex: lexer specification for the simple expression language *) open Lexing Exprpar; 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 a hashtable instead. *) fun keyword s = case s of "let" => LET | "in" => IN | "end" => END | _ => NAME s; } rule Token = parse [` ` `\t` `\n` `\r`] { Token lexbuf } | [`0`-`9`]+ { case Int.fromString (getLexeme lexbuf) of NONE => lexerError lexbuf "internal error" | SOME i => CSTINT i } | [`a`-`z``A`-`Z`][`a`-`z``A`-`Z``0`-`9`]* { keyword (getLexeme lexbuf) } | `+` { PLUS } | `-` { MINUS } | `*` { TIMES } | `=` { EQ } | `(` { LPAR } | `)` { RPAR } | eof { EOF } | _ { lexerError lexbuf "Illegal symbol in input" } ;