Search code examples
haskellparsec

What's the cleanest way to do case-insensitive parsing with Text.Combinators.Parsec?


I'm writing my first program with Parsec. I want to parse MySQL schema dumps and would like to come up with a nice way to parse strings representing certain keywords in case-insensitive fashion. Here is some code showing the approach I'm using to parse "CREATE" or "create". Is there a better way to do this? An answer that doesn't resort to buildExpressionParser would be best. I'm taking baby steps here.

  p_create_t :: GenParser Char st Statement
  p_create_t = do
      x <- (string "CREATE" <|> string "create")
      xs <- manyTill anyChar (char ';')
      return $ CreateTable (x ++ xs) []  -- refine later

Solution

  • You can build the case-insensitive parser out of character parsers.

    -- Match the lowercase or uppercase form of 'c'
    caseInsensitiveChar c = char (toLower c) <|> char (toUpper c)
    
    -- Match the string 's', accepting either lowercase or uppercase form of each character 
    caseInsensitiveString s = try (mapM caseInsensitiveChar s) <?> "\"" ++ s ++ "\""