Pegjs: 如何从命令行部署它?

创建于 2017-06-06  ·  24评论  ·  资料来源: pegjs/pegjs

我制作了一个验证的 .peg 文件(在线)。 我想在家里的命令行中使用。 我从 Ubuntu 16.04 存储库安装了 pegjs。 我做了pegjs tldr.peg并且它产生了一个tldr.js文件。

我如何在命令行上使用它? 我有文件要检查。

question

最有用的评论

看起来不错! 感谢您制作更完整的示例,@jodevsa。 我假设他知道 JavaScript。

但这种想法带来了人们可能想要在根本不了解 JavaScript 的情况下使用 PEG.js 的想法。 我认为提供一个可以通用读取语法和输入文件,并输出到文件或标准输出的程序会很方便。

所有24条评论

因此,您想要创建一个命令行工具,该工具使用您创建的 .peg 并根据命令行参数验证文件。 我对吗?

例如:
validate_file ~/file.blah

@pepa65

@jodevsa这就是我想要实现的目标..!

生成的 tldr.js 只是一个由 parse 函数调用的通用库,您必须编写一个程序来执行此操作!

1-读取文件
2- 将文件内容发送到 tldr 库
3-输出结果?

PEG.js 生成库函数定义:

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

从您想要的文件中提取数据并使用 parser(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 检查文件

  • 将文件夹位置添加到 ~/.bashrc 中的 $path 并重置终端

  • 现在你可以像这样使用它, check_file ~/file.txt

@mikeaustin我似乎没有../lib/peg即使我安装了 node-pegjs(和 peg)。

我所追求的是一个通用的节点脚本,我可以调用它: 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");} ,所以我改变了它。
但它仍然以 undefined 结束。 我的语法:

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给你的运行脚本记录了运行peg 语法的结果; 因为您的顶级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 (其中文件名是要检查的文件的位置)。

看起来不错! 感谢您制作更完整的示例,@jodevsa。 我假设他知道 JavaScript。

但这种想法带来了人们可能想要在根本不了解 JavaScript 的情况下使用 PEG.js 的想法。 我认为提供一个可以通用读取语法和输入文件,并输出到文件或标准输出的程序会很方便。

我认为提供一个可以通用读取语法和输入文件,并输出到文件或标准输出的程序会很方便。

那这个问题要不要重开?

@mikeaustin @waldyrious也许不是制作一个单独的“程序”——这可以在自述文件中提到吗? 举个例子来实现这样的事情。

随意使用上面的工作示例..!

也许不是制作一个单独的“程序”——这可以在自述文件中提到吗?

@mikeaustin的评论表明,单独的程序确实为最终用户带来了便利,我同意这一点。

@waldyrious这个问题是一个问题,我将针对@mikeaustin 的建议打开一个新问题,该问题应该看到为 0.11 实现的功能(如果它是一个没有问题的简单添加),但可能会被推送到 1.0(如果它引发了一些错误,我会把它推回去稍后整理)。 在我完成命令行工具重写后,应该很容易实现。

抱歉@pepa65没有早点回复,但说实话,直到@waldyrious今天发表评论,我什至不知道这个问题存在😆

此页面是否有帮助?
0 / 5 - 0 等级