ocaml_sql_parser/parser/parser.mly

178 lines
3.9 KiB
OCaml

%{
(* Header: Define the AST type *)
open Ast
%}
%token SELECT ALL DISTINCT FROM WHERE
%token LEFT RIGHT FULL INNER OUTER
%token CROSS NATURAL UNION JOIN
%token GREATER_THAN_OPERATOR LESS_THAN_OPERATOR EQUALS_OPERATOR
%token <string> IDENT
%token COMMA DOT
%token ASTERISK
%token AS ON
%token OR AND NOT
%token EOF
%start main
%type <query> main
%%
main:
| select_stmt EOF { Query($1) }
select_stmt :
| SELECT select_list table_expression { Select($2, $3) }
| SELECT set_identifier select_list table_expression { Select($3, $4) }
set_identifier :
| ALL {}
| DISTINCT {}
select_list :
| ASTERISK { [Asterisk] }
| select_sublist {$1}
select_sublist :
| IDENT { [Column($1)] }
| select_sublist COMMA IDENT { Column($3)::$1 }
table_expression:
| from_clause { $1 }
| from_clause where_clause { $1 }
from_clause :
| FROM table_reference_list { $2 }
table_reference_list :
| table_reference { [$1] }
| table_reference_list COMMA table_reference { $3::$1 }
table_reference :
| table_primary_or_joined_table { $1 }
(* | table_primary_or_joined_table sample_clause { $1 } *)
table_primary_or_joined_table:
| table_primary { $1 }
| joined_table { $1 }
table_primary :
| table_or_query_name { $1 }
table_or_query_name:
| table_name { $1 }
joined_table :
| cross_join { $1 }
| qualified_join { $1 }
| natural_join { $1 }
| union_join { $1 }
cross_join:
| table_reference CROSS JOIN table_primary { Join($1, Cross, $4, None) }
qualified_join:
| table_reference JOIN table_reference join_specification { Join($1, Left, $3, $4) }
| table_reference join_type JOIN table_reference join_specification { Join($1, $2, $4, $5) }
join_specification:
| join_condition { $1 }
join_condition:
| ON search_condition { Some($2) }
natural_join:
| table_reference NATURAL JOIN table_primary { Join($1, Natural, $4, None) }
| table_reference NATURAL join_type JOIN table_primary { Join($1, Natural, $5, None) }
union_join:
| table_reference UNION JOIN table_primary { Join($1, Union, $4, None) }
table_name :
| IDENT { Table($1) }
join_type:
| INNER { Inner }
| outer_join_type { $1 }
| outer_join_type OUTER { $1 }
outer_join_type:
| LEFT { Left }
| RIGHT { Right }
| FULL { Full }
where_clause :
| WHERE search_condition { }
search_condition:
(*| IDENT EQUALS_OPERATOR IDENT {}*)
| boolean_value_expression { $1 }
boolean_value_expression:
| boolean_term { $1 }
| boolean_value_expression OR boolean_term { Or($1, $3) }
boolean_term:
| boolean_factor { $1 }
| boolean_term AND boolean_factor { And($1, $3) }
boolean_factor:
| boolean_test { $1 }
| NOT boolean_test { Not($2) }
boolean_test:
| boolean_primary { $1 }
boolean_primary :
| predicate { $1 }
(*| boolean_predicand {}*)
predicate :
| comparison_predicate { $1 }
comparison_predicate :
| row_value_predicand comparison_predicate_part2 { Condition($1, $2) }
comparison_predicate_part2:
| comp_op row_value_predicand { Comparison($1, $2) }
comp_op :
| EQUALS_OPERATOR { Equals }
| not_equals_operator { NotEquals }
| LESS_THAN_OPERATOR { LessThan }
| GREATER_THAN_OPERATOR { GreaterThan }
| less_than_or_equals_operator { LessEquals }
| greater_than_or_equals_operator { GreaterEquals }
not_equals_operator :
| LESS_THAN_OPERATOR GREATER_THAN_OPERATOR {}
less_than_or_equals_operator:
| LESS_THAN_OPERATOR EQUALS_OPERATOR {}
greater_than_or_equals_operator:
| GREATER_THAN_OPERATOR EQUALS_OPERATOR {}
row_value_predicand:
| row_value_special_case { $1 }
row_value_special_case :
| nonparenthesized_value_expression_primary { $1 }
nonparenthesized_value_expression_primary:
| column_reference { $1 }
column_reference:
| basic_identifier_chain { $1 }
basic_identifier_chain:
| identifier_chain { $1 }
identifier_chain:
| IDENT { $1 }
(*| identifier_chain DOT IDENT {}*)
boolean_predicand:
| nonparenthesized_value_expression_primary {}