SQL1 BNF Syntax Description

[This is preliminary documentation and subject to change.]

<parse> ::= SELECT <prop_list> FROM <class_name> <opt_where>;
<parse> ::= SELECT <prop_list> FROM <class_name> <tolerance> <opt_where>
                <opt_aggregation>;

<opt_where> ::= WHERE <expr>;
<opt_where> ::= <>;

<prop_list> ::= <property_name> <prop_list_2>;
<prop_list_2> ::= COMMA <prop_list>;
<prop_list_2> ::= <>;

<property_name> ::= ASTERISK;
<property_name> ::= IDENTIFIER <property_name_2>;
<property_name_2> ::= <>;
<property_name_2> ::= DOT IDENTIFIER <property_name_2>;

<class_name> ::= IDENTIFIER;
<tolerance> ::= <>;
<tolerance> ::= WITHIN <duration>;

<duration> ::= DOUBLE;

// Subexpression nesting.  This particular sequence gives
// a series of AND clauses precedence over OR clauses.

<expr> ::= <term> <expr2>;
<expr2> ::= OR <term> <expr2>;
<expr2> ::= <>;

<term> ::= <simple_expr> <term2>;
<term2> ::= AND <simple_expr> <term2>;
<term2> ::= <>;

// Simple expression types.
// ========================

<simple_expr> ::= NOT <expr>;
<simple_expr> ::= OPEN_PAREN <expr> CLOSE_PAREN;
<simple_expr> ::= <property_name> <leading_ident_expr> <finalize>;
<simple_expr> ::= VARIANT <rel_operator> <trailing_prop_expr> <finalize>;

<trailing_prop_expr> ::=  <property_name> <trailing_prop_expr2>;
<trailing_prop_expr2> ::= OPEN_PAREN <property_name> CLOSE_PAREN;
<trailing_prop_expr2> ::= <>;

<leading_ident_expr> ::= OPEN_PAREN <unknown_func_expr>;
<leading_ident_expr> ::= <comp_operator> <trailing_const_expr>;
<leading_ident_expr> ::= <equiv_operator> <trailing_or_null>;
<leading_ident_expr> ::= <is_operator> NULL;

<unknown_func_expr> ::= <property_name> CLOSE_PAREN <rel_operator> <trailing_const_expr>;
<unknown_func_expr> ::= <typed_constant> CLOSE_PAREN <rel_operator> <trailing_prop_expr>;

<trailing_or_null> ::= NULL;
<trailing_or_null> ::= <trailing_const_expr>;

<trailing_const_expr> ::= <typed_constant>;
<trailing_const_expr> ::= <property_name> OPEN_PAREN <typed_constant> CLOSE_PAREN;

<typed_constant> ::= VARIANT; // VT_R8, VT_I4, VT_BSTR
<typed_constant> ::= TRUE; 
<typed_constant> ::= FALSE; 

<finalize> ::= <>; 
    // This is just a semantic production in the parser to allow
    // all the important code to be located in one place.

<rel_operator> ::= <equiv_operator>;
<rel_operator> ::= <comp_operator>;

<equiv_operator> ::= EQUIVALENT_OPERATOR; // =, !=
<comp_operator> ::=  COMPARE_OPERATOR;  // <=, >=, <, >, like
<is_operator> ::=  ISNOT_OPERATOR;  // IS, IS NOT


<opt_aggregation> ::= <>;
<opt_aggregation> ::= GROUP <aggregation_params> <opt_having>;
<aggregation_params> ::= <aggregate_by> <opt_aggregate_within>;
<aggregation_params> ::= <aggregate_within> <opt_aggregate_by>;

<opt_aggregate_by> ::= <>;
<opt_aggregate_by> ::= BY <aggregate_by>;

<opt_aggregate_within> ::= <>;
<opt_aggregate_within> ::= WITHIN <aggregate_within>;

<aggregate_within> ::= <duration>;
<aggregate_by> ::= <aggregate_prop_list>;

<aggregate_prop_list> ::= <prop_list>;

<opt_having> ::= <>;
<opt_having> ::= HAVING <expr>;