Pegjs: ¿Cómo implementarlo desde la línea de comandos?

Creado en 6 jun. 2017  ·  24Comentarios  ·  Fuente: pegjs/pegjs

Hice un archivo .peg (en línea) que valida. Me gustaría usarlo en casa en la línea de comandos. Instalé pegjs desde los repositorios de Ubuntu 16.04. Hice pegjs tldr.peg y produjo un archivo tldr.js .

¿Cómo lo uso en la línea de comandos? Tengo archivos que me gustaría revisar.

question

Comentario más útil

¡Se ve bien! Gracias por hacer un ejemplo más completo, @jodevsa. Supuse que conocía JavaScript.

Pero eso trae a colación la idea de que las personas pueden querer usar PEG.js sin siquiera saber JavaScript en absoluto. Creo que sería útil proporcionar un programa que pueda leer genéricamente un archivo de entrada y gramática, y enviarlo a un archivo o salida estándar.

Todos 24 comentarios

Por lo tanto, desea crear una herramienta de línea de comando que use el .peg que creó y valide los archivos en función de un parámetro de línea de comando. estoy en lo cierto?

por ejemplo:
validate_file ~/file.blah

@ pepa65

@jodevsa ¡ Eso es lo que estoy tratando de lograr ..!

El tldr.js generado es solo una biblioteca general invocada por la función de análisis, ¡debes escribir un programa que haga esto!

1- lee el archivo
2- enviar el contenido del archivo a la biblioteca tldr
3- resultado de salida?

Definición de función de biblioteca generada por PEG.js:

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

extraiga los datos del archivo que desee y utilice el analizador (fileContent).

Si está utilizando Node, aquí hay un ejemplo más concreto:

#!/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));
  });
}

Quizás sería útil tener una aplicación que lo haga de manera más general.

@mikeaustin Claramente, esta no es la forma más fácil para que él entienda lo que hiciste.
@ pepa65 Mira esto:

#!/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();

  • colóquelo en una carpeta con su tldr.js, digamos que lo nombró check_file

  • chmod + x check_file

  • agregue la ubicación de la carpeta a $ ruta en ~ / .bashrc y restablezca el terminal

  • ahora puedes usarlo así, check_file ~ / file.txt

@mikeaustin Parece que no tengo ../lib/peg a pesar de que tengo node-pegjs (y peg) instalados.

Lo que busco es un script de nodo generalizado que podría llamar como: peg-check tldr.pegjs file-to-be-checked donde tldr.pegjs es la salida de pegjs tldr.peg tldr.pegjs y file-to-be-checked contiene el texto que se está verificando.

O, si pegjs podría generar opcionalmente un script que incorpore tldr.pegjs , de modo que pegjs tldr.peg -s tldr-check generaría un script que podría usarse como: tldr-check file-to-be-checked , eso aumentaría la usabilidad de pegjs enormemente para los no iniciados ..!

@jodevsa ¡Gracias!
tengo

let output = parser(data);
            ^^^

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

Entonces agregué 'use strict'; , pero luego obtuve:

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

SyntaxError: Unexpected eval or arguments in strict mode

Supongo que mi javascript-fu no es lo suficientemente fuerte ...

@ pepa65 actualicé el código, compruébalo de nuevo
mi error :(

@ pepa65 estoy usando el nodo v 8.0.0, si

@ pepa65
NVM, solo prueba esto

#!/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 funciona bien aquí. El único inconveniente que encontré fue que tldr.js contenía printf (que reemplacé con console.log), ¡pero luego funciona!
Lo único que no entiendo es que termina la salida con undefined pase lo que pase.

extraño, javascript ni siquiera contiene una función "printf"; incluso versiones más antiguas
Si está de acuerdo con publicar su gramática pública, sería más fácil para mí ayudar

Oh, lo siento, revisando mi clavija, vi que había agregado incorrectamente { printf("OK");} , así que cambié eso.
Pero todavía termina con indefinido. Mi gramática:

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 Eso es porque el script en ejecución que @jodevsa le dio registra el resultado de ejecutar la gramática de clavijas; debido a que su regla page nivel superior termina con console.log , el PEG devolverá undefined al script en ejecución.

Puede cambiar console.log(OK) a return "OK"; , ignorar el undefined que está impreso o eliminar la línea console.log(output) del script en ejecución.

¡Espero que ayude!

@hawkrives : +1:

Cierto, tonto de mi parte. ¡Lo hace más fácil! Creo que llegué las cosas a donde puedo proceder. ¡Gracias a todos!

Supongo que, como resumen para aquellos que vienen aquí buscando la respuesta final, use este script, quizás llámelo 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();

Haz chmod +x grammar-check y compila tu gramática como: pegjs your-grammar.peg grammar.js y luego puedes implementar como: grammar-check filename (donde nombre de archivo es la ubicación del archivo a verificar).

¡Se ve bien! Gracias por hacer un ejemplo más completo, @jodevsa. Supuse que conocía JavaScript.

Pero eso trae a colación la idea de que las personas pueden querer usar PEG.js sin siquiera saber JavaScript en absoluto. Creo que sería útil proporcionar un programa que pueda leer genéricamente un archivo de entrada y gramática, y enviarlo a un archivo o salida estándar.

Creo que sería útil proporcionar un programa que pueda leer genéricamente un archivo de entrada y gramática, y enviarlo a un archivo o salida estándar.

Entonces, ¿se volverá a abrir este tema?

@mikeaustin @waldyrious tal vez en lugar de hacer un "programa" separado. ¿Esto se puede mencionar en el archivo Léame? Con un ejemplo de implementación de tal cosa.

¡No dude en utilizar el ejemplo de trabajo anterior ...!

tal vez en lugar de hacer un "programa" separado, ¿esto se puede mencionar en el archivo Léame?

El comentario de @mikeaustin sugiere que un programa separado tiene un beneficio de conveniencia para los usuarios finales, y estoy de acuerdo con eso.

@waldyrious Este problema fue una pregunta, voy a abrir un nuevo problema para lo que sugirió @mikeaustin , uno que debería ver la función implementada para 0.11 (si es una adición simple sin problemas), pero podría ser empujada a 1.0 ( si genera algún error, lo empujaré hacia atrás para solucionarlo más tarde). Sin embargo, debería ser fácil de implementar una vez que haya terminado con la herramienta de línea de comandos reescribir.

Lo siento @ pepa65 por no responder antes, pero para ser honesto contigo, hasta que @waldyrious publicó su comentario hoy, ni siquiera sabía que existía el problema 😆

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

mattkanwisher picture mattkanwisher  ·  5Comentarios

mikeaustin picture mikeaustin  ·  7Comentarios

audinue picture audinue  ·  13Comentarios

Coffee2CodeNL picture Coffee2CodeNL  ·  13Comentarios

StoneCypher picture StoneCypher  ·  8Comentarios