Parsec parse beaucoup question
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.
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.