%{ (* 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 IDENT %token COMMA DOT %token ASTERISK %token AS ON %token OR AND NOT %token EOF %start main %type 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 { Table($1) }*) | 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) } qualified_join: | table_reference JOIN table_reference join_specification { Join($1, Left, $3) } | table_reference join_type JOIN table_reference join_specification { Join($1, $2, $4) } join_specification: | join_condition {} join_condition: | ON search_condition {} natural_join: | table_reference NATURAL JOIN table_primary { Join($1, Natural, $4) } | table_reference NATURAL join_type JOIN table_primary { Join($1, Natural, $5) } union_join: | table_reference UNION JOIN table_primary { Join($1,Union, $4) } 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: | boolean_term {} | boolean_value_expression OR boolean_term {} boolean_term: | boolean_factor {} | boolean_term AND boolean_factor {} boolean_factor: | boolean_test {} | NOT boolean_test {} boolean_test: | boolean_primary {} boolean_primary : | predicate {} | boolean_predicand {} predicate : | comparison_predicate {} comparison_predicate : | row_value_predicand comparison_predicate_part2 {} comparison_predicate_part2: | comp_op row_value_predicand {} comp_op : | EQUALS_OPERATOR {} | not_equals_operator {} | LESS_THAN_OPERATOR {} | GREATER_THAN_OPERATOR {} | less_than_or_equals_operator {} | greater_than_or_equals_operator {} 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 {} row_value_special_case : | nonparenthesized_value_expression_primary {} nonparenthesized_value_expression_primary: | column_reference {} column_reference: | basic_identifier_chain {} basic_identifier_chain: | identifier_chain {} identifier_chain: | IDENT {} | identifier_chain DOT IDENT {} boolean_predicand: | nonparenthesized_value_expression_primary {}