Pegjs: Как его развернуть из командной строки?

Созданный на 6 июн. 2017  ·  24Комментарии  ·  Источник: pegjs/pegjs

Я сделал файл .peg (онлайн), который проверяет. Я хотел бы использовать in дома в командной строке. Я установил pegjs из репозиториев Ubuntu 16.04. Я сделал pegjs tldr.peg и tldr.js файл

Как мне использовать это в командной строке? У меня есть файлы, которые я хочу проверить.

question

Самый полезный комментарий

Выглядит неплохо! Спасибо за более полный пример, @jodevsa. Я предполагал, что он знает JavaScript.

Но это наводит на мысль, что люди могут захотеть использовать PEG.js, даже не зная JavaScript. Я думаю, было бы удобно предоставить программу, которая могла бы в общем случае читать грамматику и входной файл и выводить в файл или стандартный вывод.

Все 24 Комментарий

Итак, вы хотите создать инструмент командной строки, который будет использовать созданный вами .peg и проверять файлы на основе параметра командной строки. я прав?

например:
validate_file ~/file.blah

@ pepa65

@jodevsa Вот чего я пытаюсь достичь ..!

Сгенерированный tldr.js - это просто общая библиотека, вызываемая функцией синтаксического анализа, вам нужно написать программу, которая сделает это!

1- прочитать файл
2- отправить содержимое файла в библиотеку tldr
3- результат вывода?

Определение функции библиотеки, сгенерированной PEG.js:

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

извлеките данные из нужного файла и используйте парсер (fileContent)!

Если вы используете Node, вот более конкретный пример:

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

Может быть, было бы полезно иметь приложение, которое делает это в более общем плане.

@mikeaustin Очевидно, это не самый простой способ понять, что вы сделали
@ pepa65 Проверьте это:

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

  • поместите его в папку с вами. tldr.js позволяет сказать, что вы назвали его check_file

  • chmod + x check_file

  • добавить расположение папки в $ path в ~ / .bashrc и сбросить терминал

  • теперь вы можете использовать это так, check_file ~ / file.txt

@mikeaustin Кажется, у меня нет ../lib/peg хотя у меня установлены node-pegjs (и привязка).

Мне нужен обобщенный сценарий узла, который я мог бы назвать следующим образом: peg-check tldr.pegjs file-to-be-checked где tldr.pegjs - это результат pegjs tldr.peg tldr.pegjs а file-to-be-checked содержит проверяемый текст.

Или, если pegjs может при желании выводить сценарий, включающий tldr.pegjs , так что pegjs tldr.peg -s tldr-check выводит сценарий, который можно использовать как: tldr-check file-to-be-checked , что повысит удобство использования pegjs чрезвычайно для непосвященных ..!

@jodevsa Спасибо!
я получил

let output = parser(data);
            ^^^

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

Я добавил 'use strict'; , но потом получил:

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

SyntaxError: Unexpected eval or arguments in strict mode

Думаю, мой javascript-fu недостаточно силен ...

@ pepa65 я обновил код, проверьте его еще раз
моя вина :(

@ pepa65 я использую node v 8.0.0, если выскочит другая ошибка, просто замените каждое "let" и "const" на var

@ pepa65
NVM, просто попробуйте это

#!/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 здесь отлично работает. Единственная проблема, с которой я столкнулся, заключалась в том, что tldr.js содержал printf (который я заменил на console.log), но тогда он работает!
Единственное, чего я не понимаю, что он заканчивает вывод на undefined не смотря ни на что.

как ни странно, javascript даже не содержит функции printf; даже более старые версии
если ты не против опубликовать свою грамматику, мне будет легче помочь

О, извините, просматривая мою привязку, я увидел, что неправильно добавил { printf("OK");} , поэтому я изменил это.
Но он все равно заканчивается неопределенным. Моя грамматика:

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 Это потому, что запущенный сценарий, который дал вам @jodevsa , записывает результат выполнения грамматики привязки; поскольку ваше правило page верхнего уровня заканчивается console.log , PEG вернет undefined в запущенный скрипт.

Вы можете либо изменить console.log(OK) на return "OK"; , игнорировать напечатанное сообщение undefined , либо удалить строку console.log(output) из запущенного скрипта.

Надеюсь, это поможет!

@hawkrives : +1:

Да, глупо с моей стороны. Делает это проще! Думаю, у меня есть кое-что, к чему я могу продолжить. Спасибо вам всем!

Я предполагаю, что в качестве резюме для тех, кто приходит сюда в поисках окончательного ответа, используйте этот сценарий, возможно, назовите его 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();

Сделайте chmod +x grammar-check и скомпилируйте вашу грамматику, например: pegjs your-grammar.peg grammar.js и после этого вы можете развернуть, например: grammar-check filename (где filename - расположение проверяемого файла).

Выглядит неплохо! Спасибо за более полный пример, @jodevsa. Я предполагал, что он знает JavaScript.

Но это наводит на мысль, что люди могут захотеть использовать PEG.js, даже не зная JavaScript. Я думаю, было бы удобно предоставить программу, которая могла бы в общем случае читать грамматику и входной файл и выводить в файл или стандартный вывод.

Я думаю, было бы удобно предоставить программу, которая могла бы в общем случае читать грамматику и входной файл и выводить в файл или стандартный вывод.

Может быть, этот вопрос будет снова открыт?

@mikeaustin @waldyrious может вместо того, чтобы делать отдельную "программу" - об этом можно просто упомянуть в ридми? На примере реализации такой вещи.

Не стесняйтесь использовать рабочий пример выше ..!

может, вместо того, чтобы делать отдельную "программу" - об этом можно просто упомянуть в ридми?

Комментарий @mikeaustin предполагает, что отдельная программа действительно удобна для конечных пользователей, и я согласен с этим.

@waldyrious Эта проблема была вопросом, я собираюсь открыть новую проблему для того, что предложил @mikeaustin , тот, который должен увидеть функцию, реализованную для 0.11 (если это простое добавление без проблем), но может быть перенесено на 1.0 ( если возникнет какая-то ошибка, я верну ее, чтобы разобраться позже). Должно быть легко реализовать после того, как я закончу перезапись инструмента командной строки.

Извините @ pepa65 за то, что не ответил раньше, но, честно говоря, пока @waldyrious не опубликовал свой комментарий сегодня, я даже не знал, что проблема существует 😆

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

mreinstein picture mreinstein  ·  12Комментарии

mattkanwisher picture mattkanwisher  ·  5Комментарии

audinue picture audinue  ·  13Комментарии

emmenko picture emmenko  ·  15Комментарии

futagoza picture futagoza  ·  13Комментарии