(* lexical analysis for untyped lambda terms *) (* generates lexer.ml *) (* $Id: lexer.mll,v 1.23 2000/06/27 19:28:55 alamstei Exp $ *) { open Parser let reserved_words = [ ("let", LET); ("rec", REC); ("in", IN); ("true", BOOL(true)); ("false", BOOL(false)); ("case", CASE); ("of", OF) ] (* local exception thrown by get_pair. Used while extracting pairs from input. more specific message is thrown later depending on what the pairs represent *) exception Illegal_pair let get_pair str = let slashpos = String.index str '/' in let len = String.length str in let num1 = String.sub str 2 (slashpos-2) in let num2 = String.sub str (slashpos+1) (len-slashpos-1) in let i = int_of_string num1 in let j = int_of_string num2 in if (i >= 1 && i <= j && j > 1) then (i,j) else raise Illegal_pair } let letter = ['a' - 'z' 'A' - 'Z' '_' '\''] let number = ['0' - '9'] let int = '-'? number number* let absint = number number* let alphanum = letter | number let identifier = letter alphanum* let whitespace = [' ' '\t' '\n']* let comment = '#' [^'\n']* let proj = "pi" absint "/" absint let inj = "in" absint "/" absint rule token = parse whitespace { token lexbuf } (* skip blanks *) | comment { token lexbuf } (* skip comments *) | identifier { let id = Lexing.lexeme lexbuf in try List.assoc id reserved_words with Not_found -> IDENT(id) } | int { INT( int_of_string (Lexing.lexeme lexbuf)) } | "(" { LPAR } | ")" { RPAR } | "\\" { ABS } | "." { DOT } | "=" { EQUALS } | eof { EOF } | "," { COMMA } | "->" { ARROW } | "|" { CASEOR } | "/" { SLASH } | proj { try PROJ (get_pair (Lexing.lexeme lexbuf)) with Illegal_pair -> raise (Exn.Illegal_projection (Lexing.lexeme lexbuf, (Lexing.lexeme_start lexbuf), (Lexing.lexeme_end lexbuf))) } | inj { try INJ (get_pair (Lexing.lexeme lexbuf)) with Illegal_pair -> raise (Exn.Illegal_injection (Lexing.lexeme lexbuf, (Lexing.lexeme_start lexbuf), (Lexing.lexeme_end lexbuf))) } | _ { raise (Exn.Illegal_character(Lexing.lexeme lexbuf, Lexing.lexeme_start lexbuf, Lexing.lexeme_end lexbuf)) }