36

を使用するParsec 3.1と、いくつかのタイプの入力を解析できます。

  • [Char]Text.Parsec.String
  • Data.ByteStringText.Parsec.ByteString
  • Data.ByteString.LazyText.Parsec.ByteString.Lazy

Data.Textモジュールには何も表示されません。String非効率性に苦しむことなく、Unicode コンテンツを解析したいと考えています。したがって、モジュールに基づいて次のモジュールを作成しましたText.Parsec.ByteString

{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

module Text.Parsec.Text
    ( Parser, GenParser
    ) where

import Text.Parsec.Prim

import qualified Data.Text as T

instance (Monad m) => Stream T.Text m Char where
    uncons = return . T.uncons

type Parser = Parsec T.Text ()
type GenParser t st = Parsec T.Text st
  1. そうするのは理にかなっていますか?
  2. これは、Parsec API の残りの部分と互換性がありますか?

追加コメント:

{-# LANGUAGE NoMonomorphismRestriction #-}機能させるには、解析モジュールにプラグマを追加する必要がありました。

構文解析Textと AST の構築Textは別物です。packまた、String返品前に次のことを行う必要があります。

module TestText where

import Data.Text as T

import Text.Parsec
import Text.Parsec.Prim
import Text.Parsec.Text

input = T.pack "xxxxxxxxxxxxxxyyyyxxxxxxxxxp"

parser = do
  x1 <- many1 (char 'x')
  y <- many1 (char 'y')
  x2 <- many1 (char 'x')
  return (T.pack x1, T.pack y, T.pack x2)

test = runParser parser () "test" input
4

3 に答える 3

22

Parsec 3.1.2 以降、Data.Text のサポートが組み込まれています! http://hackage.haskell.org/package/parsec-3.1.2を参照

古いバージョンで立ち往生している場合は、他の回答のコード スニペットも役立ちます。

于 2012-02-10T13:09:01.427 に答える
10

That looks like exactly what you need to do.

It should be compatible with the rest of Parsec, include the Parsec.Char parsers.

If you're using Cabal to build your program, please put an upper bound of parsec-3.1 in your package description, in case the maintainer decides to include that instance in a future version of Parsec.

于 2010-10-31T20:42:56.833 に答える
5

parseFromUtf8FileUTF-8 でエンコードされたファイルを効率的に読み取るための機能を追加しました。ウムラウト文字で問題なく動作します。関数型は から一致parseFromFileText.Parsec.ByteStringます。このバージョンは厳密な ByteStrings を使用します。

-- A derivate work from
-- http://stackoverflow.com/questions/4064532/using-parsec-with-data-text

{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

module Text.Parsec.Text
    ( Parser, GenParser, parseFromUtf8File
    ) where

import Text.Parsec.Prim
import qualified Data.Text as T
import qualified Data.ByteString as B
import Data.Text.Encoding
import Text.Parsec.Error

instance (Monad m) => Stream T.Text m Char where
    uncons = return . T.uncons

type Parser = Parsec T.Text ()
type GenParser t st = Parsec T.Text st

-- | @parseFromUtf8File p filePath@ runs a strict bytestring parser
-- @p@ on the input read from @filePath@ using
-- 'ByteString.readFile'. Returns either a 'ParseError' ('Left') or a
-- value of type @a@ ('Right').
--
-- >  main    = do{ result <- parseFromFile numbers "digits.txt"
-- >              ; case result of
-- >                  Left err  -> print err
-- >                  Right xs  -> print (sum xs)
-- >              }
parseFromUtf8File :: Parser a -> String -> IO (Either ParseError a)
parseFromUtf8File p fname = do 
  raw <- B.readFile fname
  let input = decodeUtf8 raw
  return (runP p () fname input)
于 2010-12-09T20:00:58.847 に答える