Parsec:一行有多个可能的选项

时间:2013-10-07 14:12:56

标签: haskell parsec

所有

我正在尝试使用parsec编写解析器。目标是最终能够解析玩具语言。

现在我正努力让parsec识别两种不同的可能选项,例如赋值和函数调用。

如何编写“parseCode”函数来解析以下内容:

x = 3
y = 4
plus(x,y)

成:

(Assignment "x" "3")
(Assignment "y" "4")
(Invocation "plus" ["x","y"])

由于

编辑:

**为简洁而省略**

编辑2:

我建立了一些你的建议,现在有以下问题 运行parse parseTester "bla" "{plus(3,4)\nmin(2,3)\nx=3\n"会提供预期的解决方案:Right (Body [Invocation "plus",Invocation "min",Assignment "x" "3"])

但是运行功能(几乎)等效的parse parseBody "bla" "{plus(3,4)\nmin(2,3)\nx=3\n}"会导致错误:

Left "bla" (line 4, column 2):
unexpected end of input
expecting white space or "="

我没有看到问题。解析器是否突然寻找应该在哪里寻找调用的赋值?有什么建议吗?

代码:

data Body = Body [Statement]
    deriving (Show)

data Arguments = Arguments [String]
    deriving (Show)

data Statement = Assignment String String
               | Invocation String
    deriving (Show)


parseBody :: Parser Body
parseBody = do
    char '{'
    statements <- many1 parseStatement
    char '}'
    return $ Body statements

parseTester :: Parser Body
parseTester = do 
    char '{'
    x <- many1 parseStatement
    return $ Body x

parseStatement :: Parser Statement
parseStatement = do
        x <- try parseInvocation <|> parseAssignment <?> "statement"
        return x

parseInvocation :: Parser Statement
parseInvocation = do
    spaces
    name <- many1 (noneOf " (")
    spaces
    char '('
    spaces
    bla <- many1 (noneOf " )")
    spaces
    char ')'
    char '\n'
    return $ Invocation name

parseAssignment :: Parser Statement
parseAssignment = do
    spaces
    var <- many1 (noneOf " =")
    spaces
    char '=' <?> "equal in assignment"
    spaces
    value <- many1 (noneOf "\n")
    char '\n'
    spaces
    return $ Assignment var value

1 个答案:

答案 0 :(得分:2)

如果我们需要解析一些选项,您可以使用choice中的Text.ParserCombinators.Parsec.Combinator

choice [parseInvocation, parseAssignmen]

或更简单:try parseInvocation <|> try parseAssignmen

P.S。

您可以使用表单Text.ParserCombinators.Parsec.Char

many (oneOf " ") == spaces

oneOf " " == space