我想为允许文件包含的简单语言实现一个Parsec解析器。也就是说,语言是这样的:
include otherfile;
expression in the language;
如果解析了inclusion,我希望读取具有此名称的文件,并将解析后的内容嵌入到父结构中。
因为我必须读取文件,所以解析器需要打包在IO中。我猜测ParsecT s u m a中的底层monad u可以用来做这件事。然而,这导致了语言定义的相当大的变化,因为LanguageDef依赖于Identity作为底层的单体。
我的方法合理吗?有没有其他方法可以在解析器中包含文件,例如,扩展输入流?
我正在创建一种用于交互式约会争论的简单语言。我想有一个代表“今天”的规则:
import Data.Time
import qualified Text.Parsec as Parsec
import Text.Parsec.String(Parser)
data Date = Date { year :: Int
, month :: Int
, day :: Int
}
parseToday :: Parser Date
parseToday = do
Parsec.stri
我使用的许多Parsec组合器都属于一种类型,例如:
foo :: CharParser st Foo
CharParser被定义为:
type CharParser st = GenParser Char st
因此,CharParser是一个涉及GenParser的类型同义词,它本身将定义为:
type GenParser tok st = Parsec [tok] st
然后,GenParser是另一种类型的同义词,使用Parsec指定,将定义为:
type Parsec s u = ParsecT s u Identity
因此,Parsec是ParsecT的部分应用程序,它本身列出的
假设我只想创建我自己的解析器,这与Parsec中的char完全相同,但是当我运行时
import Text.Parsec
char1 c = char c
它给了我
? Non type-variable argument in the constraint: Stream s m Char
(Use FlexibleContexts to permit this)
? When checking the inferred type
char1 :: forall s (m :: * -> *) u.
Stream s m Char =>
如果我有这个密码:
import Text.Parsec
ispositive a = if (a<0) then Nothing else (Just a)
f a b = a+b
parserfrommaybe :: String -> (Maybe c) -> Parsec a b c
parserfrommaybe msg Nothing = fail msg
parserfrommaybe _ (Just res) = return res
(<!>) :: Parsec a b (Maybe c) -> String -&
下面的BNF定义了一种逻辑语言。
formula ::= true
| false
| var
| formula & formula
| [binder] formula
binder ::= var
| $var
本质上,这允许使用诸如x & true、[x]x和[$x](x & true)之类的公式。语义在这里并不重要;但最重要的是,我在公式前面出现了这些方括号内的表达式,在这些方括号内的表达式中,标识符的前面可能有美元符号($),也可能没有。现
想象下面的例子
data A = ...
data B = ...
data C = ...
convertA :: A -> C
parseA :: Parser A
parseB :: Parser B
parseC :: Parser C
parseC = do
a <- parseA
if parsed? a
then return $ convertA a
else parseB
是否有一种方法可以实现这样的逻辑:我可以尝试使用一个解析器,如果它成功的话,对结果进行一些转换,否则使用另一个解析器?我知道可以编写这个特定的示例,如
parseC
我想用Parsec取代sed和awk。例如,从unknown structure but containing the number 42 and maybe some other stuff这样的字符串中提取数字。
我遇到了“意外的输入结束”。我在寻找相当于非贪婪的.*([0-9]+).*。
module Main where
import Text.Parsec
parser :: Parsec String () Int
parser = do
_ <- many anyToken
x <- read <$> many1 digit
_
使用Parsec,如果违反了语义规则,如何指示特定位置的错误。我知道我们通常不想做这样的事情,但是考虑一下例子语法。
<foo> ::= <bar> | ...
<bar> ::= a positive integer power of two
<bar>规则是一个有限集(我的例子是任意的),对上述问题的纯方法可能是choice组合器的谨慎应用,但这在空间和时间上可能是不切实际的。在递归下降或工具箱生成的解析器中,标准技巧是解析一个整数(一种更宽松的语法),然后在语义上检查更难的约束。对于Parsec,我可以使用一个natural解析器来检查调用
给定Parser库中的parsec,什么是进行流读取(从输入文件)和写入(将解析的blob/行附加到输出文件)的好方法。下面是Text.Parsec.ByteString的一个示例
main = do{ result <- parseFromFile numbers "digits.txt"
; case result of
Left err -> print err
Right xs -> print (sum xs)
}
上面的
我有一个以Text作为流类型编写的解析器,而默认情况下,Text.Parsec.String模块使用String。
如何在Parsec Text b c上下文中使用自定义书面解析器( Parsec String b c )
从本质上说,我似乎需要这样一种功能:
f :: Parsec Text b c -> Parsec String b c
f = undefined
虽然这听起来是可能的,但它似乎是相当复杂的。
我正在使用Parsec,我想将两个解析器合并为一个解析器,并将结果放在一对中,然后向它提供另一个函数来对解析结果进行操作,以编写类似以下内容:
try (pFactor <&> (char '*' *> pTerm) `using` (*))
所以我写了这个:
(<&>) :: (Monad m) => m a -> m b -> m (a, b)
pa <&> pb = do
a <- pa
b <- pb
return (a, b)
和
using :: (Funct
一个人能很容易地获得位置作为偏移(作为字符从输入一开始)与Parsec?如果是这样的话,是怎么做的?在内部,Parsec将位置保持为具有源名称、行和列的数据类型。
我希望能够编写如下解析器
pWithPos p = do left <- getPosition -- gets the current position as an offset
x <- p
right <- getPosition -- gets the current position as an offset
我想使用Parsec的令牌和Expr模块来解析以$ (如$a=$b)开头的变量的表达式。下面是我的代码的简化版本:
module Main where
import Control.Monad.Identity
import Control.Applicative
import Text.Parsec
import Text.Parsec.String
import qualified Text.Parsec.Token as Tok
import qualified Text.Parsec.Language as Tok
import qualified Text.Parsec.
我开始学习Haskell,并希望为execrsice解析一个PPM映像。PPM格式的结构相当简单,但很棘手。它被描述为。首先,我为PPM映像定义了一个类型:
data Pixel = Pixel { red :: Int, green :: Int, blue :: Int} deriving(Show)
data BitmapFormat = TextualBitmap | BinaryBitmap deriving(Show)
data Header = Header { format :: BitmapFormat
, width :: Int
我试图用关键字之间的一系列数据来解析以下文本文件:
many text many text many text
BEGIN
T LISTE2
1 154
2 321
3 519
4 520
5 529
6 426
END
many text many text many text
通过使用以下haskell程序
import Text.Parsec
import Text.Parsec.String
import Text.Parsec.Char
import Text.Parsec.Combinator
endOfLine :: Parser Str
我有一个以String格式保存游戏状态的文件。此字符串由,分隔的移动列表组成。从这个动作列表中,我必须重建游戏状态。因此,从概念上讲,对于我解析的每一步,我想适当地修改游戏状态,并将此游戏状态传递给下一步的解析。从概念上讲,这等同于在开始时有一个空列表,并且对于每个移动,都包含解析后的移动到该列表。最后,您应该有一个列表,其中包含所有已解析的移动。
我将下面的代码示例作为一个简化版本来解析字母,并将这些字母推送到列表中。我想学习的核心概念是如何拥有一个初始状态,如何在每个解析周期中传递这个状态,并使用parsec返回最终状态。someState最初是空列表。
parseExample :: S