{ open Lexing open Parser exception SyntaxError of string let next_line lexbuf = let pos = lexbuf.lex_curr_p in lexbuf.lex_curr_p <- { pos with pos_bol = lexbuf.lex_curr_pos; pos_lnum = pos.pos_lnum + 1 } let linenum = ref 0 let filename = ref "" } rule token = parse | '#'' '+['0'-'9']+' '+'"'[^'"']+'"'(' '+['1'-'4'])*'\n' as marker { (* * The C preprocessor inserts so called ``line markers'' into the output. * These markers have the following form: * * # * * This marker indicates that all lines after this marker up to the next * marker come from the file starting at line . After * the file name can be zero or more flags, these flags are 1, 2, 3, 4. * These flags can be ignored. *) Scanf.sscanf marker "# %d \"%s\"" (fun i s -> linenum := i - 1; filename := String.copy s); token lexbuf } (*| ['('')''['']''{''}'';'','] as literal { literal }*) | '(' { LPAREN } | ')' { RPAREN } | '[' { LBRACK } | ']' { RBRACK } | '{' { LBRACE } | '}' { RBRACE } | ';' { SEMICOL } | ',' { COMMA } | '=' { ASSIGN } | '!' { NOT } | '+' { ADD } | '-' { SUB } | '*' { MUL } | '/' { DIV } | '%' { MOD } | "<=" { LE } | "<" { LT } | ">=" { GE } | ">" { GT } | "==" { EQ } | "!=" { NE } | "&&" { AND } | "||" { OR } | "if" { IF } | "else" { ELSE } | "do" { DO } | "while" { WHILE } | "for" { FOR } | "return" { RETURN } | "extern" { EXTERN } | "export" { EXPORT } | "int" { INT } | "bool" { BOOL } | "float" { FLOAT } | "void" { VOID } | "true" { BOOL_CONST true } | "false" { BOOL_CONST false } | ['0'-'9']+ as i { INT_CONST (int_of_string i) } | ['0'-'9']+'.'['0'-'9']+ as f { FLOAT_CONST (float_of_string f) } | ['A'-'Z''a'-'z']['A'-'Z''a'-'z''0'-'9''_']* as id { ID id } | '\r'|'\n'|"\r\n" { next_line lexbuf; token lexbuf } | [' ''\t']+ { token lexbuf } | "//"_* | "/*"_*"*/" { token lexbuf } | eof { EOF } | _ as chr { raise (SyntaxError ("Unexpected char: " ^ Char.escaped chr)) }