gpt4 book ai didi

parsing - Parsec-Parser 工作正常,但可以做得更好吗?

转载 作者:行者123 更新时间:2023-12-03 22:56:14 25 4
gpt4 key购买 nike

我尝试这样做:

解析格式中的文本:

Some Text #{0,0,0} some Text #{0,0,0}#{0,0,0} more Text #{0,0,0}



进入一些数据结构的列表:

[Inside "Some Text ",Outside (0,0,0),Inside " some Text ",Outside (0,0,0),Outside (0,0,0),Inside " more Text ",Outside (0,0,0)]



所以这些#{a,b,c} 位应该变成与文本其余部分不同的东西。

我有这个代码:
module ParsecTest where

import Text.ParserCombinators.Parsec
import Monad

type Reference = (Int, Int, Int)

data Transc = Inside String | Outside Reference
deriving (Show)

text :: Parser Transc
text = do
x <- manyTill anyChar ((lookAhead reference) <|> (eof >> return (Inside "")));
return (Inside x)

transc = reference <|> text

alot :: Parser [Transc]
alot = do
manyTill transc eof

reference :: Parser Transc
reference = try (do{ char '#';
char '{';
a <- number;
char ',';
b <- number;
char ',';
c <- number;
char '}';
return (Outside (a,b,c)) })

number :: Parser Int
number = do{ x <- many1 digit;
return (read x) }

这按预期工作。您可以通过键入在 ghci 中进行测试

parseTest alot "Some Text #{0,0,0} some Text #{0,0,0}#{0,0,0} more Text #{0,0,0}"



但是我觉得不好看。

1) 是否使用 lookAhead我的问题真的有必要吗?

2) 是 return (Inside "")一个丑陋的黑客?

3)通常有更简洁/更智能的方式来归档吗?

最佳答案

1) 我认为你确实需要 lookAhead因为您需要该解析的结果。通过 Parser (Transc,Maybe Transc) 避免运行该解析器两次会很好表示 Inside带有可选的关注 Outside .如果性能是一个问题,那么这是值得做的。

2) 是的。

3) Applicative

number2 :: Parser Int
number2 = read <$> many1 digit

text2 :: Parser Transc
text2 = (Inside .) . (:)
<$> anyChar
<*> manyTill anyChar (try (lookAhead reference2) *> pure () <|> eof)


reference2 :: Parser Transc
reference2 = ((Outside .) .) . (,,)
<$> (string "#{" *> number2 <* char ',')
<*> number2
<*> (char ',' *> number2 <* char '}')

transc2 = reference2 <|> text2

alot2 = many transc2

你可能想重写 reference2 的开头使用像 aux x y z = Outside (x,y,z) 这样的助手.

编辑:更改 text处理不以 Outside 结尾的输入.

关于parsing - Parsec-Parser 工作正常,但可以做得更好吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7852484/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com