mips-cc

A little C compiler
git clone git@git.mpah.dev/mips-cc.git
Log | Files | Refs | README

lexer.mll (2575B)


      1 {
      2   open Lexing
      3   open Parser
      4 
      5   exception Error of char
      6   exception StrEndError of string
      7 
      8   let keyword_table = Hashtbl.create 2
      9   let _ =
     10   List.iter (fun (kwd, tok) -> Hashtbl.add keyword_table kwd tok)
     11     [ "int", Lint_k;
     12       "char", Lchar_k;
     13       "float", Lfloat_k;
     14       "void", Lvoid_k;
     15       "bool", Lbool_k ]
     16 }
     17 
     18 let alpha = ['a'-'z' 'A'-'Z']
     19 let num = ['0'-'9']
     20 let numf = (num+ '.' num*)
     21 let character = "'"(_ | '\\'['a' 'b' 't' 'n' 'v' 'f' 'r' '0' '\\' '''])"'"
     22 let ident = alpha (alpha | num | '-' | '_')*
     23 
     24 rule token = parse
     25   | eof             { Lend }
     26   | [ ' ' '\t' ]    { token lexbuf }
     27   | '\n'            { Lexing.new_line lexbuf; token lexbuf }
     28   | "//"            { comment lexbuf }
     29   | "#"             { comment lexbuf } (* Ignore preprocessor *)
     30   | "/*"            { multi_line_comment lexbuf }
     31   | ";"             { Lsc }
     32   | "return"        { Lreturn }
     33   | "if"            { Lif }
     34   | "else"          { Lelse }
     35   | "while"         { Lwhile }
     36   | "true" as b     { Ltrue (bool_of_string b)}
     37   | "false" as b    { Lfalse (bool_of_string b) }
     38   | num+ as n       { Lint(int_of_string n) }
     39   | numf+ as n      { Lfloat(float_of_string n) }
     40   | character as c  { Lchar(c) }
     41   | '"'             { Lstr (String.concat "" (str lexbuf))}
     42   | '+'             { Ladd }
     43   | '-'             { Lsub }
     44   | '*'             { Lmul }
     45   | '%'             { Lmod }
     46   | '/'             { Ldiv }
     47   | '='             { Lassign }
     48   | '('             { Lopar }
     49   | ')'             { Lcpar }
     50   | '{'             { Lobra }
     51   | '}'             { Lcbra }
     52   | ','             { Lcom }
     53   | "=="            { Leq }
     54   | "!="            { Lneq }
     55   | ">"             { Lgt }
     56   | ">="            { Lge }
     57   | "<"             { Llt }
     58   | "<="            { Lle }
     59   | '|'             { Lor }
     60   | '^'             { Lxor }
     61   | '&'             { Land }
     62   | '!'             { Lex }
     63   | "puts"          { Lputs }
     64   | "puti"          { Lputi }
     65   | "geti"          { Lgeti }
     66   | ident * as id   { try
     67                         Hashtbl.find keyword_table id
     68                       with Not_found -> Lvar id }
     69   | _ as c          { raise (Error c) }
     70 
     71 and comment = parse
     72   | eof  { Lend }
     73   | '\n' { Lexing.new_line lexbuf; token lexbuf }
     74   | _    { comment lexbuf }
     75 
     76 and multi_line_comment = parse
     77   | eof  { Lend }
     78   | '\n' { Lexing.new_line lexbuf; multi_line_comment lexbuf }
     79   | "*/" { token lexbuf }
     80   | _    { multi_line_comment lexbuf }
     81 
     82 and str = parse
     83   | eof      { raise (StrEndError "error eof inside string") }
     84   | '"'      { [] }
     85   | _ as c   { (String.make 1 c) :: (str lexbuf) }