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(使用前将#替换为@)