I am new to Haskell, Parsec and I write parsers in general. I am trying to parse a simple language which (simplifying it further for this question) consists simply of lines of nested brackets, for example. [[][]][].
I have the Haskell code below that works great. However, I would like to expand it so that the inconsistent brackets match the end of the line. So, for example, it ]][][[should be equivalent [[]][][[]], but it []]should be equivalent [[]]. Doing this for open brackets corresponding to the end of a line is easy, but for closed brackets corresponding to the beginning of a line, you get left recursion and infinite loops, and I have not found a way to solve this problem. I'm not sure if this is due to the way I think about grammar or the way I use the Parsec library, but in any case, I would appreciate being shown the way forward.
Here is the working code that I have:
{-
import qualified Text.Parsec as Parsec
import Control.Applicative
-- for testing
parse rule text = Parsec.parse rule "(source)" text
data Expr = Brackets [Expr]
deriving(Show)
openBracket = Parsec.char '['
closeBracket = Parsec.char ']'
parseBrackets = do
expr <- Parsec.between openBracket closeBracket parseExpr
return $ Brackets expr
parseExpr = Parsec.many parseBrackets
If I want the closed brackets to match the end of the line, I can just change the definition closeBracketto
closeBracket = (Parsec.char ']' >> return ()) <|> Parsec.eof
, , ] . , Parsec chainl1, , -, , .