- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
下面的代码输出Right ["1<!>2<!>3"]
,但我需要Right ["1", "2", "3"]
.
import Text.ParserCombinators.Parsec
response = contents :: CharParser () [String]
where
contents = sepBy content contentDelimiter
contentDelimiter = string "<!>"
content = many anyChar
main = do
putStrLn $ show $ parse response "Response" "1<!>2<!>3"
我想这里的问题是 content
解析器消耗 sepBy
之前的所有输入开始测试分隔符。所以,我的问题是:
我的假设正确吗?如果不是,我犯了什么错误?
针对此类问题,您会推荐什么解决方案? (使用秒差距)
* content
必须匹配任何不包含分隔符的字符串。 1<!>2<!>3
这只是一个例子,它可以是 dslkf\n><!>dsf<!>3
或其他什么
最佳答案
对于第一个示例,您将替换
content = many anyChar
与
content = many digit
这样内容的解析器就不会错误地匹配分隔符。
也许您想要匹配的不仅仅是数字,但即便如此,我还是建议您仔细考虑 <!>
之间的有效内容。 s 并编写一个解析器来执行此操作。
为什么?
一旦您拥有了一个非常好的内容解析器,您对响应的定义将是完美的。这样您的内容就可以包括mystring = "hello<!>mum"
不被顶级解析器砍断 - 低级 stringLiteral
解析器将吃掉整个 "hello<!>mum"
并且顶级解析器永远不会看到 <!>
正确且无辜地包含在其中。
一般来说,...
在大多数解析情况下,最好真正清楚内容中允许的内容,并仅解析该内容,原因如下:
可重用性很重要。目前,如果您使用仅在 <!>
上进行拆分的解析器并吃掉其他所有东西,它保证吃掉整个输入,并且您将无法再进行任何解析。
自下而上
您的解析器应该从头开始工作 - 您在评论中很好地描述了这一点,即“将解析器从特定到一般堆叠”。
为了便于测试,按照这个顺序编写它们是最简单的,所以首先编写一个与 stringChar
匹配的内容。然后stringLiteral
之前member
之前array
之前object
之前json
之前content
然后response
。您可以让他们一路递归地相互调用。然后您可以使用parseTest
一边做一边测试每一个 child 子;打字parseTest response "1<!>2<!>3"
进入 ghci 比重写 main 和编译更快。
自上而下?
自上而下编写解析器并没有错,只是更难。你可以写
response = many $ content `sepBy` contentSeparator
content = json <|> somethingElse
json = object <|> array
array = ...
但是,除非您编写了最小的解析器,否则没有任何东西是可测试的。
关于haskell - 使用 Parsec 按字符串正确分割,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13431512/
Haskell Parsec 的 indents 包提供了一种解析缩进式语言(如 Haskell 和 Python)的方法。它重新定义了 Parser类型,那么如何使用 Parsec 的 Text.P
我有一个用 Text 编写的解析器作为流类型,而默认为 Text.Parsec.String模块使用 String除此以外。 如何在 Parsec Text b c 的上下文中使用自定义编写的解析器
Text Text.Parsec Text.Parsec.ByteString Text.Parsec.ByteString.Lazy
我在弄清楚如何使用 Text.Parsec.Indent 中的任何功能时遇到问题 indents 提供的模块Haskell 的包,它是 Parsec 的一种附加组件。 所有这些功能有什么作用?它们将如
Text Text.Parsec Text.Parsec.ByteString Text.Parsec.ByteString.Lazy
我目前正在尝试使用现实世界 Haskell 中提供的完整 CSV 解析器。为了我尝试修改代码以使用 ByteString 而不是 String,但是有一个 string 组合器仅适用于 字符串。 是否
我正在尝试解析嵌套的类 C block 注释 import Text.ParserCombinators.Parsec import Control.Monad (liftM) flat :: Mon
如果违反语义规则,使用 Parsec 如何在特定位置指示错误。我知道通常我们不想做这样的事情,但考虑一下示例语法。 ::= | ... ::= a positive integer power
我目前正在尝试使用 Parsec 在 Haskell 中设计一个解析器。声明类型的语法应如下所示: Fruit is a Apple 类型也应该能够有参数: Fruit a b is a Apple
我写了这样的排列解析例子: data Entry = Entry { first_name :: String , last_name :: String , date_of_birt
我正在尝试解析(目前)Dot 语言的一个子集。 语法是here我的代码如下 import System.Environment import System.IO import qualified Te
我有一个列表,我需要解析除最后一个元素之外的所有元素都需要由一个解析器解析,最后一个元素需要由另一个解析器解析。 a = "p1 p1b ... p2" or a = "p2" 原来我试过 parse
我需要为一种编程语言创建一个解析器。到目前为止,它已经完成了 95%,我想说,除了一个小细节。 用这种语言编写的程序具有以下结构: outputs inputs expressions 要求是输出不能
在我的工作中,我遇到了很多粗糙的 sql,我有一个聪明的想法,那就是编写一个程序来解析 sql 并整齐地打印出来。我很快就完成了大部分工作,但遇到了一个我不知道如何解决的问题。 所以让我们假设 sql
我正在编写一种使用 Parsec 进行解析的编程语言。为了报告错误消息,我使用 getPosition 将语法树的每个元素都标记了其源位置。函数来自 the Pos module 秒差距。 但是,它只
我正在尝试使用 parsec 解析如下表达式: f a b c => (Appl (Appl (Appl f a) b) c) 我尝试使用以下内容: appl :: Parser Expr appl
是否有可能以某种方式获得某些自定义类型的解析错误?例如,从错误中获取更多关于解析上下文的信息会很酷。而且仅以短信的形式提供错误信息似乎不太方便。 最佳答案 正如 Rhymoid 所观察到的,不幸的是,
我对 Parsec 的一个常见问题是,如果无效输入出现在“正确”的位置,它往往会忽略它。 作为一个具体的例子,假设我们有 integer :: Parser Int ,我写 expression =
我正在使用 Parsec 解析表达式,并且我想使用 Parsec 中的用户状态来跟踪这些表达式中的变量。不幸的是,我真的不知道该怎么做。 给定以下代码: import Data.Set as Set
我正在尝试编写一个 Haksell Parsec Parser,它将文件中的输入数据解析为 LogLine 数据类型,如下所示: --Final parser that holds the indvi
我是一名优秀的程序员,十分优秀!