Haskell递归问题,小解析器。否定Expr并让表达式 [英] Haskell recursive problem, tiny parser. Negation of Expr and let expressions

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

问题描述

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

parseExpr :: String - > (Expr,String)

parseExpr('*':'(':s)=(Mult xy,s'')
其中(x,',':s')= parseExpr s
(y,')':s'')= parseExpr s'
parseExpr('+':'(':s)=(Sum xy,s'')
其中(x,',':s')= parseExpr s
(y,')':s'')= parseExpr s'
parseExpr(x:xs)| isDigit x =(Tall(digitToInt x),xs)
parseExpr(x:s)=(Var x,s)
其中x> ='A'= True
x< = 'Z'= True

解析器在完成之前缺少两件事。从其缺乏Neg Expr和LetExpr Expr Expr之上的数据类型。第一部分是这样的:

  parseExpr(' - '
parseExpr('l':'e ':'t':x:'b':'e

在数据类型中,Let表达式以let开头,并带入三个Expr。
我不知道如何写出这些最后的函数。任何帮助都将非常感激。



<我没有问过关于这个问题的另一个问题,并且这里是该问题的链接。






以下是一个例子:

  parseProg设X = 4令Y为*(2,X)令Z为+(Y,X)in 
+(+( (Var'X')(Tall'4')(Let'Var'Y')(Mult(Tall 2)(Var'X'))(Let'b $ b' (Var'Z')(Sum(Var'Y')(Var'X'))(Sum(Sum(Var'X')(Var'Y'))(Var
'Z'))) )


:'e':'t':s)=(让xyz,s3)
其中(x,'b':'e':s1)= parseExpr s
(y,'i': 'n':s2)= parseExpr s1
(z,s3)= parseExpr s2

如果一个字符串以字母 l e t 取其余的字符串( s )并尝试从它解析表达式。这会产生一个表达式( x )和一个剩余的字符串。我们期望这个剩余的字符串以字母 b e 开头。由于这应该跟另一个表达式,我们再次给这个字符串( s2 )的其余部分给parseExpr解析另一个表达式。等等。



唯一的问题是我们没有考虑可能将这些关键字分隔开的空格,例如let和be 。简单的解决方案是在这些关键字之前/之后需要一个空格,然后在parseExpr中更改模式以明确包含这些模式,例如:

 其中(x,'':'b':'e':'':s1)= parseExpr s 

更灵活的是添加一个 dropSpaces :: String - > String 函数删除前导空格并在适当的位置被调用。


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

parseExpr :: String -> (Expr, String)

parseExpr ('*':'(':s) = (Mult x y, s'')
    where (x,',':s') = parseExpr s
          (y,')':s'') = parseExpr s'
parseExpr ('+':'(':s) = (Sum x y, s'')
    where (x,',':s') = parseExpr s
          (y,')':s'') = parseExpr s'
parseExpr (x : xs) | isDigit x = (Tall (digitToInt x), xs)
parseExpr (x:s) = (Var x,s) 
    where   x >= 'A' = True
        x <= 'Z' = True 

My parser is lacking two things before it is complete. As from the datatype above its lacking "Neg Expr" and Let "Expr Expr Expr". The first part would be something like this:

parseExpr('-' 
parseExpr('l':'e':'t':x:'b':'e 

As in the datatype, the Let expressions starts with let and takes in three Expr. I don't know how to write out these last functions. Any help at all will be very much appreciated.

I did ask another question here on SO about this, and here is the link for that question.


Here is an example:

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'))))

解决方案

The basic strategy for these parts of the expression would be the same as for the other operations, just that you don't have to parse two subexpressions, but one or three. For let it would look like this:

parseExpr ('l':'e':'t':s) = (Let x y z, s3)
    where (x, 'b':'e':s1) = parseExpr s
          (y, 'i':'n':s2) = parseExpr s1
          (z, s3)         = parseExpr s2

If a string starts with the letters l, e, t take the remaining string (s) and try to parse an expression from it. This results in an expression (x) and a remaining string. We expect that this remaining string starts with the letters b, e. Since this should be followed by another expression we give the rest of this string (s2) again to parseExpr to parse another expression. And so on.

The only problem with this is that we don't account for spaces that might separate these keywords like "let" and "be" from the surrounding expressions. The easy solution would be to require exactly one space before/after these keywords and change the patterns in parseExpr to explicitly include these, for example:

    where (x, ' ':'b':'e':' ':s1) = parseExpr s

More flexible would be to add a dropSpaces :: String -> String function that removes leading spaces and gets called in the appropriate places.

这篇关于Haskell递归问题,小解析器。否定Expr并让表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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