7 let store str = curStr := str
9 let error buf callerID =
10 Error.report "Lexer error : %s" callerID;
12 raise Parsing.Parse_error
14 let advance_line_pos pos =
15 let module L = Lexing in
16 {L.pos_fname = pos.L.pos_fname;
17 pos_lnum = pos.L.pos_lnum + 1;
18 pos_bol = pos.L.pos_cnum;
19 pos_cnum = pos.L.pos_cnum;}
21 let advance_line lexbuf =
22 lexbuf.Lexing.lex_curr_p <- advance_line_pos lexbuf.Lexing.lex_curr_p
24 (* use Map or Hashtbl ? *)
43 "autoincrement",AUTOINCREMENT;
49 (* CHARACTER, CHARACTER VARYING, BIT, BIT VARYING, NUMERIC, DECIMAL,
50 INTEGER, SMALLINT, FLOAT, REAL, DOUBLE PRECISION, DATE, TIME,
51 TIMESTAMP, and INTERVAL.*)
78 let all token l = k := !k @ List.map (fun x -> x,token) l in
79 all (FUNCTION (Some T.Int)) ["max"; "min"; "length"; "random";"count"];
80 all (FUNCTION (Some T.Text)) ["concat";];
81 all CONFLICT_ALGO ["ignore"; "replace"; "abort"; "fail"; "rollback";];
82 all JOIN_TYPE1 ["left";"right";"full"];
83 all JOIN_TYPE2 ["inner";"outer";"cross"];
84 all LIKE_OP ["like";"glob";"regexp";"match"];
87 let keywords = List.map (fun (k,v) -> (String.lowercase k, v)) keywords
90 let str = String.lowercase str in
91 try List.assoc str keywords with Not_found -> IDENT str
95 let alpha = ['a'-'z' 'A'-'Z']
96 let ident = (alpha) (alpha | digit | '_' )*
97 let wsp = [' ' '\r' '\t']
99 rule ruleStatement props = parse
100 | ['\n' ' ' '\r' '\t']+ { ruleStatement props lexbuf }
102 | "--" wsp* "[sql2cpp]" wsp+ (ident+ as n) wsp* "=" wsp* ([^'\n']* as v) '\n'
104 ruleStatement (Props.set props n v) lexbuf
106 | "--" { store ""; ignore (ruleComment lexbuf); ruleStatement props lexbuf }
107 | alpha [^ ';']+ as stmt ';' { Some (stmt,props) }
111 | wsp { ruleMain lexbuf }
112 (* update line number *)
113 | '\n' { advance_line lexbuf; ruleMain lexbuf}
120 | "--" { store ""; ignore (ruleComment lexbuf); ruleMain lexbuf }
121 (* | '"' { store ""; ruleInQuotes lexbuf } *)
123 | "UNION" (wsp+ "ALL")? | "EXCEPT" | "INTERSECT" { COMPOUND_OP }
133 | "/" | "%" | ">" | ">=" | "<=" | "<" | "&" | "|" { NUM_BINARY_OP }
135 | "?" { PARAM Stmt.Next }
136 | "?" (digit+ as str) { PARAM (Stmt.Numbered (int_of_string str)) }
137 | [':' '@'] (ident as str) { PARAM (Stmt.Named str) }
139 | "'" { TEXT (ruleInSingleQuotes "" lexbuf) }
140 | ['x' 'X'] "'" { BLOB (ruleInSingleQuotes "" lexbuf) }
142 | ident as str { get_ident str }
143 | digit+ as str { INTEGER (int_of_string str) }
145 | _ { error lexbuf "ruleMain" }
147 ruleInSingleQuotes acc = parse
149 | eof { error lexbuf "no terminating quote" }
150 | '\n' { advance_line lexbuf; error lexbuf "EOL before terminating quote" }
151 | "''" { ruleInSingleQuotes (acc ^ "'") lexbuf }
152 | [^'\'' '\n']+ { ruleInSingleQuotes (acc ^ Lexing.lexeme lexbuf) lexbuf }
153 | _ { error lexbuf "ruleInSingleQuotes" }
156 | '\n' { advance_line lexbuf; !curStr }
158 | [^'\n']+ { store (Lexing.lexeme lexbuf); ruleComment lexbuf; }
159 | _ { error lexbuf "ruleComment"; }
163 let parse_rule lexbuf = ruleMain lexbuf