Parsing Parsec解析器工作正常,但它能做得更好吗?

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

我尝试这样做:

以以下形式分析文本:

一些文本#{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
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
本身。