所有
我正在尝试使用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
答案 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