Haskell 递归问题,微型解析器。一些东西

2023-12-25

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

这是数据类型Expr, 我有几个问题。我想解析像这样的表达式*(Expr,Expr)如数据类型定义中所示。然而,我在“创建”有效的Expr。我使用模式匹配来识别 Expr 的不同含义。更多代码:

parseExpr :: String -> (Expr, String)
parseExpr ('*':'(':x:',':y:')':s)   = (Mult (parseExpr [x] parseExpr [y]),s) 

显然,这是行不通的。返回类型为parseExpr是将要解析的表达式的其余部分作为解析代码的一部分返回Expr。这段代码的右侧是问题所在。我无法做出有效的Expr。该函数应该递归地调用自身,直到问题得到解决。

另一个问题是我不知道如何进行模式匹配Var and Tall。我该如何检查Var是 A-Z 之间的大写字符Tall是 0-9 并将其作为有效值返回Expr?

一般来说,我可以只查看字符串的几个部分来了解哪一部分Expr我正在处理。

Input like: parseProg "let X be 9 in *(X , 2)" Would spit out: Let (Var 'X') (Tall 9) (Mult (Var 'X') (Tall 2)) 

Your parseExpr函数返回一个对,所以当然你不能直接使用它的结果来构造一个Expr。我写这个的方式会是这样的

parseExpr ('*':'(':s) = (Mult x y, s'')
    where (x,',':s') = parseExpr s
          (y,')':s'') = parseExpr s'

基本思想是,既然parseExpr返回剩余的字符串作为该对的第二个参数,您需要在进行的每个递归调用中保存该字符串,并且当您处理完所有子表达式后,您需要返回剩余的任何内容。显然这里的错误处理很糟糕,所以如果这是一个强大的解析器,您可能需要多考虑一下。

处理Var and Tall我会按原样提取第一个字符并有一个if构建一个Expr适当的类型。

如果你想在 Haskell 中编写更复杂的解析器,你会想要看看 Parsec 库,它可以让你编写一个解析器,就像你正在解析的语言的语法一样。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Haskell 递归问题,微型解析器。一些东西 的相关文章

随机推荐