2

全部,

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

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

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

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

进入:

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

谢谢

编辑:

**为简洁起见省略**

编辑2:

我根据您的建议进行了一些构建,现在遇到以下问题 Runningparse 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
4

1 回答 1

2

如果我们需要解析一些选择,你可以使用choicefromText.ParserCombinators.Parsec.Combinator

choice [parseInvocation, parseAssignmen]

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

附言

你可以使用形式Text.ParserCombinators.Parsec.Char

many (oneOf " ") == spaces

oneOf " " == space
于 2013-10-07T15:23:01.517 回答