2017-01-24 1 views
0
#!/usr/bin/env runhaskell 

import   Control.Applicative   ((<|>)) 
import   Text.Parsec.Char 
import   Text.ParserCombinators.Parsec hiding (spaces, (<|>)) 

main :: IO() 
main = do 
    print $ parse p "" "a\nb\n\nc\nd" where 
    p = sepBy1 (try pp) newline 
    pp = sepBy1 l newline 
    l = many1 letter 

Je suis en train d'analyser ceci:Nested sepBy1 avec la même delimiter

a 
b 

c 
d 

à ceci: [["a", "b"], ["c", "d"]]. J'ai essayé de jouer avec try mais ça ne semble pas marcher.

C'est probablement quelque chose de très basique, essayez d'expliquer ce qui se passe dans votre réponse (je suis débutant dans Haskell et Parsec).

Editer: J'ai oublié d'ajouter un message d'erreur.

Left (line 3, column 1): 
unexpected "\n" 
expecting letter 
+0

Qu'est-ce qui ne fonctionne pas? Vous obtenez une erreur de compilation? Mauvaise sortie ?? S'il vous plaît soyez précis sur ce qu'est votre problème. –

+0

@WillemVanOnsem Désolé, vous avez oublié d'ajouter un message d'erreur. Je l'ai ajouté à la question. – monnef

+0

Il y a deux nouvelles lignes séparant chaque segment de lettres – Euge

Répondre

2

Le problème semble être la mise en œuvre de sepBy1, car l'erreur apparaît même pour parse pp "" "a\nb\n". Alors que nous nous attendons à ce que cela retourne Right ["a","b"], il renvoie la même erreur expected \n. Donc, il semble que sepBy1 fonctionne comme prévu, sauf dans le cas où la chaîne à analyser se termine avec le séparateur. Cela semble être inoffensif, car il y a un autre combinateur d'analyseur pour ce cas. Mais maintenant que nous voulons deux sepBy1 s imbriqués avec le même séparateur, c'est un problème.

La seule solution que j'ai trouvé est d'écrire votre propre retour arrière sepBy1, et l'utiliser dans le cas interne.

main :: IO() 
main = print $ parse p "" "a\nb\n\nc\nd" 
    where pp = mySepBy1 l newline 
     l = many1 letter 
     p = sepBy1 pp (newline >> newline) 

mySepBy1 parser separator = do 
    x <- parser 
    xs <- many (try $ separator >> parser) 
    return (x:xs)