2010-10-30 6 views
2

Je dois créer un analyseur pour un langage de programmation. Jusqu'à présent, il est fait à 95%, je dirais, sauf pour un petit détail.Parsec analyser de nombreuses questions

Le programme écrit dans cette langue a la structure suivante:

outputs 
inputs 
expressions 

L'exigence est que les résultats ne peuvent pas être mélangés avec des entrées. Par exemple:

x := output of int; 
y := output of in; 
..... 
z := input of int; 
t := input of in; 
..... 
expressions 

je peux analyser une seule sortie très bien, mais si je tente d'utiliser (sortie many1), pour permettre à plusieurs sorties, il ne fonctionne pas parce qu'il essaie d'analyser les entrées comme sorties.

Mon analyseur principal ressemble à ceci:

prog = 
    do outs <- many1 output 
     ins <- many1 input 
     exs <- expressions 
     eof 
     return (Prog outs ins exs) 

Je sais que cela semble facile, mais j'ai essayé beaucoup de choses et ne peux pas le faire fonctionner. S'il vous plaît aider.

Répondre

3

Si votre règle pour la sortie ressemble à ceci:

output = do name <- ident 
      string ":= output of" 
      type <- ident 
      char ';' 
      return $ Out name type 

et votre règle d'entrée a la même sauf avec « entrée », le problème est que les deux règles commencent par une ident et depuis parsec doesn Reculer automatiquement, il va juste essayer d'appliquer output d'abord, en consommant le ident, puis échouer quand il ne peut pas correspondre à "sortie de".

Pour résoudre ce problème, vous pouvez simplement envelopper output et input dans try, à savoir

outs <- many1 (try output) 
ins <- many1 (try input) 
+0

Merci beaucoup. Cela l'a totalement réparé. Je ne me suis pas rendu compte qu'ils commencent tous deux par un ident et qu'il est consommé par l'analyseur de sortie. – HaskellNoob

0

Tout fonctionne la réponse de sepp2k, je tiens personnellement à résumer la retours en arrière à l'intérieur des parseurs de sortie et d'entrée.

Bien que cela ajoute du code aux parseurs il les rendre plus robustes:

output = do name <- try prefix 
      type <- ident 
      char ';' 
      return $ Out name type 
    where 
    prefix = do name <- ident 
       string ":= output of" 
       return name 

Avec parsec, son généralement préférable d'éviter essayer à l'exception de Char Parsers et l'affacturage gauche pour améliorer la grammaire (essayer peut rendre les parseurs très fragiles). Malheureusement, la grammaire que vous utilisez n'est pas particulièrement adaptée à l'affacturage de gauche et, dans ce cas, cela ne vaut probablement pas la peine de le déranger.

Questions connexes