2020-10-27 05:25:55
 
(* 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
}
Invalid Email or Password