xml – 为什么parsecs“选择”组合似乎坚持第一选择?

在查看Real World Haskell中的CSV示例代码之后,我尝试构建一个小的 XML解析器.但是关闭标签错误输出“意外”/“错误”.你能告诉我为什么我的“closeTag”解析器不起作用(或者可能不会被调用)吗?谢谢!
import Text.ParserCombinators.Parsec

xmlFile = manyTill line eof
line = manyTill tag eol
eol = char '\n'

word = many1 (noneOf "></")

tag = choice [openTag,closeTag,nullTag,word]

nullTag = between (char '<') (string "/>") word
closeTag = between (string "</") (char '>') word
openTag = between (char '<') (char '>')  tagContent
attrval = between (char '"') (char '"') word

atts = do {
        (char ' ')
        ; sepBy attr (char ' ')
}

attr = do {
                word
                ; char '='
                ; attrval
        }

tagContent = do {
                w <- word
                ; option []  atts
                ; return w
        }

parseXML :: String -> Either ParseError [[String]]
parseXML input = parse xmlFile "(unknown)" input

main =
    do c <- getContents
       case parse xmlFile "(stdin)" c of
            Left e -> do putStrLn "Error parsing input:"
                         print e
            Right r -> mapM_ print r
Parsec的策略本质上是LL(1),这意味着只要消耗任何输入,它就会“提交”到当前分支.你的openTag解析器使用<使用其char'<',这意味着如果它看到>而不是/,整个解析失败而不是尝试新的选择.如果openTag没有消耗任何输入并且失败,那么将尝试另一种选择. Parsec这样做是为了提高效率(替代方法是指数时间!)和合理的错误消息.

你有两个选择.当合理推出时,首选选项是将语法分解,以便在不消耗输入的情况下进行所有选择,例如:

tag = word <|> (char '<' >> tagbody)
    where
    tagbody = do
        content <- tagcontent
        choice [ string "/>",char '>' ]

Modulo错误和风格(我的大脑现在有点油炸:-P).

另一种方式是,本地更改parsec的语义(以牺牲前面提到的错误消息和效率为代价 – 但它通常不是太糟糕,因为它是本地的),是使用try组合器,它允许解析器使用输入但仍然失败“轻轻地“所以可以尝试另一种选择:

nulltag = try $between (char '<') (string "/>") word
-- etc.

有时使用try比上面的因子更清晰,更容易,这可能会掩盖语言的“深层结构”.这是一种风格权衡.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念
xml文件介绍及使用
xml编程(一)-xml语法
XML文件结构和基本语法
第2章 包装类
XML入门的常见问题(二)
Java对象的强、软、弱和虚引用
JS解析XML文件和XML字符串详解
java中枚举的详细使用介绍
了解Xml格式
XML入门的常见问题(四)
深入SQLite多线程的使用总结详解
PlayFramework完整实现一个APP(一)
XML和YAML的使用方法
XML轻松学习总节篇