了解Haskell中已实现的递归下降解析器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了了解Haskell中已实现的递归下降解析器相关的知识,希望对你有一定的参考价值。
我遇到了分配问题,因为我必须在预定义的AST上解析标记化前缀计算器符号。我们为解析提供了非常完整的算法(我们必须添加一些内容)。
我提交的算法和AST如下:
data Ast = Tall Int | Sum Ast Ast | Mult Ast Ast | Min Ast | Var String deriving (Eq, Show)
parseExpr :: [String] -> (Ast, [String])
parseExpr [] = error "Empty!"
parseExpr ("+":rs) = let (e1, r1) = parseExpr rs ;(e2, r2) = parseExpr r1 in (Sum e1 e2, r2)
parseExpr ("*":rs) = let (e1, r1) = parseExpr rs ;(e2, r2) = parseExpr r1 in (Mult e1 e2, r2)
parseExpr ("-":rs) = let (e1, r1) = parseExpr rs in (Min e1, r1)
parseExpr (x:rs)
| all isDigit x = (Tall (read x), rs)
| all isAlpha x = (Var x, rs)
| otherwise = error ("Syntax errors "++x)
输入/输出示例:
parseExpr ["+","4","*","8","-","5"] =
(Sum (Tall 4) (Mult (Tall 8) (Min (Tall 5))),[])
我在继续任务时需要的是元组的第一部分。这是正确的,已上交作业,并且就作业而言一切都很好。
话虽如此,我不知道递归函数中发生了什么。特别是在这三行中:
parseExpr ("+":rs) = let (e1, r1) = parseExpr rs ;(e2, r2) = parseExpr r1 in (Sum e1 e2, r2)
parseExpr ("*":rs) = let (e1, r1) = parseExpr rs ;(e2, r2) = parseExpr r1 in (Mult e1 e2, r2)
parseExpr ("-":rs) = let (e1, r1) = parseExpr rs in (Min e1, r1)
当然,我得到(“ +”:rs)表示法。我很难理解的是“ let(e1,r1)= .....”等
而且在最后的警卫中,我看不到任何递归调用。但是,递归会发生,对吗?如何运作?
答案
让我们以更传统的方式写出其中一个定义:
parseExpr ("+":rs) = let (e1, r1) = parseExpr rs -- recursive call #1
(e2, r2) = parseExpr r1 -- recursive call #2
in (Sum e1 e2, r2)
给出一个以"+"
开头的列表,我们首先递归地解析它之后的所有内容;结果表达式的名称为e1
,未使用的后缀rs
的名称为r1
。我们通过解析r1
以获得表达式e2
和其余输入r2
来重复此过程。这样,我们可以使用两个子表达式Sum
和e1
构造e2
值,然后将r2
传回给我们的调用方进行解析。
使用您的示例,
-- Step 1
parseExpr ["+","4","*","8","-","5"]
= let (e1, r1) = parseExpr ["4","*","8","-","5"]
(e2, r2) = parseExpr r1
in (Sum e1 e2, r2)
在我们可以做更多之前,我们必须评估第一个递归调用
-- Step 2
parseExpr ["4","*","8","-","5"] = (Tall 4, ["*","8","-","5"])
现在我们可以将结果插入步骤1
-- Step 3
parseExpr ["+","4","*","8","-","5"]
= let (e1, r1) = (Tall 4, ["*","8","-","5"])
(e2, r2) = parseExpr r1
in (Sum e1 e2, r2)
-- Step 4
parseExpr ["+","4","*","8","-","5"]
= let (e2, r2) = parseExpr ["*","8","-","5"]
in (Sum (Tall 4) e2, r2)
依此类推...
以上是关于了解Haskell中已实现的递归下降解析器的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 C++ 递归下降解析器只适用于几台计算机? [关闭]