Pegjs: Como implantá-lo a partir da linha de comando?

Criado em 6 jun. 2017  ·  24Comentários  ·  Fonte: pegjs/pegjs

Fiz um arquivo .peg (online) que valida. Eu gostaria de usar em casa na linha de comando. Instalei pegjs dos repositórios Ubuntu 16.04. Eu fiz pegjs tldr.peg e produziu um arquivo tldr.js .

Como faço para usar isso na linha de comando? Tenho arquivos que gostaria de verificar.

question

Comentários muito úteis

Parece bom! Obrigado por fazer um exemplo mais completo, @jodevsa. Presumi que ele conhecia JavaScript.

Mas isso meio que traz a ideia de que as pessoas podem querer usar o PEG.js mesmo sem conhecer JavaScript. Acho que seria útil fornecer um programa que pudesse ler genericamente uma gramática e um arquivo de entrada e gerar um arquivo ou saída padrão.

Todos 24 comentários

Portanto, você deseja criar uma ferramenta de linha de comando que use o .peg que você criou e validar os arquivos com base em um parâmetro de linha de comando. Estou certo?

por ex:
validate_file ~/file.blah

@ pepa65

@jodevsa É isso que estou tentando alcançar ..!

O tldr.js gerado é apenas uma biblioteca geral invocada pela função parse, você tem que escrever um programa que faça isso!

1- leia o arquivo
2- enviar o conteúdo do arquivo para a biblioteca tldr
3- resultado de saída?

Definição de função de biblioteca gerada por PEG.js:

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

extraia os dados do arquivo que você deseja e use o analisador (fileContent)!

Se você estiver usando o Node, aqui está um exemplo mais 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));
  });
}

Talvez seja útil ter um aplicativo que faça isso de forma mais geral.

@mikeaustin Obviamente, esta não é a maneira mais fácil para ele entender o que você fez
@ pepa65 Veja isto:

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

  • coloque-o em uma pasta com seu tldr.js, digamos que você o nomeou check_file

  • chmod + x check_file

  • adicione a localização da pasta a $ path em ~ / .bashrc e reinicie o terminal

  • agora você pode usá-lo assim, check_file ~ / file.txt

@mikeaustin Eu não tenho ../lib/peg embora eu tenha node-pegjs (e peg) instalado.

O que estou procurando é um script de nó generalizado que eu poderia chamar como: peg-check tldr.pegjs file-to-be-checked onde tldr.pegjs é a saída de pegjs tldr.peg tldr.pegjs e file-to-be-checked contém o texto que está sendo verificado.

Ou, se os pegjs pudessem, opcionalmente, gerar um script que incorpora tldr.pegjs , de modo que pegjs tldr.peg -s tldr-check geraria um script que poderia ser usado como: tldr-check file-to-be-checked , que aumentaria a usabilidade dos pegjs enormemente para os não iniciados ..!

@jodevsa Obrigado!
eu obtive

let output = parser(data);
            ^^^

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

Então, adicionei 'use strict'; , mas obtive:

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

SyntaxError: Unexpected eval or arguments in strict mode

Acho que meu javascript-fu não é forte o suficiente ...

@ pepa65 atualizei o código, verifique novamente
meu erro :(

@ pepa65 estou usando o node v 8.0.0, se outro erro aparecer, basta substituir cada "let" e "const" por var

@ pepa65
NVM, apenas tente isso

#!/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 bem aqui. O único obstáculo que encontrei foi que tldr.js continha printf (que substituí por console.log), mas funciona!
A única coisa que não entendo é que termina a saída com undefined aconteça o que acontecer.

estranho, o javascript nem mesmo contém a função "printf"; versões ainda mais antigas
se você concordar em postar sua gramática pública, seria mais fácil para mim ajudar

Oh, desculpe, revendo meu peg, vi que tinha adicionado { printf("OK");} erroneamente, então mudei isso.
Mas ainda termina com indefinido. Minha 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 Isso @jodevsa forneceu registra o resultado da execução da gramática de page termina com console.log , o PEG retornará undefined para o script em execução.

Você pode alterar console.log(OK) para return "OK"; , ignorar o undefined impresso ou remover a linha console.log(output) do script em execução.

Espero que ajude!

@hawkrives : +1:

Certo, bobo da minha parte. Torna mais fácil! Acho que tenho coisas para onde posso prosseguir. Obrigado a todos!

Eu acho que, como um resumo para aqueles que vêm aqui em busca da resposta final, use este script, talvez chame-o de 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();

Faça chmod +x grammar-check e compile sua gramática como: pegjs your-grammar.peg grammar.js e depois disso você pode implementar como: grammar-check filename (onde filename é a localização do arquivo a ser verificado).

Parece bom! Obrigado por fazer um exemplo mais completo, @jodevsa. Presumi que ele conhecia JavaScript.

Mas isso meio que traz a ideia de que as pessoas podem querer usar o PEG.js mesmo sem conhecer JavaScript. Acho que seria útil fornecer um programa que pudesse ler genericamente uma gramática e um arquivo de entrada e gerar um arquivo ou saída padrão.

Acho que seria útil fornecer um programa que pudesse ler genericamente uma gramática e um arquivo de entrada e gerar um arquivo ou saída padrão.

Essa edição deve ser reaberta, então?

@mikeaustin @waldyrious talvez em vez de fazer um "programa" separado - isso pode ser mencionado apenas no readme? Com um exemplo de implementação de tal coisa.

Sinta-se à vontade para usar o exemplo de trabalho acima ..!

talvez em vez de fazer um "programa" separado - isso pode apenas ser mencionado no leia-me?

O comentário de @mikeaustin sugere que um programa separado oferece um benefício de conveniência para os usuários finais, e eu concordo com isso.

@waldyrious Esse problema era uma questão, vou abrir um novo problema para o que @mikeaustin sugeriu, um que deve ver o recurso implementado para 0.11 (se for uma adição simples sem problemas), mas pode ser empurrado para 1.0 ( se levantar algum erro, vou empurrá-lo de volta para resolver mais tarde). Deve ser simples de implementar depois que eu terminar de reescrever a ferramenta de linha de comando.

Desculpe @ pepa65 por não responder antes, mas para ser honesto com você, até @waldyrious postar seu comentário hoje, eu nem sabia que o problema existia 😆

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

futagoza picture futagoza  ·  13Comentários

emmenko picture emmenko  ·  15Comentários

lontivero picture lontivero  ·  25Comentários

kwesibrunee picture kwesibrunee  ·  33Comentários

doersino picture doersino  ·  15Comentários