【问题标题】:Issue with recursion writing a tiny parser in Haskell. Check variables在 Haskell 中编写一个小型解析器的递归问题。检查变量
【发布时间】:2009-10-07 22:17:22
【问题描述】:

我仍在为学校任务中​​定义的一种小型语言开发一个小型解析器。生成 AST(抽象语法树)的解析器正在工作。我想要的是检查定义的变量,它们必须以 let 表达式为界。首先是任务中定义的方法(建议,不需要):

checkVars :: Expr -> Char 

data Expr =  Var Char | Tall Int | Sum Expr Expr | Mult Expr Expr | Neg Expr | Let Expr Expr Expr
    deriving(Eq, Show) 

一个有效的句子应该是“让 X 在 *(2,X) 中为 5”。 X 通常是 Var 而 5 通常是 int。最后一个可以是 dataExpr 类型的任何部分。要点:X 用在最后一个表达式的某处。 let 的数据类型是:

Let Expr Expr Expr

链接到我在此处询问的有关此任务的其他问题,仅供参考; First question Second question

正如您看到的 checkVars 的数据类型是 Expr,所以这里是我将提供给该函数的示例:

parseProg "let X be 4 in let Y be *(2 , X) in let Z be +(Y , X) in
+(+(X , Y) , Z)"
Let (Var 'X') (Tall 4) (Let (Var 'Y') (Mult (Tall 2) (Var 'X')) (Let
(Var 'Z') (Sum (Var 'Y') (Var 'X')) (Sum (Sum (Var 'X') (Var 'Y')) (Var
'Z'))))
Just 24

这是一个包罗万象的示例,顶部是正在解析的字符串/程序。第二部分,从第 3 行(Let)开始是 AST,是 checkVars 函数的输入。而底部“Just 24”是评价。我会回到这里寻求更多帮助。 注意:重点是将找到的第一个未绑定变量作为错误吐出,如果一切正常,则吐出''。显然,如果您想以其他方式执行此操作。

【问题讨论】:

  • 我这周因为生病而错过了研讨会,如果组长回复他的电子邮件,他回复的速度很慢。

标签: parsing haskell interpreter evaluation


【解决方案1】:

这里有一些事情要考虑:

您的 Let 构造函数的第一个字段是 Expr。但它实际上还能容纳Vars 以外的任何东西吗?如果不是,您应该通过将该字段的类型设为String 并相应地调整解析器来反映这一点。这将使您的任务更容易。

使用 let-bindings 评估表达式的标准技巧(您正在这样做)是编写一个函数

type Env = [(String, Int)]
eval :: Expr -> Env -> Int

注意环境的额外参数。环境会跟踪在任何给定时刻将哪些变量绑定到哪些值。它在类型中的位置意味着您每次在子表达式上调用eval 时都可以决定它的值。这很关键!这也意味着您可以拥有本地声明的变量:绑定变量对其上下文没有影响,仅对子表达式有影响。

以下是特殊情况:

  • Var 中,您希望lookup 环境中的变量名并返回绑定到它的值。 (使用标准 Prelude 函数lookup。)
  • Let 中,您希望在将(varname, value) 传递给子表达式之前,在环境列表的前面添加一个额外的(varname, value)

我遗漏了一些细节,但这应该足以让您走得更远。如果你卡住了,再问一个问题。 :-)

哦,我看到你想返回一个 Maybe 值来表示失败。我建议您首先尝试不使用并使用error 来指示未绑定的变量。当你有那个版本的eval 工作时,调整它以返回Maybe 值。原因是使用Maybe 值会使评估变得相当复杂。

【讨论】:

    【解决方案2】:

    我实际上会尝试评估 AST。首先处理(并因此删除)所有Lets。现在,尝试评估生成的 AST。如果您遇到Var,则存在未绑定的变量。

    【讨论】:

      猜你喜欢
      • 2020-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-06
      • 1970-01-01
      • 2012-01-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多