我正在用Parsec编写我的第一个程序。下面的代码展示了我用来解析"create“或"CREATE”的方法。有没有更好的方法来做这件事?不求助于buildExpressionParser的答案将是最好的。我在这里迈出了一小步。
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发布于 2012-10-18 00:24:41
您可以在字符解析器之外构建不区分大小写的解析器。
-- 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 ++ "\""发布于 2012-10-17 23:43:37
重复我在评论中说的话,因为这显然是有帮助的:
这里的简单大锤解决方案是在运行解析器之前简单地将toLower映射到整个输入上,然后以小写进行所有的关键字匹配。
例如,尽管HTML标签不区分大小写,但在解析整个网页时将其转换为小写可能是不可取的。
发布于 2015-09-26 01:12:14
不,Parsec不能以干净的方式做到这一点。string是在原始tokens组合器之上实现的,该组合器被硬编码为使用相等性测试(==)。解析不区分大小写的字符要简单一些,但是您可能需要更多。
然而,Parsec有一个现代的分支,称为Megaparsec,它有内置的解决方案,可以满足您的所有需求:
λ> parseTest (char' 'a') "b"
parse error at line 1, column 1:
unexpected 'b'
expecting 'A' or 'a'
λ> parseTest (string' "foo") "Foo"
"Foo"
λ> parseTest (string' "foo") "FOO"
"FOO"
λ> parseTest (string' "foo") "fo!"
parse error at line 1, column 1:
unexpected "fo!"
expecting "foo"注意最后一条错误消息,它比一个接一个地解析字符要好(在您的特定情况下特别有用)。string'的实现就像Parsec的string一样,但是使用不区分大小写的比较来比较字符。还有一些oneOf'和noneOf'在某些情况下可能会有帮助。
披露:我是Megaparsec的作者之一。
https://stackoverflow.com/questions/12937325
复制相似问题