рдореИрдВрдиреЗ рдПрдХ .peg рдлрд╝рд╛рдЗрд▓ (рдСрдирд▓рд╛рдЗрди) рдмрдирд╛рдИ рд╣реИ рдЬреЛ рдорд╛рдиреНрдп рд╣реИред рдореИрдВ рдХрдорд╛рдВрдбрд▓рд╛рдЗрди рдкрд░ рдШрд░ рдкрд░ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдореИрдВрдиреЗ Ubuntu 16.04 рд░реЗрдкреЛ рд╕реЗ pegjs рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдПред рдореИрдВрдиреЗ pegjs tldr.peg
рдФрд░ рдЗрд╕рдиреЗ tldr.js
рдлрд╝рд╛рдЗрд▓ рддреИрдпрд╛рд░ рдХреАред
рдореИрдВ рдЗрд╕реЗ рдХрдорд╛рдВрдбрд▓рд╛рдЗрди рдкрд░ рдХреИрд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВ? рдореЗрд░реЗ рдкрд╛рд╕ рдлрд╛рдЗрд▓реЗрдВ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдореИрдВ рдЬрд╛рдВрдЪрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред
рддреЛ рдЖрдк рдПрдХ рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдЯреВрд▓ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬреЛ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдмрдирд╛рдП рдЧрдП .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 рдиреЗ рдЖрдЬ рдЕрдкрдиреА рдЯрд┐рдкреНрдкрдгреА рдкреЛрд╕реНрдЯ рдирд╣реАрдВ рдХреА, рдореБрдЭреЗ рдпрд╣ рднреА рдирд╣реАрдВ рдкрддрд╛ рдерд╛ рдХрд┐ рд╕рдорд╕реНрдпрд╛ рдореМрдЬреВрдж рд╣реИ
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
рдЕрдЫрд╛ рд▓рдЧрддрд╛ рд╣реИ! рдПрдХ рдФрд░ рдкреВрд░реНрдг рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, @jodevsaред рдореИрдВ рдорд╛рди рд░рд╣рд╛ рдерд╛ рдХрд┐ рд╡рд╣ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЬрд╛рдирддрд╛ рдерд╛ред
рд▓реЗрдХрд┐рди рдЙрд╕ рддрд░рд╣ рд╕реЗ рдпрд╣ рд╡рд┐рдЪрд╛рд░ рд╕рд╛рдордиреЗ рдЖрддрд╛ рд╣реИ рдХрд┐ рд▓реЛрдЧ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЬрд╛рдиреЗ рдмрд┐рдирд╛ рднреА PEG.js рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣ рд╕рдХрддреЗ рд╣реИрдВред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛрдЧрд╛ рдЬреЛ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдПрдХ рд╡реНрдпрд╛рдХрд░рдг рдФрд░ рдЗрдирдкреБрдЯ рдлрд╝рд╛рдЗрд▓ рдкрдврд╝ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдлрд╝рд╛рдЗрд▓ рдпрд╛ рдорд╛рдирдХ рдЖрдЙрдЯрдкреБрдЯ рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдХрд░ рд╕рдХрддрд╛ рд╣реИред