Pegjs: Comment le déployer depuis la ligne de commande ?

Créé le 6 juin 2017  ·  24Commentaires  ·  Source: pegjs/pegjs

J'ai fait un fichier .peg (en ligne) qui valide. Je voudrais utiliser à la maison sur la ligne de commande. J'ai installé pegjs à partir des dépôts Ubuntu 16.04. J'ai fait pegjs tldr.peg et cela a produit un fichier tldr.js .

Comment l'utiliser en ligne de commande ? J'ai des fichiers que j'aimerais vérifier.

question

Commentaire le plus utile

Cela semble bon! Merci d'avoir fait un exemple plus complet, @jodevsa. Je supposais qu'il connaissait JavaScript.

Mais ce genre de choses amène l'idée que les gens peuvent vouloir utiliser PEG.js sans même connaître du tout JavaScript. Je pense qu'il serait pratique de fournir un programme capable de lire de manière générique un fichier de grammaire et d'entrée, et de produire une sortie dans un fichier ou une sortie standard.

Tous les 24 commentaires

Vous souhaitez donc créer un outil de ligne de commande qui utilise le fichier .peg que vous avez créé et valider les fichiers en fonction d'un paramètre de ligne de commande. ai-je raison?

par exemple :
validate_file ~/file.blah

@ pepa65

@jodevsa C'est ce que j'essaie de réaliser..!

Le tldr.js généré n'est qu'une bibliothèque générale invoquée par la fonction d'analyse, vous devez écrire un programme qui fait cela !

1- lire le fichier
2- envoyer le contenu du fichier à la bibliothèque tldr
3- résultat de sortie ?

Définition de la fonction de bibliothèque générée par PEG.js :

var parser=require('./tldr').parse;

extrayez les données du fichier que vous voulez et utilisez parser(fileContent) !

Si vous utilisez Node, voici un exemple plus concret :

#!/usr/bin/env node

'use strict';

//
// echo "2 + 3" | node compile.js arithmetics.pegjs
// echo "2 + 3" | node compile.js javascript.pegjs
//

let fs = require('fs');
let peg = require('../lib/peg');

let grammar = fs.readFileSync(process.argv[2]).toString();
let parser = peg.generate(grammar);
let input = [];

compile(process.stdin);

function compile(stdin) {
  stdin.resume();
  stdin.setEncoding('utf8');

  stdin.on('data', (data) => input.push(data));

  stdin.on('end', () => {
    let output = parser.parse(input.join('').trim());

    console.log(JSON.stringify(output, null, 2));
  });
}

Il serait peut-être utile d'avoir une application qui le fasse de manière plus générale.

@mikeustin De
@ pepa65 Vérifiez ceci:

#!/usr/bin/env node
'use strict';

const fs = require('fs');
const parser = require('./tldr.js').parse;

function main() {
    const args = require('process').argv;
    if (args.length != 3) {
        console.error("Enter file Path as argument.")
        return 1;
    }
    let filename = args[2];
    fs.readFile(filename, {encoding: 'utf8'},function(err, data) {
        if (err) {
            console.log("error while reading the file!");
            console.error(err);
            return 1;
        }

        try {
            let output = parser(data);
            console.log(output)

        } catch (e) {
            console.error(e.message);

        }


    });

}

main();

  • mettez-le dans un dossier avec votre tldr.js disons que vous l'avez nommé check_file

  • chmod +x fichier_contrôle

  • ajouter l'emplacement du dossier à $path dans ~/.bashrc et réinitialiser le terminal

  • maintenant vous pouvez l'utiliser comme ceci, check_file ~/file.txt

@mikeaustin Je ne semble pas avoir ../lib/peg même si j'ai installé node-pegjs (et peg).

Ce que je recherche, c'est un script de nœud généralisé que je pourrais appeler comme : peg-check tldr.pegjs file-to-be-checked où tldr.pegjs est la sortie de pegjs tldr.peg tldr.pegjs et file-to-be-checked contient le texte en cours de vérification.

Ou, si pegjs pouvait éventuellement sortir un script qui incorpore tldr.pegjs , de sorte que pegjs tldr.peg -s tldr-check produirait un script qui pourrait être utilisé comme : tldr-check file-to-be-checked , cela augmenterait la convivialité de pegjs énormément pour les non-initiés..!

@jodevsa Merci !
j'ai eu

let output = parser(data);
            ^^^

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode

J'ai donc ajouté 'use strict'; , mais j'ai obtenu :

const arguments = require('process').argv;
          ^^^^^^^^^

SyntaxError: Unexpected eval or arguments in strict mode

Je suppose que mon javascript-fu n'est pas assez puissant...

@ pepa65 j'ai mis à jour le code, vérifiez-le à nouveau
ma faute :(

@ pepa65 j'utilise node v 8.0.0 , si une autre erreur apparaît, remplacez simplement chaque "let" et "const" par var

@pepa65
NVM, essayez ceci

#!/usr/bin/env node

  'use strict';

  var fs = require('fs');
  var parser = require('./tldr.js').parse;

  function main() {
      var args = require('process').argv;
      if (args.length != 3) {
          console.error("Enter file Path as argument.")
          return 1;
      }
      var filename = args[2];
      fs.readFile(filename, {encoding: 'utf8'},function(err, data) {
          if (err) {
              console.log("error while reading the file!");
              console.error(err);
              return 1;
          }

          try {
              var output = parser(data);
              console.log(output)

          } catch (e) {
              console.error(e.message);

          }


      });

  }

  main();

const fonctionne bien ici. Le seul hic que j'ai rencontré était que tldr.js contenait printf (que j'ai remplacé par console.log), mais ça marche !
La seule chose que je ne comprends pas, c'est que cela termine la sortie avec undefined quoi qu'il arrive.

bizarre, javascript ne contient même pas de fonction "printf" ; versions encore plus anciennes
si vous êtes d'accord pour publier votre grammaire publique, il serait plus facile pour moi de vous aider

O, désolé, en révisant ma cheville, j'ai vu que j'avais mal ajouté { printf("OK");} , alors j'ai changé ça.
Mais cela se termine toujours par undefined. Ma grammaire :

page = header description examples eof { console.log("OK");}
header = command nl underline nl nl
description = (descriptor nolowercase any dot nl)+
examples = example (nl example)*
example = example_description nl example_command
example_description = nolowercase any colon nl
example_command = fourspace any nl
command = [a-zA-Z0-9_][-a-zA-Z0-9_ ]*
underline = '='+
any = [a-z ()-,-.={}/_0-9A-Z]*
nolowercase = [^a-z]
descriptor = '> '
fourspace = '    '
dot = .
colon = ':'
nl = [\n]
eof = !.

@ pepa65 C'est parce que le script en cours d'exécution que @jodevsa vous a fourni enregistre le résultat de l'exécution de la grammaire peg; parce que votre règle de niveau supérieur page se termine par un console.log , le PEG renverra undefined au script en cours d'exécution.

Vous pouvez soit changer le console.log(OK) en return "OK"; , ignorer le undefined qui est imprimé ou supprimer la ligne console.log(output) du script en cours d'exécution.

J'espère que cela pourra aider!

@hawkrives :+1:

Bon, idiot de ma part. C'est plus facile ! Je pense que j'ai réussi à faire avancer les choses. Merci à tous!

Je suppose que, en guise de résumé pour ceux qui viennent ici à la recherche de la réponse finale, utilisez ce script, appelez-le peut-être grammar-check :

#!/usr/bin/env node
'use strict';

const fs = require('fs');
const parser = require('./grammar.js').parse;

function main() {
  const args = require('process').argv;
  if (args.length != 3) {
    console.error("Only 1 argument needed: file-path")
    return 1;
  }
  const filename = args[2];
  fs.readFile(filename, {encoding: 'utf8'}, function(err, data) {
    if (err) {
      console.log("Error reading file", filename);
      console.error(err);
      return 1;
    }
    try {
      let output = parser(data);
      console.log(output);
    }
    catch (e) {
      console.error(e.message);
    }
  });
}

main();

Faites chmod +x grammar-check et compilez votre grammaire comme : pegjs your-grammar.peg grammar.js et après cela vous pouvez déployer comme : grammar-check filename (où filename est l'emplacement du fichier à vérifier).

Cela semble bon! Merci d'avoir fait un exemple plus complet, @jodevsa. Je supposais qu'il connaissait JavaScript.

Mais ce genre de choses amène l'idée que les gens peuvent vouloir utiliser PEG.js sans même connaître du tout JavaScript. Je pense qu'il serait pratique de fournir un programme capable de lire de manière générique un fichier de grammaire et d'entrée, et de produire une sortie dans un fichier ou une sortie standard.

Je pense qu'il serait pratique de fournir un programme capable de lire de manière générique un fichier de grammaire et d'entrée, et de produire une sortie dans un fichier ou une sortie standard.

Est-ce que cette question sera rouverte, alors?

@mikeaustin @waldyrious peut-être au lieu de créer un "programme" séparé - cela peut simplement être mentionné dans le fichier readme ? Avec un exemple de mise en œuvre d'une telle chose.

N'hésitez pas à utiliser l'exemple de travail ci -

peut-être au lieu de créer un "programme" séparé - cela peut être simplement mentionné dans le fichier readme ?

Le commentaire de @mikeaustin suggère qu'un programme distinct présente un avantage de commodité pour les utilisateurs finaux, et je suis d'accord avec cela.

@waldyrious Ce problème était une question, je vais ouvrir un nouveau problème pour ce que @mikeaustin a suggéré, celui qui devrait voir la fonctionnalité implémentée pour 0.11 (s'il s'agit d'un simple ajout sans problème), mais qui pourrait être poussé à 1.0 ( si cela soulève des erreurs, je le repousserai pour régler plus tard). Cela devrait être simple à mettre en œuvre une fois que j'ai terminé avec la réécriture de l'outil de ligne de commande.

Désolé @pepa65 de ne pas avoir répondu plus tôt, mais pour être honnête avec vous, jusqu'à ce que

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

Questions connexes

richb-hanover picture richb-hanover  ·  7Commentaires

mikeaustin picture mikeaustin  ·  7Commentaires

mattkanwisher picture mattkanwisher  ·  5Commentaires

futagoza picture futagoza  ·  6Commentaires

marek-baranowski picture marek-baranowski  ·  6Commentaires