【发布时间】:2012-06-27 09:50:43
【问题描述】:
如何翻译这段 Haskell 代码:
import Text.ParserCombinators.Parsec((<|>), unexpected, lookAhead, noneOf, char)
import Control.Monad(when)
data BracketElement = BEChar Char | BEChars String | BEColl String | BEEquiv String | BEClass String
p_set_elem_char = do
c <- noneOf "]"
when (c == '-') $ do
atEnd <- (lookAhead (char ']') >> return True) <|> (return False)
when (not atEnd) (unexpected "A dash is in the wrong place in a bracket")
return (BEChar c)
到 FParsec ?最好的方法是不使用单子语法来提供良好的性能。
提前致谢,亚历山大。
抱歉有点误导。我稍微纠正了问题以使 Haskell 代码可编译:
import Text.ParserCombinators.Parsec((<|>), (<?>), unexpected, lookAhead, noneOf, char)
import Control.Monad(when)
import Data.Functor.Identity
import qualified Text.Parsec.Prim as PR
-- | BracketElement is internal to this module
data BracketElement = BEChar Char | BEChars String | BEColl String | BEEquiv String | BEClass String
deriving Show
p_set_elem_char :: PR.ParsecT [Char] u Identity BracketElement
p_set_elem_char = do
c <- noneOf "]"
when (c == '-') $ do
atEnd <- (lookAhead (char ']') >> return True) <|> (return False)
when (not atEnd) (unexpected "A dash is in the wrong place in a bracket")
return (BEChar c)
现在可以重现 *p_set_elem_char* 计算。
我衷心感谢所有帮助过我的人。
我做了自己的近似,但不幸的是,它的功能并没有达到应有的水平:
type BracketElement = BEChar of char
| BEChars of string
| BEColl of string
| BEEquiv of string
| BEClass of string
let p_set_elem_char : Parser<BracketElement, _> =
fun stream ->
let stateTag = stream.StateTag
let reply = (noneOf "]") stream
let chr = reply.Result
let mutable reply2 = Reply(BEChar chr)
if reply.Status = Error && stateTag = stream.StateTag then
reply2.Status <- Error
reply2.Error <- reply.Error
else if chr = '-' && stream.Peek() <> ']' then
reply2.Status <- Error
reply2.Error <- messageError ("A dash is in the wrong place in a bracket")
reply2
【问题讨论】:
-
您至少尝试过自己做这件事吗?
-
请尝试一下,并向我们提供您建议的代码并解释为什么它不符合您的期望。
-
是的,但我是新手,所以我得到了一些涂鸦。我像狗一样阅读 FParsec 的资料:完全了解所有内容,但不能说什么。主动和被动词典之间的差距:)
-
哦,我的.. 看起来它会运行得很快。请注意 - 如果速度对您来说很重要,为什么还要使用 FParsec?手动编写的解析器将为您提供最高速度。
-
您的代码看起来不错,但您不应该为如此琐碎的事情使用低级 API。