Pegjs: Parse (règle spécifique) n'a aucun sens !

Créé le 2 nov. 2016  ·  2Commentaires  ·  Source: pegjs/pegjs

J'ai essayé d'analyser avec quelque chose de différent de start mais cela échoue avec "Can't start parsing from rule myrule" parce que

        var startRule = options.startRule || "start";
        if (["start"].indexOf(startRule) < 0) {
          throw new Error("Can't start parsing from rule " + quote(startRule) + ".");
        }

Pourquoi définissez-vous la grammaire mais ne pouvez tester qu'une seule d'entre elles ? Écrivez-vous des programmes tels que seule la méthode main puisse y être exécutée ? Qu'en est-il des autres procédures ? Ne comprenez-vous pas qu'une grammaire est une bibliothèque, que vous pouvez utiliser chaque parseur séparément, en dehors du cadre de la main ? J'ai défini un analyseur entier quelque part au bas de ma grammaire. Pourquoi je ne peux pas l'utiliser/tester séparément, en dehors de mon programme principal ? Vous dites que je suis autorisé à analyser avec n'importe quelle règle de démarrage mais limitez leur nom à 'start'. C'est quoi l'engouement ? Pourquoi indexOf('start') , pourquoi pas startRule == 'start' ? Cela donnerait plus de liberté et de compréhension à l'utilisateur !

feature

Commentaire le plus utile

@ valtih1978 Veuillez atténuer votre voix agressive. Ce n'est pas parce que quelque chose n'est pas fait comme vous le feriez qu'il n'y a pas de bonnes raisons de le faire comme ça.

Le point de vue de PEG.js est que toute la grammaire (ou plutôt l'analyseur généré à partir de celle-ci) est l'unité atomique, pas une règle. Le point d'entrée d'un analyseur est sa règle de démarrage (la première par défaut). Si vous voulez avoir plusieurs points d'entrée, très bien, il vous suffit de les désigner explicitement.

Considérez l'analyseur comme un objet où chaque règle est une méthode distincte. Un conseil sensé en POO est de garder toutes les méthodes privées à l'exception de celles qui forment l'interface avec l'objet. Et c'est exactement ce que PEG.js fait pour les analyseurs.

Cette partie de la philosophie de PEG.js est justifiée par deux choses :

  1. Les analyseurs peuvent maintenir l'état. Autoriser l'analyse à démarrer à partir de n'importe quelle règle par défaut pourrait facilement conduire les utilisateurs à violer certains invariants sur lesquels l'analyseur s'appuie, à moins que l'auteur de l'analyseur n'ait pris soin de spécifier explicitement les règles de démarrage autorisées.

  2. Il est logique d'avoir la liberté d'intégrer des règles. Cela n'est actuellement fait que dans des circonstances très spécifiques (règles de proxy), mais l'architecture n'empêche pas de l'étendre et d'améliorer les performances de l'analyseur sans que les auteurs de l'analyseur ne fassent quoi que ce soit.

Les deux raisons ont leur équivalent dans l'analogie POO que j'ai mentionnée.

Maintenant, vous avez raison de dire que l'approche de PEG.js rend les tests légèrement plus difficiles. D'après mon expérience, ce n'est pas un gros problème. Vous avez juste besoin d'utiliser des cas de test qui sont une entrée valide d'une règle de démarrage. J'ai pu tester la grammaire PEG.js et quelques autres grammaires très bien en utilisant cette approche.

Quant aux bibliothèques, je ne vois pas en quoi l'approche actuelle empêche de les construire. Il suffit d'être explicite sur les règles « exportées ». Mais si la construction de bibliothèques de règles est votre principal cas d'utilisation, il peut être préférable d'utiliser une bibliothèque basée sur un combinateur d'analyseurs, qui est naturellement mieux adaptée à cette tâche que les générateurs d'analyseurs basés sur la grammaire.

En tout cas, je ne changerais pas la valeur par défaut. Pour ce qui est d'avoir un moyen d'autoriser facilement toutes les règles comme règles de démarrage, voir #234.

Tous les 2 commentaires

Ok, j'ai constaté que vous limitiez l'ensemble des règles de démarrage pour des raisons de performances

La liste des règles de démarrage autorisées d'un analyseur généré doit maintenant être spécifiée explicitement à l'aide de l'option allowStartRules de la méthode PEG.buildParser ou de l'option --allowed-start-rule sur la ligne de commande. Cela facilitera certaines optimisations telles que l'intégration de règles à l'avenir.

Je vous propose d'activer toutes les fonctionnalités par défaut et de limiter les règles de démarrage à la demande de performances.

En attendant, j'ai trouvé une solution de contournement

function *execAllGen(re, text){
    for (let match; (match = re.exec(text)) !== null;) 
      yield match;
} ; const execAll = (re, text) => [...execAllGen(re, text)]

  const allRules = execAll(/^\s*(\w+)/mg, grammar).map(m=>m[1])
  const parser = peg.generate(grammar, {allowedStartRules:allRules});

Je soutiens que generate pourrait produire un certain nombre d'analyseurs, un analyseur pour chaque règle de démarrage.

Edit : Attendez, conseillez-vous que je génère un analyseur pour chaque règle séparément ?

@ valtih1978 Veuillez atténuer votre voix agressive. Ce n'est pas parce que quelque chose n'est pas fait comme vous le feriez qu'il n'y a pas de bonnes raisons de le faire comme ça.

Le point de vue de PEG.js est que toute la grammaire (ou plutôt l'analyseur généré à partir de celle-ci) est l'unité atomique, pas une règle. Le point d'entrée d'un analyseur est sa règle de démarrage (la première par défaut). Si vous voulez avoir plusieurs points d'entrée, très bien, il vous suffit de les désigner explicitement.

Considérez l'analyseur comme un objet où chaque règle est une méthode distincte. Un conseil sensé en POO est de garder toutes les méthodes privées à l'exception de celles qui forment l'interface avec l'objet. Et c'est exactement ce que PEG.js fait pour les analyseurs.

Cette partie de la philosophie de PEG.js est justifiée par deux choses :

  1. Les analyseurs peuvent maintenir l'état. Autoriser l'analyse à démarrer à partir de n'importe quelle règle par défaut pourrait facilement conduire les utilisateurs à violer certains invariants sur lesquels l'analyseur s'appuie, à moins que l'auteur de l'analyseur n'ait pris soin de spécifier explicitement les règles de démarrage autorisées.

  2. Il est logique d'avoir la liberté d'intégrer des règles. Cela n'est actuellement fait que dans des circonstances très spécifiques (règles de proxy), mais l'architecture n'empêche pas de l'étendre et d'améliorer les performances de l'analyseur sans que les auteurs de l'analyseur ne fassent quoi que ce soit.

Les deux raisons ont leur équivalent dans l'analogie POO que j'ai mentionnée.

Maintenant, vous avez raison de dire que l'approche de PEG.js rend les tests légèrement plus difficiles. D'après mon expérience, ce n'est pas un gros problème. Vous avez juste besoin d'utiliser des cas de test qui sont une entrée valide d'une règle de démarrage. J'ai pu tester la grammaire PEG.js et quelques autres grammaires très bien en utilisant cette approche.

Quant aux bibliothèques, je ne vois pas en quoi l'approche actuelle empêche de les construire. Il suffit d'être explicite sur les règles « exportées ». Mais si la construction de bibliothèques de règles est votre principal cas d'utilisation, il peut être préférable d'utiliser une bibliothèque basée sur un combinateur d'analyseurs, qui est naturellement mieux adaptée à cette tâche que les générateurs d'analyseurs basés sur la grammaire.

En tout cas, je ne changerais pas la valeur par défaut. Pour ce qui est d'avoir un moyen d'autoriser facilement toutes les règles comme règles de démarrage, voir #234.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

brettz9 picture brettz9  ·  8Commentaires

mattkanwisher picture mattkanwisher  ·  5Commentaires

futagoza picture futagoza  ·  13Commentaires

Coffee2CodeNL picture Coffee2CodeNL  ·  13Commentaires

dmajda picture dmajda  ·  15Commentaires