Pegjs: рдЗрд╕реЗ рдХрдорд╛рдВрдбрд▓рд╛рдЗрди рд╕реЗ рдХреИрд╕реЗ рддреИрдирд╛рдд рдХрд░реЗрдВ?

рдХреЛ рдирд┐рд░реНрдорд┐рдд 6 рдЬреВрди 2017  ┬╖  24рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: pegjs/pegjs

рдореИрдВрдиреЗ рдПрдХ .peg рдлрд╝рд╛рдЗрд▓ (рдСрдирд▓рд╛рдЗрди) рдмрдирд╛рдИ рд╣реИ рдЬреЛ рдорд╛рдиреНрдп рд╣реИред рдореИрдВ рдХрдорд╛рдВрдбрд▓рд╛рдЗрди рдкрд░ рдШрд░ рдкрд░ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдореИрдВрдиреЗ Ubuntu 16.04 рд░реЗрдкреЛ рд╕реЗ pegjs рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдПред рдореИрдВрдиреЗ pegjs tldr.peg рдФрд░ рдЗрд╕рдиреЗ tldr.js рдлрд╝рд╛рдЗрд▓ рддреИрдпрд╛рд░ рдХреАред

рдореИрдВ рдЗрд╕реЗ рдХрдорд╛рдВрдбрд▓рд╛рдЗрди рдкрд░ рдХреИрд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВ? рдореЗрд░реЗ рдкрд╛рд╕ рдлрд╛рдЗрд▓реЗрдВ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдореИрдВ рдЬрд╛рдВрдЪрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдЕрдЫрд╛ рд▓рдЧрддрд╛ рд╣реИ! рдПрдХ рдФрд░ рдкреВрд░реНрдг рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, @jodevsaред рдореИрдВ рдорд╛рди рд░рд╣рд╛ рдерд╛ рдХрд┐ рд╡рд╣ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЬрд╛рдирддрд╛ рдерд╛ред

рд▓реЗрдХрд┐рди рдЙрд╕ рддрд░рд╣ рд╕реЗ рдпрд╣ рд╡рд┐рдЪрд╛рд░ рд╕рд╛рдордиреЗ рдЖрддрд╛ рд╣реИ рдХрд┐ рд▓реЛрдЧ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЬрд╛рдиреЗ рдмрд┐рдирд╛ рднреА PEG.js рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣ рд╕рдХрддреЗ рд╣реИрдВред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛрдЧрд╛ рдЬреЛ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдПрдХ рд╡реНрдпрд╛рдХрд░рдг рдФрд░ рдЗрдирдкреБрдЯ рдлрд╝рд╛рдЗрд▓ рдкрдврд╝ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдлрд╝рд╛рдЗрд▓ рдпрд╛ рдорд╛рдирдХ рдЖрдЙрдЯрдкреБрдЯ рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рд╕рднреА 24 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рддреЛ рдЖрдк рдПрдХ рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдЯреВрд▓ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬреЛ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдмрдирд╛рдП рдЧрдП .peg рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рдорд╛рдиреНрдп рдХрд░рддрд╛ рд╣реИред рдХреНрдпрд╛ рдореИрдВ рд╕рд╣реА рд╣реВрдБ?

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:
validate_file ~/file.blah

@ рдкреЗрдкрд╛65

@jodevsa рдореИрдВ рдпрд╣реА рд╣рд╛рд╕рд┐рд▓ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ ..!

рдЬреЗрдирд░реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ tldr.js рд╕рд┐рд░реНрдл рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ рдЬрд┐рд╕реЗ рдкрд╛рд░реНрд╕ рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЖрдкрдХреЛ рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ рдЬреЛ рдРрд╕рд╛ рдХрд░рддрд╛ рд╣реИ!

1- рдлрд╝рд╛рдЗрд▓ рдкрдврд╝реЗрдВ
2- рдлрд╝рд╛рдЗрд▓ рд╕рд╛рдордЧреНрд░реА рдХреЛ tldr рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рднреЗрдЬреЗрдВ
3- рдЖрдЙрдЯрдкреБрдЯ рдкрд░рд┐рдгрд╛рдо?

рдкреАрдИрдЬреА.рдЬреЗрдПрд╕ рдЬреЗрдирд░реЗрдЯреЗрдб рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдлрдВрдХреНрд╢рди рдбреЗрдлрд┐рдирд┐рд╢рди:

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

рдЕрдкрдиреА рдЗрдЪреНрдЫрд┐рдд рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдбреЗрдЯрд╛ рдирд┐рдХрд╛рд▓реЗрдВ рдФрд░ рдкрд╛рд░реНрд╕рд░ (рдлрд╝рд╛рдЗрд▓ рд╕рд╛рдордЧреНрд░реА) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ!

рдпрджрд┐ рдЖрдк рдиреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдпрд╣рд╛рдВ рдПрдХ рдФрд░ рдареЛрд╕ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

#!/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 рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдпрд╣ рд╕рдордЭрдиреЗ рдХрд╛ рдпрд╣ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЖрдкрдиреЗ рдХреНрдпрд╛ рдХрд┐рдпрд╛
@ рдкреЗрдкрд╛65 рдЗрд╕реЗ рджреЗрдЦреЗрдВ:

#!/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

  • ~/.bashrc рдореЗрдВ $path рдореЗрдВ рдлрд╝реЛрд▓реНрдбрд░ рд╕реНрдерд╛рди рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЯрд░реНрдорд┐рдирд▓ рд░реАрд╕реЗрдЯ рдХрд░реЗрдВ

  • рдЕрдм рдЖрдк рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, check_file ~/file.txt

@mikeaustin рдореБрдЭреЗ ../lib/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

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореЗрд░рд╛ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ-рдлреВ рдкрд░реНрдпрд╛рдкреНрдд рдордЬрдмреВрдд рдирд╣реАрдВ рд╣реИ ...

@ рдкреЗрдкрд╛ 65 рдореИрдВрдиреЗ рдХреЛрдб рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рд╣реИ, рдЗрд╕реЗ рджреЛрдмрд╛рд░рд╛ рдЬрд╛рдВрдЪреЗрдВ
рдореЗрд░рд╛ рдмреБрд░рд╛ :(

@ pepa65 рдореИрдВ рдиреЛрдб v

@ рдкреЗрдкрд╛65
рдПрдирд╡реАрдПрдо, рдмрд╕ рдЗрд╕реЗ рдЖрдЬрдорд╛рдПрдВ

#!/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 рдореЗрдВ рдкреНрд░рд┐рдВрдЯрдл рдерд╛ (рдЬрд┐рд╕реЗ рдореИрдВрдиреЗ рдХрдВрд╕реЛрд▓.рд▓реЙрдЧ рд╕реЗ рдмрджрд▓ рджрд┐рдпрд╛ рдерд╛), рд▓реЗрдХрд┐рди рдлрд┐рд░ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ!
рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдЬреЛ рдореБрдЭреЗ рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖрддреА рд╣реИ рд╡рд╣ undefined рд╕рд╛рде рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рддреА рд╣реИ рдЪрд╛рд╣реЗ рдХреБрдЫ рднреА рд╣реЛред

рдЕрдЬреАрдм, рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ "рдкреНрд░рд┐рдВрдЯрдл" рдлрд╝рдВрдХреНрд╢рди рднреА рдирд╣реАрдВ рд╣реИ; рдФрд░ рднреА рдкреБрд░рд╛рдиреЗ рд╕рдВрд╕реНрдХрд░рдг
рдпрджрд┐ рдЖрдк рдЕрдкрдирд╛ рд╡реНрдпрд╛рдХрд░рдг рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд░реВрдк рд╕реЗ рдкреЛрд╕реНрдЯ рдХрд░рдирд╛ рдареАрдХ рд╕рдордЭрддреЗ рд╣реИрдВ, рддреЛ рдореЗрд░реЗ рд▓рд┐рдП рдорджрдж рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛрдЧрд╛

рдУрд╣, рдХреНрд╖рдорд╛ рдХрд░реЗрдВ, рдореЗрд░реЗ рдЦреВрдВрдЯреА рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реБрдП, рдореИрдВрдиреЗ рджреЗрдЦрд╛ рдХрд┐ рдореИрдВрдиреЗ рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ { 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) рд▓рд╛рдЗрди рдХреЛ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЖрдкрдХреА рдорджрдж рд╣реЛрдЧреА!

@ рд╣реЙрдХрд░рд╛рдЗрд╡реНрд╕ : +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ред рдореИрдВ рдорд╛рди рд░рд╣рд╛ рдерд╛ рдХрд┐ рд╡рд╣ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЬрд╛рдирддрд╛ рдерд╛ред

рд▓реЗрдХрд┐рди рдЙрд╕ рддрд░рд╣ рд╕реЗ рдпрд╣ рд╡рд┐рдЪрд╛рд░ рд╕рд╛рдордиреЗ рдЖрддрд╛ рд╣реИ рдХрд┐ рд▓реЛрдЧ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЬрд╛рдиреЗ рдмрд┐рдирд╛ рднреА PEG.js рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣ рд╕рдХрддреЗ рд╣реИрдВред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛрдЧрд╛ рдЬреЛ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдПрдХ рд╡реНрдпрд╛рдХрд░рдг рдФрд░ рдЗрдирдкреБрдЯ рдлрд╝рд╛рдЗрд▓ рдкрдврд╝ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдлрд╝рд╛рдЗрд▓ рдпрд╛ рдорд╛рдирдХ рдЖрдЙрдЯрдкреБрдЯ рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛрдЧрд╛ рдЬреЛ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдПрдХ рд╡реНрдпрд╛рдХрд░рдг рдФрд░ рдЗрдирдкреБрдЯ рдлрд╝рд╛рдЗрд▓ рдкрдврд╝ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдлрд╝рд╛рдЗрд▓ рдпрд╛ рдорд╛рдирдХ рдЖрдЙрдЯрдкреБрдЯ рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдХреНрдпрд╛ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓рд╛ рдЬрд╛рдПрдЧрд╛?

@mikeaustin @waldyrios рд╢рд╛рдпрдж рдПрдХ рдЕрд▓рдЧ "рдкреНрд░реЛрдЧреНрд░рд╛рдо" рдмрдирд╛рдиреЗ рдХреЗ рдмрдЬрд╛рдп - рдЗрд╕рдХрд╛ рдХреЗрд╡рд▓ рд░реАрдбрдореА рдореЗрдВ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ? рдРрд╕реА рдЪреАрдЬ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рдеред

рдКрдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣реЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ ..!

рд╢рд╛рдпрдж рдПрдХ рдЕрд▓рдЧ "рдХрд╛рд░реНрдпрдХреНрд░рдо" рдмрдирд╛рдиреЗ рдХреЗ рдмрдЬрд╛рдп - рдЗрд╕рдХрд╛ рдХреЗрд╡рд▓ рд░реАрдбрдореА рдореЗрдВ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ?

@mikeaustin рдХреА рдЯрд┐рдкреНрдкрдгреА рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдЕрд▓рдЧ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдЕрдВрддрд┐рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛ рд▓рд╛рдн рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдореИрдВ рдЗрд╕рд╕реЗ рд╕рд╣рдордд рд╣реВрдВред

@ рд╡рд╛рд▓реНрдбрд┐рд░рд┐рдпрд╕ рдпрд╣ рдореБрджреНрджрд╛ рдПрдХ рдкреНрд░рд╢реНрди рдерд╛, рдореИрдВ @mikeaustin рдХреЗ рд╕реБрдЭрд╛рд╡ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдореБрджреНрджрд╛ рдЦреЛрд▓рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВ, рдЬрд┐рд╕реЗ 0.11 рдХреЗ рд▓рд┐рдП рд▓рд╛рдЧреВ рдХреА рдЧрдИ рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рд┐рдП (рдпрджрд┐ рдпрд╣ рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╕рдорд╕реНрдпрд╛ рдХреЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЬреЛрдбрд╝ рд╣реИ), рд▓реЗрдХрд┐рди 1.0 рддрдХ рдзрдХреЗрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЕрдЧрд░ рдпрд╣ рдХреБрдЫ рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ, рддреЛ рдореИрдВ рдЗрд╕реЗ рдмрд╛рдж рдореЗрдВ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд╛рдкрд╕ рдзрдХреНрдХрд╛ рджреВрдВрдЧрд╛)ред рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдЯреВрд▓ рд░реАрд░рд╛рдЗрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдХреНрд╖рдорд╛ рдХрд░реЗрдВ @ Pepa65 рдкрд╣рд▓реЗ рдЬрд╡рд╛рдм рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП, рд▓реЗрдХрд┐рди рдЖрдкрдХреЗ рд╕рд╛рде рдИрдорд╛рдирджрд╛рд░ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдЬрдм рддрдХ @waldyrios рдиреЗ рдЖрдЬ рдЕрдкрдиреА рдЯрд┐рдкреНрдкрдгреА рдкреЛрд╕реНрдЯ рдирд╣реАрдВ рдХреА, рдореБрдЭреЗ рдпрд╣ рднреА рдирд╣реАрдВ рдкрддрд╛ рдерд╛ рдХрд┐ рд╕рдорд╕реНрдпрд╛ рдореМрдЬреВрдж рд╣реИ

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

mikeaustin picture mikeaustin  ┬╖  7рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

audinue picture audinue  ┬╖  13рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

brettz9 picture brettz9  ┬╖  8рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

emmenko picture emmenko  ┬╖  15рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

StoneCypher picture StoneCypher  ┬╖  6рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ