4

This code will read this input "(WEEKEND-SUNDAY)" and then return "SATURDAY" but input "WEEKEND-SUNDAY)" still return "SATURDAY" => this parser ignore last ')'

let pDayOfWeekKeyWords = choice [ 
                          pstring "MONDAY" ;
                          pstring "TUESDAY" ;
                          pstring "WEDNESDAY" ;
                          pstring "THURSDAY" ;
                          pstring "FRIDAY" ;
                          pstring "SATURDAY" ;
                          pstring "SUNDAY" ;
                          pstring "WEEKEND" ;
                          pstring "WEEKDAY" ;
                          pstring "ALL" ] 

let betweenParentheses p =
    between (pstring "(") (pstring ")") p

let opp = new OperatorPrecedenceParser<Set<DayOfWeek>,unit,unit>()
let pExpr = opp.ExpressionParser 
let term = (betweenParentheses pExpr) <|> (pDayOfWeekKeyWords |>> ( fun x -> 
    match x with 
    | "MONDAY" ->  Set.ofList [DayOfWeek.Monday]
    | "TUESDAY" ->  Set.ofList [DayOfWeek.Tuesday]
    | "WEDNESDAY" ->  Set.ofList [DayOfWeek.Wednesday]
    | "THURSDAY" -> Set.ofList [DayOfWeek.Thursday]
    | "FRIDAY" -> Set.ofList [DayOfWeek.Friday]
    | "SATURDAY" -> Set.ofList [DayOfWeek.Saturday]
    | "SUNDAY" -> Set.ofList [DayOfWeek.Sunday]
    | "WEEKDAY" -> Set.ofList [DayOfWeek.Monday ; DayOfWeek.Tuesday ; DayOfWeek.Wednesday;DayOfWeek.Thursday;DayOfWeek.Friday]
    | "WEEKEND" -> Set.ofList [DayOfWeek.Saturday;DayOfWeek.Sunday]
    | "ALL"-> Set.ofList [DayOfWeek.Monday ; DayOfWeek.Tuesday ; DayOfWeek.Wednesday;DayOfWeek.Thursday;DayOfWeek.Friday;DayOfWeek.Saturday;DayOfWeek.Sunday]
    | _ -> failwith "ERROR MESSAGE") )
opp.TermParser <- term 
opp.AddOperator(InfixOperator<Set<DayOfWeek>,unit,unit>("+", skipString "", 1, Associativity.Left, fun x y -> x + y))
opp.AddOperator(InfixOperator<Set<DayOfWeek>,unit,unit>("-", skipString "" , 1, Associativity.Left, fun x y -> x - y))

run

 run pExpr "MONDAY+(WEEKEND-SUNDAY)"

output

 Success: set [Monday; Saturday]

problem is

 run pExpr "MONDAY+WEEKEND-SUNDAY)" or run pExpr "MONDAY)+WEEKEND-SUNDAY"

it still return

 Success: set [Monday; Saturday]

I want it to show Failure: something..

did I miss something? thank you

1 Answers1

2

In your latter two examples pexpr returns after having successfully parsed the input stream up to the unmatched closing parenthesis. So, in the last example the result is actually Success: set [Monday] not Success: set [Monday; Saturday].

You can use the eof parser to force an error if the input stream hasn't been consumed completely:

> run (pExpr .>> eof) "MONDAY)+WEEKEND-SUNDAY"
Error in Ln: 1 Col: 7
MONDAY)+WEEKEND-SUNDAY
      ^
Expecting: end of input or infix operator
Stephan Tolksdorf
  • 3,062
  • 21
  • 28