首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用兆赫秒解析多行?很多。许多人撞上了太空泄漏

如何用兆赫秒解析多行?很多。许多人撞上了太空泄漏
EN

Stack Overflow用户
提问于 2021-12-20 18:37:34
回答 1查看 174关注 0票数 1

我想解析一些非常简单的文本,例如,将"abcxyzzzz\nhello\n"解析为["abcxyzzz", "hello"] :: String

而不是寻找一个更简单的函数来完成这个任务(比如words),因为我需要解析一些更复杂的东西,我只是在这里打下基础。

代码语言:javascript
运行
复制
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}

module RgParse where

import Data.Text (Text)
import Text.Megaparsec
import Text.Megaparsec.Char


data SimpleData = SimpleData String deriving (Eq, Show, Ord)
data SimpleData' = SimpleData' [String] deriving (Eq, Show, Ord)

instance ShowErrorComponent SimpleData where
  showErrorComponent = show

instance ShowErrorComponent String where
  showErrorComponent = show



simple :: Parsec String Text SimpleData
simple = do
  x <- many (noneOf (Just '\n'))
  pure $ SimpleData x

simple' :: Parsec String Text SimpleData'
simple' = do
  x <- many (many (noneOf (Just '\n')))
  pure $ SimpleData' x

example2 :: Text
example2 = "abcxyzzzz\nhello\n"

main :: IO ()
main = do
  print "Simple:"
  case parse simple "<stdin>" example2 of
    Left bundle -> putStr (errorBundlePretty bundle)
    Right result -> print result
  print "Simple':"
  case parse simple' "<stdin>" example2 of
    Left bundle -> putStr (errorBundlePretty bundle)
    Right result -> print result
  print "done.."

不幸的是,当输入simple'时,在输出以下内容时,会遇到无限循环/空间泄漏:

代码语言:javascript
运行
复制
Hello, Haskell!
[]
"Simple:"
SimpleData "abcxyzzzz"
"Simple':"

使用兆赫秒-7.0.5(不是最新的9.x.x)。

有可能有一种更简单的方法来获得多行?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-20 19:00:57

仅将many应用于使用至少一个令牌(此处为一个Char)或失败的解析器。这是因为many通过运行其参数来工作,直到失败为止。many x可能会消耗零令牌,因此many (many x)违反了这一要求。

请注意,一行至少应该包含一个终止换行符。这样才能满足这一要求。

代码语言:javascript
运行
复制
oneline :: Parsec String Text String
oneline = many (noneOf (Just '\n')) <* single '\n'

manylines :: Parsec String Text [String]
manylines = many oneline

simple :: Parsec String Text SimpleData
simple = do
  x <- oneline
  pure $ SimpleData x

simple' :: Parsec String Text SimpleData'
simple' = do
  x <- manylines
  pure $ SimpleData' x

many p的一个更宽松的要求是,任何对p的重复都必须在有限的迭代之后失败(在这里,p = many x从未失败),因此p在某些步骤中可能不会消耗任何东西,但是它必须是有状态的,以便在一些重复之后,它最终会消耗一些东西或失败。但在实践中,上述近似是一个很好的经验法则。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70426519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档