9 let store str = curStr := str
11 let error buf callerID =
12 Error.report "Lexer error : %s" callerID;
14 raise Parsing.Parse_error
16 let advance_line_pos pos =
17 let module L = Lexing in
18 {L.pos_fname=pos.L.pos_fname;
19 pos_lnum = pos.L.pos_lnum + 1;
21 pos_cnum = pos.L.pos_cnum}
23 let advance_line lexbuf =
24 lexbuf.Lexing.lex_curr_p <- advance_line_pos lexbuf.Lexing.lex_curr_p
28 let alpha = ['a'-'z' 'A'-'Z']
29 let ident = (alpha) (alpha | digit | '_' )*
31 let mnot = ("NOT" wsp+)?
33 rule ruleStatement props = parse
34 | ['\n' ' ' '\t']+ { ruleStatement props lexbuf }
36 | "--" wsp* "[sql2cpp]" wsp+ (ident+ as n) wsp* "=" wsp* ([^'\n']* as v) '\n'
38 ruleStatement (Props.set props n v) lexbuf
40 | "--" { store ""; ignore (ruleComment lexbuf); ruleStatement props lexbuf }
41 | alpha [^ ';']+ as stmt ';' { Some (stmt,props) }
45 | wsp { ruleMain lexbuf }
46 (* update line number *)
47 | '\n' { advance_line lexbuf; ruleMain lexbuf}
54 | "--" { store ""; ignore (ruleComment lexbuf); ruleMain lexbuf }
55 (* | '"' { store ""; ruleInQuotes lexbuf } *)
58 | "CREATE" wsp+ "TABLE" { CREATE_TABLE }
60 | "REPLACE" { REPLACE }
62 | "DELETE" wsp+ "FROM" { DELETE_FROM }
72 | "UNION" (wsp+ "ALL")? | "EXCEPT" | "INTERSECT" { COMPOUND_OP }
84 (* column-constraint *)
85 | "NOT" wsp+ "NULL" { NOT_NULL }
87 | "PRIMARY" wsp+ "KEY" { PRIMARY_KEY }
88 | "AUTOINCREMENT" { AUTOINCREMENT }
89 | "DEFAULT" { DEFAULT }
92 | "INTEGER" { T_INTEGER }
96 | "DISTINCT" { DISTINCT }
99 | "ORDER" wsp+ "BY" { ORDER_BY }
103 | "OFFSET" { OFFSET }
105 | "?" { PARAM Stmt.Raw.Next }
106 | "?" (digit+ as str) { PARAM (Stmt.Raw.Numbered (int_of_string str)) }
107 | [':' '@'] (ident as str) { PARAM (Stmt.Raw.Named str) }
110 | "CONFLICT" { CONFLICT }
113 | "IGNORE" { IGNORE }
114 | "REPLACE" { REPLACE }
117 | "ROLLBACK" { ROLLBACK }
120 (("LEFT"|"RIGHT"|"FULL") wsp+)?
121 (("INNER"|"OUTER"|"CROSS") wsp+)?
124 | mnot ("LIKE" | "GLOB" | "REGEXP" | "MATCH") { LIKE_OP }
128 | "MAX" | "MIN" | "CONCAT" { FUNCTION }
129 | "ISNULL" | "NOTNULL" { TEST_NULL }
130 | "BETWEEN" { BETWEEN }
132 | "ESCAPE" { ESCAPE }
134 | '\'' { TEXT (ruleInSingleQuotes "" lexbuf) }
135 | ['x' 'X'] '\'' { BLOB (ruleInSingleQuotes "" lexbuf) }
137 | ident as str { IDENT (str) }
138 | digit+ as str { INTEGER (int_of_string str) }
140 | _ { error lexbuf "ruleMain" }
142 ruleInSingleQuotes acc = parse
144 | eof { error lexbuf "no terminating quote" }
145 | '\n' { advance_line lexbuf; error lexbuf "EOL before terminating quote" }
146 | "''" { ruleInSingleQuotes (acc ^ "'") lexbuf }
147 | [^'\'' '\n']+ { ruleInSingleQuotes (acc ^ Lexing.lexeme lexbuf) lexbuf }
148 | _ { error lexbuf "ruleInSingleQuotes" }
151 | '\n' { advance_line lexbuf; !curStr }
153 | [^'\n']+ { store (Lexing.lexeme lexbuf); ruleComment lexbuf; }
154 | _ { error lexbuf "ruleComment"; }
158 let parse_rule lexbuf = ruleMain lexbuf