module SQLiterate

grammar Operator
  include Space
  include Comment
  include Keywords

  rule gen_operator
    symbol_operator
  end

  rule symbol_operator
    sign_ending_operator
    /
    comparison_operator
    /
    nonsign_ending_operator
    /
    ambiguous_operator
    /
    single_char_operator
  end

  rule sign_ending_operator
    b:( r:( basic_op_char !special_op_char )* basic_op_char )? special_op_char
    o:( r:( op_char !(sign_op_char !op_char) )* op_char )? sign_op_char !op_char
    <Node::SignEndingOperator>
  end

  rule nonsign_ending_operator
    !comparison_operator
    r:( op_char !(nonsign_op_char !op_char) )* op_char nonsign_op_char !op_char
    <Node::NonsignEndingOperator>
  end

  rule ambiguous_operator
    !comparison_operator
    r:( op_char !(sign_op_char !op_char) )* op_char
    <Node::AmbiguousOperator>
  end

  rule single_char_operator
    !comparison_operator
    c:op_char <Node::SingleCharOperator>
  end

  rule sign_op_char
    c:[+\-] comment* <Node::OperatorChar>
  end

  rule basic_op_char
    c:[+\-*/<>=] comment* <Node::OperatorChar>
  end

  rule special_op_char
    c:[~!@#%^&|`?] comment* <Node::OperatorChar>
  end

  rule nonsign_op_char
    c:[*/<>=~!@#%^&|`?] comment* <Node::OperatorChar>
  end

  rule op_char
    c:[+\-*/<>=~!@#%^&|`?] comment* <Node::OperatorChar>
  end

  rule comparison_operator
    o:( '>=' / '<=' / '<>' / '!=' / '=' / '>' / '<' ) comment* !nonsign_op_char
    <Node::ComparisonOperator>
  end

  rule binary_test_operator
    is_kw space ( not_kw space )? distinct_kw space from_kw
  end

  rule unary_test_operator
    is_kw space ( not_kw space )? null_kw
    /
    isnull_kw
    /
    notnull_kw
    /
    is_kw space ( not_kw space )? true_kw
    /
    is_kw space ( not_kw space )? false_kw
    /
    is_kw space ( not_kw space )? unknown_kw
  end

  rule set_predicate_operator
    ( not_kw space )? in_kw
    /
    comparison_operator space ( any_kw / some_kw / all_kw )
  end
end

end