Question

J'essaie de concevoir une grammaire de l'île en utilisant Rascal MPL , mais j'ai couru dans un Problème:

Lors de la mise en œuvre d'une grammaire île dans le SDF une approche très courante consiste à définir une production d'eau "attrape-tout" à l'aide de l'attribut {éviter}. Cela empêche l'analyseur d'utiliser cette production si d'autres sont applicables. Cela permet de spécifier un comportement par défaut qui peut être remplacé par d'autres productions WHITOUT générant des abus. Un exemple très simple de cela serait:

context free syntax
    Chunk*         -> Input
    Water          -> Chunk
lexical syntax
    ~[\t\n\ ]+   -> Water {avoid}  // avoid the Water production

J'ai essayé de reproduire ce comportement avec Rascal MPL. Mon objectif est de créer une grammaire insulaire qui rassemble toutes les directives de préprocesseur conditionnelles à l'intérieur d'une pièce de code C / C ++ et saute le reste de l'entrée à l'aide de productions d'eau.

layout LAYOUT = [\t\n\ ];
lexical WATER = ![\t\n\ ]+;

start syntax Program = Line*;       // program consists of lines

syntax Line = ConditionalDirective  // preprocessor directives
            > WATER;                // catch-all option

syntax ConditionalDirective = "#ifdef" 
                            | "#ifndef"
                            | "#if"
                            | "#elif";

J'ai essayé de créer l'effet {éviter} en donnant à la production conditionnelle une priorité plus élevée à l'aide de l'opérateur ">", mais cela ne fonctionne pas apparemment. L'arbre d'analyse contient encore des ambiguïtés.

#ifdef asd

Si j'estime le code ci-dessus par exemple, je reçois un arbre d'analyse qui ressemble comme suit:

arbre d'analyse ambiguë

Autant que je puisse dire au Rascal La documentation , en utilisant la "priorité" -Oprateur pourrait ne pas être la voie à suivre dans mon cas, mais je ne vois aucune autre possibilité. Je suppose qu'il y a un moyen cependant, car les auteurs de Rascal affirment clairement que chaque grammaire SDF peut être convertie en une grammaire coquine.

Y a-t-il un moyen de reproduire sdfs {éviter} fonctionnalité avec Rascal MPL? Ou est-il possible de filtrer la forêt d'analyse en quelque sorte, réapplique les priorités?

Était-ce utile?

La solution

Réponse courte: Éviter est dans SDF2 un filtre post analyse. Dans Rascal, vous pouvez les définir vous-même, voir https://github.com/cwi-swat/rascal/blob/master/src/org/rascalmpl/library/lang/sdf2/filters/preferavoid.arc pour un exemple qui imite SDF2 Évitez le comportement sans ignorer les chaînes d'injection et sans compter. Vous pouvez l'importer dans votre grammaire et utiliser des balises @avoid et @prefer comme dans le SDF2, ou écrivez vos propres filtres.

CAVEATAIRE: L'éviter ne suffisait généralement pas pour définir le comportement de l'eau dans le SDF2 et ce n'est pas non plus dans le coquin. La raison en est que l'eau peut devenir plus longue que son alternative. Les préférences et l'éviter ne peuvent choisir que des alternatives de longueur égale en termes de longueur de sous-traitance. Un moyen Serfire mais un moyen lent de traiter de l'eau à Rascal est de le compter dans chaque alternative et de choisir des dérivations avec moins d'eau.

Un autre problème avec la préférence et l'éviter était que les utilisations commenceraient à interférer, surtout quand elles ont été comptées. Cela peut être évité à Rascal en spécialisant des filtres pour des non-mines spécifiques ou même des règles alternatives.

Une autre option consiste à utiliser les \ et! opérateurs de désambigation. Voir le manuel. Cependant, tous et tous Je crois que l'option de filtrage post-analyse est actuellement la meilleure façon de gérer les grammaires de l'île, car vous contrôlez ce qui se passe.

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