1

我完全不知道还能问什么。我想我在这里需要一般指导。我有这样的事情:

expr = buildExpressionParser table term
    <?> "expression"

term = choice [
    (float >>= return . EDouble)
    , try (natural >>= return . EInteger)
    , try (stringLiteral >>= return . EString)
    , try (reserved "true" >> return (EBool True))
    , try (reserved "false" >> return (EBool False))
    , try assign
    , try ifelse
    , try lambda
    , try array
    , try eseq
    , parens expr
    ]
    <?> "simple expression"

但是,当我测试该解析器时,我大多会遇到问题......就像我尝试解析时

 (a,b) -> "b"

它被lambda解析器接受,但expr解析器讨厌它。有时它甚至完全挂在永恒的规则中。

我已经通读了Write Yourself a Scheme,但它只解析 Scheme 的同源源。

也许我通常在错误的方向思考。

编辑:这里是内部解析器:

assign = do
    i <- identifier
    reservedOp "="
    e <- expr
    return $ EAssign i e

ifelse = do
    reserved "if"
    e <- expr
    reserved "then"
    a <- expr
    reserved "else"
    b <- expr
    return $ EIfElse e a b

lambda = do
    ls <- parens $ commaSep identifier
    reservedOp "->"
    e <- expr
    return $ ELambda ls e

array = (squares $ commaSep expr) >>= return . EArray

eseq = do
    a <- expr
    semi <|> (newline >>= (\x -> return [x]))
    b <- expr
    return $ ESequence a b

table = [
        [binary "*" EMult AssocLeft, binary "/" EDiv AssocLeft, binary "%" EMod AssocLeft ],
        [binary "+" EPlus AssocLeft, binary "-" EMinus   AssocLeft ],
        [binary "~" EConcat AssocLeft],
        [prefixF "not" ENot],
        [binaryF "and" EAnd AssocLeft, binaryF "or" EAnd AssocLeft]
    ]

“讨厌它”是指它告诉我它需要一个整数或一个浮点数。

4

2 回答 2

6
于 2011-05-03T23:22:09.153 回答
4

似乎存在左递归,如果choiceinterm到达,这将导致解析器挂起eseq

expr-> term-> eseq->expr

term (a,b)不会解析为 alambda或 an ,因此array它会落入eseq循环中。

我不明白为什么(a,b) -> "b"不解析为expr,因为choicein 术语lambda在到达eseq. 解析错误中报告的位置是什么?

于 2011-05-04T16:39:48.647 回答