minic/lexer.mll

93 lines
2.7 KiB
OCaml
Raw Permalink Normal View History

2022-01-27 16:31:58 +01:00
{
open Lexing
open Parser
exception Error of char
exception ErrorStr of string
let keywords =
[
("void", Lvoid_kw);
("int", Lint_kw);
("char", Lchar_kw);
("float", Lfloat_kw);
("bool", Lbool_kw);
("return", Lreturn);
("puts", Lputs);
("puti", Lputi);
("geti", Lgeti);
("if", Lif);
("else", Lelse);
(* ("for", Lfor); *)
(* ("do", Ldo); *)
("while", Lwhile);
(* ("break", Lbreak); *)
(* ("continue", Lcontinue) *)
]
let find_kw s =
match List.assoc_opt s keywords with
| Some kw -> kw
| None -> Lvar s
}
let alpha = ['a'-'z' 'A'-'Z']
let num = ['0'-'9']
let numf = (num)+ '.' (num)+
let identifier = alpha (alpha | num | '-' | '_')*
let character = (_ | '\\'['a' 'b' 't' 'n' 'v' 'f' 'r' '0' '\\' '''])
let boo = ("true" | "false")
rule token = parse
| eof { Lend }
| [ ' ' '\t' ] { token lexbuf }
| '\n' { Lexing.new_line lexbuf; token lexbuf }
| "//" { comment lexbuf }
| "/*" { multiline_comment lexbuf }
| ('-')? numf as n { Lfloat (float_of_string n) }
| ('-')? num+ as n { Lint (int_of_string n) }
| boo as b { Lbool (bool_of_string b) }
| "'" character"'" as c { Lchar c }
| '"' { Lstr (str lexbuf) }
| "(" { Lopar }
| ")" { Lcpar }
(* | "[" { Lob } *)
(* | "]" { Lcb } *)
| ";" { Lsc }
| "*" { Lmul }
| "+" { Ladd }
| "/" { Ldiv }
| "%" { Lmod }
| "^" { Lxor }
| "&" { Land }
| "|" { Lor }
| "-" { Lsub }
| "=" { Lassign }
| "==" { Leq }
| "!=" { Lneq }
| ">=" { Lge }
| ">" { Lgt }
| "<=" { Lle }
| "<" { Llt }
| "," { Lcomma }
| "{" { Lobr }
| "}" { Lcbr }
| "!" { Lnot }
| identifier as i { find_kw i }
| _ as c { raise (Error c) }
and comment = parse
| eof { Lend }
| '\n' { Lexing.new_line lexbuf; token lexbuf }
| _ { comment lexbuf }
and multiline_comment = parse
| eof { Lend }
| '\n' { Lexing.new_line lexbuf; multiline_comment lexbuf }
| "*/" { token lexbuf }
| _ { multiline_comment lexbuf }
and str = parse
| eof { raise (ErrorStr "Unexpected EOF") }
| '"' { "" }
| _ as c { (String.make 1 c) ^ (str lexbuf) }