93 lines
2.7 KiB
OCaml
93 lines
2.7 KiB
OCaml
{
|
|
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) }
|