(* Analyseur lexical pour le langage Julia *) { open Parser open Lexing let keywords = [ "true", TRUE; "false", FALSE; "return", RETURN; "for", FOR; "end", END; "while", WHILE; "else", ELSE; "elseif", ELSEIF; "if", IF; "function", FUNCTION; "mutable", MUTABLE; "struct", STRUCT ] let hsh = Hashtbl.create 16 let create_hash = List.iter (fun (a, b) -> Hashtbl.add hsh a b) keywords let kwd_or_ident s = try Hashtbl.find hsh (String.lowercase_ascii s) with | Not_found -> IDENT s let get_entier_ident s = let i = ref 0 in while (Char.code s.[!i]) >= (Char.code '0') && (Char.code s.[!i]) <= (Char.code '9') do incr i done; (int_of_string (String.sub s 0 !i), String.sub s !i (String.length s - !i)) exception Lexing_error of string } let space = [' ' '\t'] let chiffre = ['0'-'9'] let alpha = ['a'-'z' 'A'-'Z' '_'] let entier = chiffre+ let car = [' ' '!' '#'-'[' ']'-'~'] | "\\\\" | "\\\"" | "\\n" | "\\t" let chaine = '"' car* '"' let ident = alpha (chiffre | alpha)* let entier_ident = entier ident let ident_parg = ident '(' let entier_parg = entier '(' let pard_ident = ')' ident rule next_tokens = parse | space+ { next_tokens lexbuf } | '#' [^ '\n']* '\n' | '\n' { new_line lexbuf; [NEWLINE] } | entier as s { try [CST (int_of_string s)] with _ -> raise (Lexing_error ("Integer too big " ^ s)) } | '+' { [ADD] } | '-' { [SUB] } | '*' { [MUL] } | '%' { [MOD] } | '^' { [POW] } | "==" { [ EQ ] } | "!=" { [ DIFF ] } | '<' { [ LT ] } | "<=" { [ LE ] } | '>' { [ GT ] } | ">=" { [ GE ] } | "&&" { [ AND ] } | "||" { [ OR ] } | entier_ident as s { [ENTIER_IDENT (get_entier_ident s)] } | ident_parg as s { [IDENT_PARG (String.sub s 0 (String.length s - 1))] } | entier_parg as s { let s = String.sub s 0 (String.length s - 1) in try [ENTIER_PARG (int_of_string s)] with _ -> raise (Lexing_error ("Integer too big " ^ s)) } | pard_ident as s { [PARD_IDENT (String.sub s 1 (String.length s -1))] } | '(' { [LPAR] } | ')' { [RPAR] } | ';' { [SEMICOLON] } | ',' { [COMMA] } | "::" { [DOUBLECOLON] } | ":" { [COLON] } | '.' { [DOT] } | '=' { [ASSIGN] } | chaine as s { [STRING s] } | ident as s { [kwd_or_ident s] } | eof { [EOF] } | _ as c {raise (Lexing_error ("Illegal character: " ^ String.make 1 c)) } { let next_token = let tokens = Queue.create () in let lastToken = ref EOF in let tokensColon = function | IDENT _ | CST _ | ENTIER_IDENT _ | PARD_IDENT _ | TRUE | FALSE | RPAR | END | STRING _ | RETURN -> true | _ -> false in (* Missing chaine return end *) let rec ret lb = if Queue.is_empty tokens then List.iter (fun t -> Queue.add t tokens) (next_tokens lb); let curToken = Queue.pop tokens in if curToken = NEWLINE then ( if tokensColon !lastToken then ( lastToken := SEMICOLON; SEMICOLON ) else ret lb) else ( lastToken := curToken; curToken ) in ret }