Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing Haskell解析器到AST数据类型-输入“|”时解析错误_Parsing_Haskell - Fatal编程技术网

Parsing Haskell解析器到AST数据类型-输入“|”时解析错误

Parsing Haskell解析器到AST数据类型-输入“|”时解析错误,parsing,haskell,Parsing,Haskell,我正在为一项分配给我们的任务苦苦挣扎。我在这里根据不同的指南编写了这段代码: 我遇到的问题是这里的管道有一个问题: | x == "+" = (Sum y y',xs'') where 问题似乎与在where后面有3个管道或一个管道有关。如果我交换最后两个管道。 放置 以前 x == "*" = (Prod y y' (...)) 导致错误移动到该代码。如果我注释掉这两个代码段中的任何一个,一切都会正常工作,但是我需要它们来完成分配给我们的任务 快速总结: | x == "*" = (Pr

我正在为一项分配给我们的任务苦苦挣扎。我在这里根据不同的指南编写了这段代码:

我遇到的问题是这里的管道有一个问题:

| x == "+" = (Sum y y',xs'') where
问题似乎与在where后面有3个管道或一个管道有关。如果我交换最后两个管道。 放置

以前

x == "*"  = (Prod y y' (...))
导致错误移动到该代码。如果我注释掉这两个代码段中的任何一个,一切都会正常工作,但是我需要它们来完成分配给我们的任务

快速总结:

| x == "*" = (Prod y y',xs'') where
                (y,xs') = ast xs
                (y',xs'') = ast xs'

两者都能100%单独工作,但当我把它们放在一起时,我的程序无法编译

完整代码:

import Data.Char

data AST = Leaf Int 
            | Sum AST AST 
            | Min AST 
            | Prod AST AST
            deriving Show

tokenize::String -> [String]
tokenize[] = []
tokenize('+':xs) = "+": tokenize xs
tokenize('-':xs) = "-": tokenize xs
tokenize('*':xs) = "*": tokenize xs
tokenize(x:xs) = if isDigit x then (takeWhile isDigit (x:xs)) : tokenize (dropWhile isDigit xs) else tokenize(xs)

ast :: [String] -> (AST,[String])
ast [] = error "Empty string"
ast (x:xs) | all isDigit x = (Leaf (read x),xs)
    | x == "-" = let (y,xs') = ast xs in (Min y,xs')
    | x == "*" = (Prod y y',xs'') where
            (y,xs') = ast xs
            (y',xs'') = ast xs'
    | x == "+" = (Sum y y',xs'') where
            (y,xs') = ast xs
            (y',xs'') = ast xs'
中的问题

ast [] = error "Empty string"
ast (x:xs) | all isDigit x = (Leaf (read x),xs)
    | x == "-" = let (y,xs') = ast xs in (Min y,xs')
    | x == "*" = (Prod y y',xs'') where
            (y,xs') = ast xs
            (y',xs'') = ast xs'
    | x == "+" = (Sum y y',xs'') where
            (y,xs') = ast xs
            (y',xs'') = ast xs'
在函数定义中,每个方程只能有一个where子句。因此,在x==*选项中的where之后,解析器希望模式x:xs的等式是完整的

只需删除有问题的where,where子句的范围覆盖了等式中的所有选项,两个where子句的内容相同,缩进更好,where根据我的偏好属于它自己的行。由于第一个备选方案中的let使用where子句中也存在的绑定,因此也可以删除该绑定:

ast [] = error "Empty string"
ast (x:xs) | all isDigit x = (Leaf (read x),xs)
    | x == "-" = (Min y,xs')
    | x == "*" = (Prod y y',xs'')
    | x == "+" = (Sum y y',xs'')
      where
        (y,xs') = ast xs
        (y',xs'') = ast xs'
中的问题

ast [] = error "Empty string"
ast (x:xs) | all isDigit x = (Leaf (read x),xs)
    | x == "-" = let (y,xs') = ast xs in (Min y,xs')
    | x == "*" = (Prod y y',xs'') where
            (y,xs') = ast xs
            (y',xs'') = ast xs'
    | x == "+" = (Sum y y',xs'') where
            (y,xs') = ast xs
            (y',xs'') = ast xs'
在函数定义中,每个方程只能有一个where子句。因此,在x==*选项中的where之后,解析器希望模式x:xs的等式是完整的

只需删除有问题的where,where子句的范围覆盖了等式中的所有选项,两个where子句的内容相同,缩进更好,where根据我的偏好属于它自己的行。由于第一个备选方案中的let使用where子句中也存在的绑定,因此也可以删除该绑定:

ast [] = error "Empty string"
ast (x:xs) | all isDigit x = (Leaf (read x),xs)
    | x == "-" = (Min y,xs')
    | x == "*" = (Prod y y',xs'')
    | x == "+" = (Sum y y',xs'')
      where
        (y,xs') = ast xs
        (y',xs'') = ast xs'

解决此问题的一种方法是使用let,而不是where:

在let中可以有任意多个定义,而不仅仅是一个

where语句始终在范围内,而let在范围内结束。这就是你收到错误信息的原因——它认为你仍然在where,但你想继续。把where条款推迟到最后


在这种情况下,您不需要将它们分开,因此可以将它们组合到一个where中,但let通常适用于此问题。

一种解决方法是使用let而不是where:

在let中可以有任意多个定义,而不仅仅是一个

where语句始终在范围内,而let在范围内结束。这就是你收到错误信息的原因——它认为你仍然在where,但你想继续。把where条款推迟到最后

在这种情况下,您不需要将它们分开,因此可以将它们组合到一个where中,但let通常对这个问题很有用

ast :: [String] -> (AST,[String])
ast [] = error "Empty string"
ast (x:xs) | all isDigit x = (Leaf (read x),xs)
    | x == "-" = let (y,xs') = ast xs in (Min y,xs')
    | x == "*" = let
            (y,xs') = ast xs 
            (y',xs'') = ast xs'
            in (Prod y y',xs'')
    | x == "+" = let 
            (y,xs') = ast xs
            (y',xs'') = ast xs'
            in (Sum y y',xs'')