๊ฒ์ฆํ๋ .peg ํ์ผ (์จ๋ผ์ธ)์ ๋ง๋ค์์ต๋๋ค. ๋ช
๋ น ์ค์์ ์ง์์ ์ฌ์ฉํ๊ณ ์ถ์ต๋๋ค. Ubuntu 16.04 repos์์ pegjs๋ฅผ ์ค์นํ์ต๋๋ค. pegjs tldr.peg
ํ๊ณ tldr.js
ํ์ผ์ ์์ฑํ์ต๋๋ค.
๋ช ๋ น ์ค์์ ์ด๋ป๊ฒ ์ฌ์ฉํฉ๋๊น? ํ์ธํ๊ณ ์ถ์ ํ์ผ์ด ์์ต๋๋ค.
๋ฐ๋ผ์ ์์ฑ ํ .peg๋ฅผ ์ฌ์ฉํ๋ ๋ช ๋ น ์ค ๋๊ตฌ๋ฅผ ๋ง๋ค๊ณ ๋ช ๋ น ์ค ๋งค๊ฐ ๋ณ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ์ผ์ ์ ํจ์ฑ์ ๊ฒ์ฌํ๋ ค๊ณ ํฉ๋๋ค. ๋ด๊ฐ ๋ง์?
์ :
validate_file ~/file.blah
@ pepa65
@jodevsa ๊ทธ๊ฒ ์ ๊ฐ ๋ฌ์ฑํ๋ ค๋ ๊ฒ์ ๋๋ค ..!
์์ฑ ๋ tldr.js๋ ๊ตฌ๋ฌธ ๋ถ์ ํจ์์ ์ํด ํธ์ถ๋๋ ์ผ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ผ๋ฟ์ ๋๋ค.์ด ์์ ์ ์ํํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํด์ผํฉ๋๋ค!
1- ํ์ผ ์ฝ๊ธฐ
2- tldr ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํ์ผ ๋ด์ฉ ๋ณด๋ด๊ธฐ
3- ์ถ๋ ฅ ๊ฒฐ๊ณผ?
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 check_file
~ / .bashrc์ $ path์ ํด๋ ์์น๋ฅผ ์ถ๊ฐํ๊ณ ํฐ๋ฏธ๋์ ์ฌ์ค์ ํ์ญ์์ค.
์ด์ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค. check_file ~ / file.txt
@mikeaustin node-pegjs (๋ฐ peg)๊ฐ ์ค์น๋์ด ์์ด๋ ../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
๋ด javascript-fu๊ฐ ์ถฉ๋ถํ ๊ฐํ์ง ์์ ๊ฒ ๊ฐ์ต๋๋ค ...
@ pepa65 ์ฝ๋๋ฅผ ์
๋ฐ์ดํธํ์ต๋๋ค. ๋ค์ ํ์ธํ์ญ์์ค.
๋ด ์๋ชป์ด์ผ :(
@ pepa65 ๋ ธ๋ v 8.0.0์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ๋ค๋ฅธ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ๊ฐ "let"๋ฐ "const"๋ฅผ var๋ก
๋ฟก๋ฟก
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
์ถ๋ ฅ์ ๋๋ธ๋ค๋ ๊ฒ์
๋๋ค.
์ด์ํ๊ฒ๋ ์๋ฐ ์คํฌ๋ฆฝํธ๋ "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
(ํ์ผ ์ด๋ฆ์ ํ์ธํ ํ์ผ์ ์์น์
๋๋ค).
์ข์ ๋ณด์ธ๋ค! ๋ ์์ ํ ์์ @jodevsa๋ฅผ ๋ง๋ค์ด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ๋๋ ๊ทธ๊ฐ JavaScript๋ฅผ ์๊ณ ์๋ค๊ณ ๊ฐ์ ํ๊ณ ์์๋ค.
๊ทธ๋ฌ๋ ๊ทธ๋ฐ ์ข ๋ฅ์ ์ฌ๋๋ค์ JavaScript๋ฅผ ์ ํ ๋ชฐ๋ผ๋ PEG.js๋ฅผ ์ฌ์ฉํ๊ณ ์ถ์ด ํ ์ ์๋ค๋ ์๊ฐ์ ๊ฐ๊ฒ๋ฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๋ฌธ๋ฒ๊ณผ ์ ๋ ฅ ํ์ผ์ ์ฝ๊ณ ํ์ผ์ด๋ ํ์ค ์ถ๋ ฅ์ผ๋ก ์ถ๋ ฅ ํ ์์๋ ํ๋ก๊ทธ๋จ์ ์ ๊ณตํ๋ ๊ฒ์ด ํธ๋ฆฌํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ๋ฌธ๋ฒ๊ณผ ์ ๋ ฅ ํ์ผ์ ์ฝ๊ณ ํ์ผ์ด๋ ํ์ค ์ถ๋ ฅ์ผ๋ก ์ถ๋ ฅ ํ ์์๋ ํ๋ก๊ทธ๋จ์ ์ ๊ณตํ๋ ๊ฒ์ด ํธ๋ฆฌํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ทธ๋ผ ์ด๋ฒ ํธ๋ฅผ ๋ค์ ์ด๊ฒ ์ต๋๊น?
@mikeaustin @waldyrious ์๋ง๋ ๋ณ๋์ "ํ๋ก๊ทธ๋จ"์ ๋ง๋๋ ๋์ -์ด๊ฒ์ readme์์ ์ธ๊ธ ํ ์ ์์ต๋๊น? ๊ทธ๋ฌํ ๊ฒ์ ๊ตฌํํ๋ ์๋ฅผ ๋ค์ด.
์์ ์์ ์์ ๋ฅผ ์์ ๋กญ๊ฒ ์ฌ์ฉ
์๋ง๋ ๋ณ๋์ "ํ๋ก๊ทธ๋จ"์ ๋ง๋๋ ๋์ -์ด๊ฒ์ readme์์ ์ธ๊ธ ํ ์ ์์ต๋๊น?
@mikeaustin ์ ์๊ฒฌ์ ๋ณ๋์ ํ๋ก๊ทธ๋จ์ด ์ต์ข ์ฌ์ฉ์์๊ฒ ํธ์ ์ด์ ์ ์ ๊ณตํ๋ค๊ณ ์ ์ํ๋ฉฐ ์ด์ ๋์ํฉ๋๋ค.
@waldyrious ์ด ๋ฌธ์ ๋ ์ง๋ฌธ์ด์์ต๋๋ค. ๊ฒ ์ต๋๋ค. 0.11์ ๋ํด ๊ตฌํ ๋ ๊ธฐ๋ฅ (๋ฌธ์ ๊ฐ์๋ ๊ฐ๋จํ ์ถ๊ฐ ์ธ ๊ฒฝ์ฐ)์ ํ์ธํด์ผํ์ง๋ง 1.0 ( ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ ๋์ค์ ๋ค์ ๋ถ๋ฅํ๋๋ก ํธ์ํ๊ฒ ์ต๋๋ค). ๋ช ๋ น ์ค ๋๊ตฌ ์ฌ ์์ฑ์ ๋ง์น ํ์๋ ๊ตฌํ์ด ๊ฐ๋จํด์ผํฉ๋๋ค.
์ด์ ์ ๋ต์ฅํ์ง ์์ @ pepa65 ์๊ฒ ์ฃ์กํ์ง๋ง ์์งํ ๋ง์ ๋๋ฆฌ๋ฉด @waldyrious ๊ฐ ์ค๋ ๊ทธ์ ๋๊ธ์ ๊ฒ์ ํ ๋๊น์ง ๋ฌธ์ ๊ฐ ์กด์ฌํ๋์ง์กฐ์ฐจ ๋ชฐ๋์ต๋๋ค ๐
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ข์ ๋ณด์ธ๋ค! ๋ ์์ ํ ์์ @jodevsa๋ฅผ ๋ง๋ค์ด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ๋๋ ๊ทธ๊ฐ JavaScript๋ฅผ ์๊ณ ์๋ค๊ณ ๊ฐ์ ํ๊ณ ์์๋ค.
๊ทธ๋ฌ๋ ๊ทธ๋ฐ ์ข ๋ฅ์ ์ฌ๋๋ค์ JavaScript๋ฅผ ์ ํ ๋ชฐ๋ผ๋ PEG.js๋ฅผ ์ฌ์ฉํ๊ณ ์ถ์ด ํ ์ ์๋ค๋ ์๊ฐ์ ๊ฐ๊ฒ๋ฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๋ฌธ๋ฒ๊ณผ ์ ๋ ฅ ํ์ผ์ ์ฝ๊ณ ํ์ผ์ด๋ ํ์ค ์ถ๋ ฅ์ผ๋ก ์ถ๋ ฅ ํ ์์๋ ํ๋ก๊ทธ๋จ์ ์ ๊ณตํ๋ ๊ฒ์ด ํธ๋ฆฌํ๋ค๊ณ ์๊ฐํฉ๋๋ค.