haskell - Parsec parser: Custom fail is not evaluated in certain conditions -


i'm starting learn parsing strings parsec, , i'm faced following problem can't wrap mind around:

the following code contains 3 parser runs, 2 of fail. strange thing custom failure message occur second run, not third.

import text.parsec import text.parsec.string  ps :: parser string ps = (string "123") <|> (string "456") <|> fail "my-failure"  main =      putstrln $ "a: " ++ show (parse ps "" "123")      putstrln $ "\nb: " ++ show (parse ps "" "789")      putstrln $ "\nc: " ++ show (parse ps "" "45x") 

output:

a: right "123"  b: left (line 1, column 1): unexpected "7" expecting "123" or "456" my-failure  c: left (line 1, column 1): unexpected "x" expecting "456" 

what correct way have failure message occur always when part left of second <|> fails? can override occured error?

the <|> combinator in parsec tries next option when parser doesn't consume input. in case, parser string "456" matches beginning of "45x", no further alternatives tried. if need arbitrary look-ahead, need use try function.

ps :: parser string ps = string "123" <|> try (string "456") <|> fail "my-failure" 

from parsec's documentation of <|>:

this combinator implements choice. parser p <|> q first applies p. if succeeds, value of p returned. if p fails without consuming input, parser q tried. combinator defined equal mplus member of monadplus class , (<|>) member of alternative.

the parser called predictive since q tried when parser p didn't consume input (i.e.. ahead 1). non-backtracking behaviour allows both efficient implementation of parser combinators , generation of error messages.


Comments

Popular posts from this blog

get url and add instance to a model with prefilled foreign key :django admin -

css - Make div keyboard-scrollable in jQuery Mobile? -

ruby on rails - Seeing duplicate requests handled with Unicorn -