Question

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

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 principal ressemble parser comme 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 au travail. S'il vous plaît aider.

Était-ce utile?

La solution

Si votre règle pour la sortie ressemble à quelque chose comme 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 », alors le problème est que les deux règles commencent par une ident et depuis parsec ne backtrack automatiquement, il va juste essayer d'appliquer output d'abord, la consommation de la ident et puis échouer quand il ne peut pas correspondre à « sortie ».

Pour résoudre ce problème, vous pouvez simplement envelopper output et input dans try, i.e..

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

Autres conseils

Alors que les travaux de 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 et Parsers utiliser l'affacturage gauche pour améliorer la grammaire ( essayer peut rendre parseurs très fragile). Malheureusement, la grammaire que vous travaillez est pas particulièrement favorable à l'affacturage gauche et dans ce cas, il est sans doute pas la peine.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top