How to parse SQL operators using FParsec

37 Views Asked by At

I'm parsing SQL expressions and have been looking at this example. So far I'm focused on boolean operators like AND, OR, NOT, IN and NOT IN. The first four seem easy to implement, however I'm not sure what to do with NOT IN:

type BinaryExpr = {left: SqlExpr; right: SqlExpr}
and SqlExpr = 
    And of BinaryExpr 
    | Or of BinaryExpr 
    | Not of SqlExpr 
    | In of BinaryExpr 
    | NotIn of BinaryExpr
    | Identifier of string

let parser =
    let opp = OperatorPrecedenceParser<SqlExpr, unit, unit>()
    let ws = spaces
    let ws1 = nextCharSatisfiesNot isLetter >>. ws
    let expr = opp.ExpressionParser
    
    opp.TermParser <- identifier <|> expr
    let buildAnd x y = And { left = x; right = y }
    let buildOr x y = Or { left = x; right = y }
    let buildIn x y = In { left = x; right = y }
    let buildNotIn x y = NotIn { left = x; right = y }
    opp.AddOperator(InfixOperator("OR", ws1, 1, Associativity.Left, buildOr))
    opp.AddOperator(InfixOperator("AND", ws1, 2, Associativity.Left, buildAnd))
    opp.AddOperator(PrefixOperator("NOT", ws1, 3, false, Not))
    opp.AddOperator(InfixOperator("IN", ws1, 4, Associativity.None, buildIn))
    opp.AddOperator(InfixOperator("NOT IN", ws1, 4, Associativity.None, buildNotIn))
    
    ws >>. expr .>> eof

What I want is:

  • Handle more than one space between "NOT" and "IN"
  • Parse "NOT IN" as a binary operator

Currently I'm failing in the first point.

I'm assuming that NOT IN is semantically a binary operator and because of that I have created the NotIn type variant.

0

There are 0 best solutions below