2016-05-14 2 views
1

Pour un projet, nous sommes chargés de construire un analyseur/évaluateur de haskell qui contrôle un petit robot arduino. Pour commencer, j'ai fait quelques recherches sur des configurations d'analyseurs déjà implémentées, et j'ai rencontré celui-ci: https://wiki.haskell.org/Parsing_a_simple_imperative_language. Après (certes) copier-coller le code, j'ai commencé à le tester. Et cela a fonctionné \ o /. Il était maintenant temps d'étendre ses fonctionnalités.Parsec: extension d'un analyseur de travail donne des résultats impairs

Code Modifié:

data Stmt = Seq [Stmt] 
    | Assign String AExpr 
    | If BExpr Stmt Stmt 
    | While BExpr Stmt 
    | Motor String AExpr 
    | Skip 
     deriving (Show) 

Token.reservedNames = [ "if" 
           , "then" 
           , "else" 
           , "while" 
           , "do" 
           , "skip" 
           , "true" 
           , "false" 
           , "not" 
           , "and" 
           , "or", "set" , "to" 
           ] 
statement' :: Parser Stmt 
statement' = ifStmt 
     <|> whileStmt 
     <|> skipStmt 
     <|> assignStmt 
     <|> motorStatement 

motorStatement :: Parser Stmt 
motorStatement = 
    do reserved "set" 
    var <- identifier 
    reserved "to" 
    expr <- aExpression 
    return $ Motor var expr 

Ce sont les seuls morceaux de code que je sous la direction. Pour le tester, je fait une petite testfile:

x := 4; 
x := 6; 

Le code ci-dessus analysé beatifully avant mes changements, mais après avoir ajouté les changements que j'obtiens l'erreur suivante

< (line 3, column 1): 
< unexpected end of input 
< expecting "if", "while", "skip", identifier or "set" 

Avec mes connaissances limitées de Haskell, je suis incapable de comprendre pourquoi ce "unexpected end of input" se passe.

Peut-être que certains Haskeller ici est capable de me signaler l'erreur.

Répondre

2

Je ne suis pas convaincu que votre entrée a été analysée correctement avant d'effectuer les modifications. Une liste des états est analysée en utilisant sepBy1:

sequenceOfStmt = 
    do list <- (sepBy1 statement' semi) 
    -- If there's only one statement return it without using Seq. 
    return $ if length list == 1 then head list else Seq list 

sequenceOfStmt est gourmand en ce que si on voit un point-virgule, il s'attendre à voir un autre statement'. Un point-virgule doit donc être considéré comme un séparateur d'instructions, par opposition à un terminateur d'instruction.

Essayez d'exécuter ces tests pour voir comment sepBy1: se comporte

import Text.Parsec 
import Text.Parsec.Combinator 

p1 = sepBy1 (char 'a') (char ';') 

test1 = parseTest p1 "a;a"  -- OK 
test2 = parseTest p1 "a;a;"  -- FAILS 

Pour aider à explorer cette question, j'ai mis la source pour la langue ParseWhile sur lpaste.net: http://lpaste.net/163332

+0

lecture de votre réponse faite Je réalise rapidement mon "erreur". Chaque point-virgule fait en sorte qu'il a besoin/veut une autre ligne/déclaration. Et parce qu'une ligne vide ne peut pas être convertie en un type, c'est une erreur. Merci Monsieur! – MrKickkiller