{ open Parser exception LexingError of string let create_hashtable size init = let tbl = Hashtbl.create size in List.iter (fun (key, data) -> Hashtbl.add tbl key data) init; tbl let keyword_table = let mapping = [ ("main", MAIN); ("skip", SKIP); ("if", IF); ("else", ELSE); ("while", WHILE); ("for", FOR); ("do", DO); ("true", BOOL(true)); ("false", BOOL(false)); ("not", BNOT); ("rand", RAND); ("powmod", POWERMOD); ] in create_hashtable (List.length mapping) mapping } let digit = ['0'-'9'] let alpha = ['a'-'z' 'A'-'Z'] let white = [' ' '\t']+ | '\r' | '\n' | "\r\n" let integer = (digit)(digit*) let var = (alpha|'_') (alpha|digit|'_')* let symbols = ['!'-'/' ':'-'?' '[' ']' '^' '{'-'}' '~'] (* lexing rules *) rule read = parse | white {read lexbuf} | var as v { match Hashtbl.find_opt keyword_table v with | Some keyword -> keyword | None -> VARIABLE(v) } | ";" {SEQUENCE} | "," {COMMA} | "{" {LEFTGPAR} | "}" {RIGHTGPAR} | "(" {LEFTPAR} | ")" {RIGHTPAR} | "<" {BCMPLESS} | ">" {BCMPGREATER} | "+" {PLUS} | "-" {MINUS} | "*" {TIMES} | "/" {DIVISION} | "%" {MODULO} | "^" {POWER} | ":=" {ASSIGNMENT} | "&&" {BAND} | "||" {BOR} | "==" {BCMP} | "<=" {BCMPLESSEQ} | ">=" {BCMPGREATEREQ} | integer as i {INT(int_of_string i)} | "(*" {comments 0 lexbuf} | eof {EOF} | _ { raise (LexingError (Printf.sprintf "Error scanning %s on line %d at char %d" (Lexing.lexeme lexbuf) (lexbuf.Lexing.lex_curr_p.Lexing.pos_lnum) (lexbuf.Lexing.lex_curr_p.Lexing.pos_lnum) ))} and comments level = parse | "*)" {if level = 0 then read lexbuf else comments (level-1) lexbuf} | "(*" {comments (level+1) lexbuf} | _ {comments level lexbuf} | eof {raise (LexingError ("Comment is not closed"))} { let lex = read }