../ppc/lexer.mll
{
open Parser;;        (* The type token is defined in parser.mli *)
exception Eof;;
exception Illegal;;
let keywords = Hashtbl.create 13;;
let () =
  List.iter (function key, data -> Hashtbl.add keywords key data)
    [
  "var", VAR;
  "alloc",  ALLOC;
  "false",  BOOL false;
  "true",  BOOL true;
  "read",  READ;
  "write",  WRITE;
  "writeln",  WRITELN;
  "array",  ARRAY;
  "of",  OF;
  "do",  DO;
  "begin",  BEGIN;
  "end",  END;
  "if",  IF;
  "then",  THEN;
  "else",  ELSE;
  "while",  WHILE;
  "type",  TYPE;
  "function",  FUNCTION;
  "procedure",  PROCEDURE;
  "integer",  INTEGER;
  "boolean",  BOOLEAN;
  "program",  PROGRAM;
];;
let ident_or_keyword s =
  try Hashtbl.find keywords s with Not_found -> IDENT s
;;
}
rule token = parse
    [' ' '\t' '\n']
                   { token lexbuf }     (* skip blanks *)
  | '"' ( [^ '"' ] | "\\\"" ) * '"'    
                   { STRING (Lexing.lexeme lexbuf) }
  | ['A'-'Z' 'a'-'z' '_'] + ['0'-'9'] * ''' *
                   { ident_or_keyword (Lexing.lexeme lexbuf) }
  | ['0'-'9']+     { INT(int_of_string (Lexing.lexeme lexbuf)) }
  | ";;"           { SEMISEMI }
  | ":="           { COLONEQUAL }
  | "<>"           { LESSGREATER }
  | "<="           { LESSEQUAL }
  | ">="           { GREATEREQUAL }
  | '<'            { LESS }
  | '>'            { GREATER }
  | ";"            { SEMI }
  | ","            { COMMA }
  | ':'            { COLON }
  | '='            { EQUAL }
  | '-'            { MINUS }
  | '+'            { PLUS }
  | '*'            { TIMES }
  | '/'            { DIV }
  | '('            { LPAREN }
  | ')'            { RPAREN }
  | '['            { LBRACKET }
  | ']'            { RBRACKET }
  | eof            { raise Eof }
  | _              { raise Illegal }