The problem's not solved! Check out this weirdness. |+| and |-| are supposed to be identical, mapping to the same function, the Pair constructor.> mapM_ putStrLn exprsa |+| ba |-| ba |+| b |-| ca |-| b |+| ca |+| b |-| c |+| d> mapM_ putStrLn $ map (show . parseMaybe aExpr) exprsJust (Pair (Var "a") (Var "b"))NothingJust (Pair (Pair (Var "a") (Var "b")) (Var "c"))NothingJust (Pair (Pair (Var "a") (Var "b")) (Pair (Var "c") (Var "d")))Why the two failures?If I change them from InfixN to InfixR or InfixL, then only the first of those five expressions parses.Here are two relevant definitions:data AExpr = Var String | Pair AExpr AExpr deriving (Show)aOperators :: [[Operator Parser AExpr]]aOperators =[ [ InfixN $ symbol "|+|" *> pure (Pair) ], [ InfixN $ symbol "|-|" *> pure (Pair) ] -- binds last, I think]And here is the code in full[1].Thanks,Jeff[1] https://github.com/JeffreyBenjaminBrown/digraphs- with-text/blob/master/howto/ megaparsec/minimal.hs On Sun, Oct 23, 2016 at 2:50 PM, Brandon Allbery <allbery.b@gmail.com> wrote:Aha. I had forgotten some details.If you want to have an operator that is a prefix of another operator in the table, use the following (or similar) wrapper instead of plainsymbol
:
op n = (lexeme . try) (string n <* notFollowedBy punctuationChar)So you actually need to be a little clever for those two operators to work; it's not as simple as I had recalled it (which would have been correct for a basic manual combinator setup). I am going to guess that something in there is not using `try` and silently consuming the extra "#", but I'd have to study the `makeExprParser` code in Megaparsec to be certain.On Sun, Oct 23, 2016 at 5:38 PM, Jeffrey Brown <jeffbrown.the@gmail.com> wrote:Thanks, Brandon! How did you know that?I changed them to "#1" and "#2" and now it works[1].But before making that change, why would "a # b ## c # d" evaluate, even though "a ## b" would not?The corrected file is called "experim.hs"; the old one, uncorrected, is called "experim.buggy.hs".--On Sun, Oct 23, 2016 at 2:03 PM, Brandon Allbery <allbery.b@gmail.com> wrote:On Sun, Oct 23, 2016 at 4:15 PM, Jeffrey Brown <jeffbrown.the@gmail.com> wrote:[ [ InfixN # symbol "#" *> pure (Pair) ], [ InfixN # symbol "##" *> pure (Pair) ]]Combinator parsers can't rearrange themselves to do longest token matching. So the ## operator will take the first case, match against `symbol "#"` and aOperator will succeed; the the next token match will hit the unconsumed "#" and fail. If you place "##" first then it will match "##" but not "#", which would the match the second rule.--brandon s allbery kf8nh sine nomine associatesunix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
--brandon s allbery kf8nh sine nomine associatesunix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net--
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell- cafe
Only members subscribed via the mailman list are allowed to post.