Haskell递归问题,小解析器。一些东西 [英] Haskell recursive problem, tiny parser. A few things

查看:86
本文介绍了Haskell递归问题,小解析器。一些东西的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  data Expr = Var Char |高层Int | Sum Expr Expr | Mult Expr Expr | Neg Expr |让Expr Expr Expr 
导出(Eq,Show)

这是<$的数据类型c $ c> Expr ,我有几个问题。我假设分析像 *(Expr,Expr)这样的表达式,如数据类型定义中所示。然而,我确实遇到了一些问题,创建一个有效的 Expr 。我使用模式匹配来识别Expr可以做的不同事情。还有一些代码:

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

显然,这不起作用。 parseExpr 的返回类型是将要解析的表达式的其余部分作为 Expr 。此代码的右侧是问题。我无法生成一个有效的 Expr 。该函数假设以递归方式自我调用,直到问题解决。

另一个问题是我不知道如何对 Var 和<$ c $进行模式匹配C>高大。我如何检查 Var 是AZ与 Tall 之间的大写字符是0-9,并将其作为有效 Expr



通常,我只需看一下字符串的几个部分即可了解 Expr 的哪一部分用。

 输入如下:parseProglet X be 9 in *(X,2)会吐出:Let(Var'X ')(Tall 9)(Mult(Var'X')(Tall 2))


解决方

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

  parseExpr('*':'(':s)=(Mult xy ,s'')
其中(x,',':s')= parseExpr s
(y,')':s'')= parseExpr s'
$ b $ p $基本思想是,因为 parseExpr 返回剩下的字符串作为第二个参数你需要在每一次递归调用中保存该字符串,当你处理了所有的子表达式时,你需要返回剩下的内容。显然,这里的错误处理很糟糕,所以如果这是一个强大的解析器,你可能会想更多地考虑这一点。



处理 Var Tall 我会按照原样提取第一个字符,并且如果 c>构造适当类型的 Expr



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


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

That is the datatype for Expr, I have a few questions. I'm suppose to parse expressions like *(Expr,Expr) as shown in the datatype definition. However I do have some problems with "creating" a valid Expr. I use pattern matching for recognizing the different things Expr can be. Some more code:

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

This is not working, obviously. The return type of parseExpr is to return the rest of the expression that is to be parsed an a portion of the parsed code as an Expr. The right side of this code is the problem. I can't make a valid Expr. The function is suppose to call it self recursively until the problem is solved.

ANOTHER problem is that I don't know how to do the pattern matching against Var and Tall. How can I check that Var is an uppercase character between A-Z and that Tall is 0-9 and return it as a valid Expr?

Generally I can just look at a few parts of the string to understand what part of Expr I'm dealing with.

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 function returns a pair, so of course you cannot use its result directly to construct an Expr. The way I would write this would be something like

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

The basic idea is that, since parseExpr returns the leftover string as the second argument of the pair, you need to save that string in each recursive call you make, and when you've handled all the subexpressions, you need to return whatever is left over. And obviously the error handling here sucks, so you may want to think about that a bit more if this is intended to be a robust parser.

Handling Var and Tall I would do by just extracting the first character as is and have an if to construct an Expr of the appropriate type.

And if you want to write more complex parsers in Haskell, you'll want to look at the Parsec library, which lets you write a parser as pretty much the grammar of the language you're parsing.

这篇关于Haskell递归问题,小解析器。一些东西的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆