2017-10-06 3 views
2

Kann mir bitte jemand sagen, was hier nicht stimmt? Ich kann nicht herausfinden, wo der Fehler ist. Ich bin neu in Haskell, also kenne ich nicht jede Regel der Syntax atm. DieseHaskell - Syntaxfehler

parseS (s:xs) | all isDigit s = (xs, Lit (read s)) 
      | s == " " = parseS xs 
      | s == "-" = let (remainder, e) = parseS xs in (remainder, Sub e) 
      | s == "+" = (xs'', Sum e e') where 
         (xs', e) = parseS xs 
         (xs'', e') = parseS xs' 

      | s == "*" = (xs'', Mul e e') where  <- parse error on input on this line 
         (xs', e) = parseS xs 
         (xs'', e') = parseS xs' 
+2

Bitte schreiben Sie Code, Fehler, Beispieldaten oder Textausgabe hier als Nur-Text, nicht als Bilder, die schwer zu lesen sind, können nicht kopiert werden, um Code zu testen oder in Antworten zu verwenden, und sind feindlich diejenigen, die Bildschirmleser verwenden. Sie können Ihre Frage bearbeiten, um den Code im Hauptteil Ihrer Frage hinzuzufügen. Verwenden Sie die Schaltfläche '{'} ', um beliebige Codeblöcke zu formatieren, oder versehen Sie sie mit vier Leerzeichen für denselben Effekt. Wir können Ihren Screenshot nicht als Code ausführen. – tadman

+3

Bitte senden Sie die Fehlermeldung, wörtlich. –

Antwort

2

ist, wie Haskell sieht Ihr Code:

parseS (s:xs) 
     | all isDigit s = (xs, Lit (read s)) 
     | s == " " = parseS xs 
     | s == "-" = let (remainder, e) = parseS xs in (remainder, Sub e) 
     | s == "+" = (xs'', Sum e e') 
    where 
    (xs', e) = parseS xs 
    (xs'', e') = parseS xs' 

| s == "*" = (xs'', Mul e e') 
    where 
    (xs', e) = parseS xs 
    (xs'', e') = parseS xs' 

Ein where Block legt auf eine Erklärung, die in Ihrem Fall ist die ganze parseS Definition.

Die nächste Zeile, die mit | beginnt, wird als Start einer neuen Deklaration angesehen, die ungültig ist, weil Sie eine Deklaration mit | nicht starten können.

Die einfachste Lösung ist mit where für lokale Bindungen zu stoppen und let stattdessen verwenden, wie folgt aus:

  | s == "+" = 
       let 
        (xs', e) = parseS xs 
        (xs'', e') = parseS xs' 
       in 
       (xs'', Sum e e') 

      | s == "*" = 
       let 
        (xs', e) = parseS xs 
        (xs'', e') = parseS xs' 
       in 
       (xs'', Mul e e') 
3

Das Problem ist, dass die erste where Klausel für parseS (s:xs) als das Ende der Definition genommen wird. Sie versuchen anschließend, einen weiteren geschützten Fall hinzuzufügen, aber der Parser sieht ihn nicht als an dieselbe Definition angehängt.

Es gibt mehrere Möglichkeiten, wie Sie das beheben können.

Sie könnte dieses Problem beheben, indem ein let ... in stattdessen für s == "+"

 | s == "+" = let (xs', e) = parseS xs 
         (xs'', e') = parseS xs 
        in (xs'', Sum e e') 
     | s == "*" = (xs'', Mul e e') where 
         (xs', e) = parseS xs 
         (xs'', e') = parseS xs' 

Verwendung Aber es gibt einen einfacheren Weg, es zu tun - fallen nur, dass where Klausel.

 | s == "+" = (xs'', Sum e e') 
     | s == "*" = (xs'', Mul e e') where 
         (xs', e) = parseS xs 
         (xs'', e') = parseS xs' 

Die Variablen in einer where Klausel definiert sind in Rahmen für die Gesamtheit einer Definition (für alle Wach Fälle), so Ihre Definition von xs'' kann für beide Fälle wiederverwendet werden.