Parsing try函数解析lambda表达式
我是Haskell的新手,正在尝试实现一个“Lambda演算”解析器,该解析器将用于读取Lambda reducer的输入。。首先需要从文本文件中解析绑定“identifier=expression;”,然后在最后只有一个表达式。。 到目前为止,它只能解析绑定,并且在单独遇到表达式时显示错误。。当我尝试使用Parsing try函数解析lambda表达式,parsing,haskell,lambda,Parsing,Haskell,Lambda,我是Haskell的新手,正在尝试实现一个“Lambda演算”解析器,该解析器将用于读取Lambda reducer的输入。。首先需要从文本文件中解析绑定“identifier=expression;”,然后在最后只有一个表达式。。 到目前为止,它只能解析绑定,并且在单独遇到表达式时显示错误。。当我尝试使用try或选项功能时,会出现类型不匹配错误: 绑定不应该返回任何内容,但我尝试添加一个return语句,它还返回了一个类型不匹配错误: 无法将类型“[Expr]”与“Expr”匹配 预期类型:T
try
或选项
功能时,会出现类型不匹配错误:
绑定不应该返回任何内容,但我尝试添加一个return语句,它还返回了一个类型不匹配错误:
无法将类型“[Expr]”与“Expr”匹配
预期类型:Text.Parsec.Prim.ParsecT
[Char]u0 Data.Functor.Identity.Identity[Expr]
实际类型:Text.Parsec.Prim.ParsecT
[Char]u0 Data.Functor.Identity.Identity[[Expr]]
在“()”的第二个参数中,即“expressions”
如果要同时允许这两种情况,请不要使用
您的程序
解析器的主要工作是使用
program = do
spaces
try bindings <|> expressions
spaces >> eof
如果有更多的“binding”
类型提示,则更容易找到此错误,这样您就可以更清楚地看到预期的内容
endBy
不需要many
您收到的错误消息来自该行
expressions = many (endBy expression eol)
应该是哪一个
expressions :: Parser [Expr]
expressions = endBy expression eol
endBy
的工作原理类似于sebby
——您不需要在其上使用many
,因为它已经解析了许多
如果使用更强的数据类型树,则更容易找到此错误,因此:
使用尝试处理常见前缀
您遇到的一个难以调试的问题是在解析表达式时出现错误需要空格或“=”
。如果我们考虑到这一点,我们期望的唯一位置是在绑定中,因此当我们给绑定一个表达式时,它一定是解析绑定的一部分。只有当表达式以标识符开头时才会发生这种情况,就像绑定一样
binding
看到第一个标识符并说“没关系,伙计们,我有这个”,但随后没有找到=
,并给出一个错误,我们希望它回溯并让表达式
试一试。关键的一点是,我们已经使用了标识符输入,我们希望使用它try
正适合这样做
用try
封装绑定
解析器,因此如果失败,我们将返回到行的开头,并将其交给表达式
binding = try (do
(Var id) <- identifier
_ <- char '='
spaces
exp <- expression
spaces
eol <?> "end of line"
return $ Eq id exp
<?> "binding")
例如,不要对字母这样做,而是对重要的事情。重要的事情是判断的问题,但我要从标识符开始。(您可以使用
在结果中不包含类似=
的语法。)
修订守则:
在重构类型和使用Applicative之前
然后谢谢你。。我试图进行您提到的修改,但是当解析器到达只有表达式的行时,它会显示一个错误&需要绑定:code
unexpected”(“需要空格或“=”我将绑定定义为:data binding=Eq Symbol Expr绑定的类型是:bindings::parser[binding]binding::Parser binding是否正确?是的。我正在使用更正但未改进的版本(如)解析括号内的表达式。如果这不起作用,能否发布“Program.txt”
?解析表达式时仍返回相同的错误,“Program.txt”仅在删除所有绑定后才包含表达式:eq(div(add 2 7)(sub 5 2))3;
@user3305447 Ah yes-表达式和绑定都可以以标识符开头,因此绑定
有一个尝试,但预期=
失败。这是常见的前缀问题。请参阅新版本的答案。
expressions = many (endBy expression eol)
expressions :: Parser [Expr]
expressions = endBy expression eol
binding = try (do
(Var id) <- identifier
_ <- char '='
spaces
exp <- expression
spaces
eol <?> "end of line"
return $ Eq id exp
<?> "binding")
--<program> ::= <spaces> [<bindings>] <expressions>
data Program = Prog [Binding] [Expr]
program = spaces >> Prog <$> bindings <*> expressions
-- <expression> ::= <abstraction> | factors
data Expression = Ab Abstraction | Fa [Factor]
expression = Ab <$> abstraction <|> Fa <$> factors <?> "expression"