Parsing Parsec解析器工作正常,但它能做得更好吗?
我尝试这样做: 以以下形式分析文本: 一些文本#{0,0,0}一些文本#{0,0,0}{0,0,0}更多文本#{0,0,0} 进入某些数据结构的列表: [在“某些文本”内部、外部(0,0,0)、内部“某些文本”、外部(0,0,0)、外部(0,0,0)、内部“更多文本”、外部(0,0,0)] 所以这些#{a,b,c}位应该和文本的其余部分一样变成不同的东西 我有以下代码:Parsing Parsec解析器工作正常,但它能做得更好吗?,parsing,haskell,parsec,Parsing,Haskell,Parsec,我尝试这样做: 以以下形式分析文本: 一些文本#{0,0,0}一些文本#{0,0,0}{0,0,0}更多文本#{0,0,0} 进入某些数据结构的列表: [在“某些文本”内部、外部(0,0,0)、内部“某些文本”、外部(0,0,0)、外部(0,0,0)、内部“更多文本”、外部(0,0,0)] 所以这些#{a,b,c}位应该和文本的其余部分一样变成不同的东西 我有以下代码: module ParsecTest where import Text.ParserCombinators.Parsec i
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) }
模块解析测试,其中
导入Text.ParserCombinators.Parsec
导入单子
类型引用=(Int,Int,Int)
数据传输=内部字符串|外部引用
派生(显示)
text::Parser Transc
text=do
x>返回(在“”内);
返回(x内)
transc=参考文本
alot::解析器[Transc]
多做
manyTill transc eof
reference::Parser Transc
reference=try(do{char'#';
字符“{”;
a1)我认为您确实需要lookAhead
,因为您需要该解析的结果。通过使用解析器(Transc,可能是Transc)
来指示内部的,以及可选的外部的,可以避免运行该解析器两次。如果性能是一个问题,那么这是值得做的
2) 对
3) Applicative
s
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
number2::解析器Int
number2=读取多个1位数
text2::解析器Transc
text2=(内部。)(:)
阿尼查尔
manyTill anyChar(try(lookAhead reference2)*>pure()eof)
reference2::解析器Transc
参考2=((外部)。(,)
(字符串“#{”*>number2 number2谢谢。很不幸,您的版本产生了一个错误,最初导致了“text”中的丑陋破解。它甚至在字符串“some”上也会失败。这就是我被迫将“eof”-检查放入“text”-解析器中的原因,并且里面是空的“”出于打字的目的,我很抱歉!我原以为try
会处理eof
本身。