首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Megaparsec:将注释语法转换为记录

Megaparsec:将注释语法转换为记录
EN

Stack Overflow用户
提问于 2022-11-02 10:02:43
回答 1查看 60关注 0票数 0

如果我想要将包含表单~{content}注释的字符串解析为Comment记录,那么我将如何处理?例如:

代码语言:javascript
复制
data Comment = { id :: Integer, content :: String }

parse :: Parser [Comment]
parse = _

parse
  "hello world ~{1-sometext} bla bla ~{2-another comment}" 
  == [Comment { id = 1, content = "sometext" }, Comment { id = 2, content = "another comment"}]

我所坚持的是允许忽略所有非~{}的内容,包括单独的char ~和唯一的方括号{}

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-02 16:34:34

您可以这样做:将字符拖到下一个倾斜点,然后可选地解析该倾斜符,后面跟着一个有效的注释,然后循环。

特别是,如果我们将nonTildes定义为丢弃非倾斜体:

代码语言:javascript
复制
nonTildes :: Parser String
nonTildes = takeWhileP (Just "non-tilde") (/= '~')

然后是一个optionalComment,用于在大括号中解析一个倾斜的和可选的注释:

代码语言:javascript
复制
optionalComment :: Parser (Maybe Comment)
optionalComment = char '~' *>
  optional (braces (Comment <$> ident_ <* char '-' <*> content_))
  where
    braces = between (char '{') (char '}')
    ident_ = read <$> takeWhile1P (Just "digit") isDigit
    content_ = takeWhileP Nothing (/= '}')

然后,这些注释可以用以下内容进行解析:

代码语言:javascript
复制
comments :: Parser [Comment]
comments = catMaybes <$> (nonTildes *> many (optionalComment <* nonTildes))

这假设没有匹配的~{是一个解析错误,而不是有效的非注释文本,这似乎是明智的。但是,content_解析器的定义可能过于宽松。它吞噬了所有的东西,直到下一个},这意味着:

代码语言:javascript
复制
"~{1-{{{\n}"

是带有内容"{{{\n"的有效注释。在注释中不允许{ (或者~),或者要求大括号正确地嵌套在注释中似乎是个好主意。

总之,这里有一个完整的代码示例供您使用:

代码语言:javascript
复制
{-# OPTIONS_GHC -Wall #-}

import Data.Char
import Data.Maybe
import Data.Void
import Text.Megaparsec
import Text.Megaparsec.Char

type Parser = Parsec Void String

data Comment = Comment { ident :: Integer, content :: String } deriving (Show)

nonTildes :: Parser String
nonTildes = takeWhileP (Just "non-tilde") (/= '~')

optionalComment :: Parser (Maybe Comment)
optionalComment = char '~' *>
  optional (braces (Comment <$> ident_ <* char '-' <*> content_))
  where
    braces = between (char '{') (char '}')
    ident_ = read <$> takeWhile1P (Just "digit") isDigit
    content_ = takeWhileP Nothing (/= '}')

comments :: Parser [Comment]
comments = catMaybes <$> (nonTildes *> many (optionalComment <* nonTildes))

main :: IO ()
main = do
  parseTest comments "hello world ~{1-sometext} bla bla ~{2-another comment}"
  parseTest comments "~~~ ~~~{1-sometext} {junk}"
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74287406

复制
相关文章

相似问题

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