Pegjs: ์‹œ๋งจํ‹ฑ ์•ก์…˜์˜ ์•ฝ์–ด

์— ๋งŒ๋“  2018๋…„ 09์›” 10์ผ  ยท  13์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: pegjs/pegjs

์˜๋ฏธ๋ก ์  ํ–‰๋™์— ๋Œ€ํ•œ ์•ฝ์นญ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด { return value } ๋ฅผ ์“ฐ๋Š” ๋Œ€์‹  ์ด๋‹ˆ์…œ๋ผ์ด์ €์— ์ •์˜๋œ { extract } ๋ฅผ ์”๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด:

{
  function extract(value) {
    return value;
  }
  function concat(head, tail) {
    return head ? [head].concat(tail) : [];
  }
  function toAddExpr(head, tail) {
    return { type: 'addExpr', expressions: concat(head, tail) };
  }
}

List
  = '(' _ head:Item? tail:( _ ',' _ value:Item { extract } )* _ ')' { concat }

// Another kind of list
Add
  = '(' _ head:Multiply? tail:( _ '+' _ value:Multiply { extract } )* _ ')' { toAddExpr }

์ฒซ์งธ, ์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ๊ธฐ๋Šฅ์„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค... ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์œผ๋กœ :smile:
๋‘˜์งธ, ์ด๊ฒƒ์€ ๋ฌธ๋ฒ•์„ ์ข€ ๋” ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ์•ก์…˜ ์†๊ธฐ์— ํฌํ•จ๋œ ํ‘œํ˜„์‹์ด ์‹๋ณ„์ž { foo } ๋Œ€์‹  ๋ฉค๋ฒ„ ํ‘œํ˜„์‹ { foo.bar.baz } ๋•Œ ๋” ์œ ์šฉํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋ฌธ๋ฒ• ์ž‘์„ฑ์ž๋Š” ๊ฐ์ฒด ๋˜๋Š” ๋ชจ๋“ˆ ๋‚ด๋ถ€์—์„œ ๊ธฐ๋Šฅ์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

discussion feature

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์‚ฌ์‹ค, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํšจ๊ณผ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

CodeBlock "code block"
  = "=>" _ expession:CallExpression {
       return `return ${ expession };`;
     }
  / "{" <strong i="6">@Code</strong> "}"
  / "{" { error("Unbalanced brace."); }

// Will be based on ECMAScript's CallExpression
CallExpression
  = ...
  / MemberExpression

// Will be based on ECMAScript's MemberExpression
MemberExpression
  = ...
  / ValidIdentifier

// Change `LabelIdentifier` into `ValidIdentifier`

์ด ๋ฐฉ๋ฒ•์€ ์—ฌ์ „ํžˆ โ€‹โ€‹ECMAScript์˜ ๊ธฐ๋ณธ ํ‘œํ˜„์‹(์ˆซ์ž, ๋ถ€์šธ, ๋ฐฐ์—ด ๋“ฑ)๊ณผ ๊ฐ™์€ ์ผ๋ถ€ ํ•ญ๋ชฉ์„ ์ธ์ˆ˜๋กœ ์‚ฌ์šฉํ•˜์—ฌ ํ†ตํ•ฉํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ถ”๊ฐ€ํ•  ํ•ญ๋ชฉ์„ ์‹ ์ค‘ํ•˜๊ฒŒ ํŒŒ์•…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.


๊ท ํ˜• ๋ธŒ๋ž˜ํ‚ท ๋ฐ ์ค‘๊ด„ํ˜ธ

์ด๊ฒƒ์€ ์ ์ ˆํ•œ JavaScript ํŒŒ์„œ๊ฐ€ PEG.js ํŒŒ์„œ์— ๋‚ด์žฅ๋  ๋•Œ๊นŒ์ง€ ์ˆ˜์ •๋˜์ง€ ์•Š์„ ๊ฒƒ์ด์ง€๋งŒ, ์†”์งํžˆ ๋งํ•ด์„œ ๋‹ค๋ฅธ ์–ธ์–ด(C, PHP, TypeScript ๋“ฑ), ๊ทธ๋ฆฌ๊ณ  ์–ธ์  ๊ฐ€๋Š” ํŒŒ์„œ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์ปดํ“จํ„ฐ ์–ธ์–ด๋„ ์ž‘์—…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


_PEG.js์ด v0.12_ ์™ธ์—๋„, ๋‚˜๋Š”์— ์ž‘์—… ํ•  OpenPEG ์ถฉ๋ถ„ํ•œ ๊ธฐ๋Šฅ์ด ๊ฐ™์€ ํ”„๋กœ์ ํŠธ๋ฅผ ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋ฐ˜ ์žˆ๋„๋ก ๊ธฐ๋ณธ์ ์œผ๋กœ ํฌํ•จ ๋œ ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ ํŒŒ์„œ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ณ  PEG.js์˜ ๋ฒ„์ „์„ ๋ฐ•ํƒˆ ์ธ NPM ํŒจํ‚ค์ง€๋ฅผ ์ œ๊ณต ํ•  ๊ฒƒ์ด๋‹ค,ํ•˜์ง€๋งŒ, PEG.js๋Š” ๋ฐฑ์—”๋“œ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. _v0.12_๊ฐ€ ๋‚˜์˜ค๋ฉด ์ปค์Šคํ…€ ํŒŒ์„œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ชจ๋“  ํ”Œ๋Ÿฌ๊ทธ์ธ ํ”„๋กœ์ ํŠธ์— OpenPEG์— ๋Œ€ํ•œ ์•Œ๋ฆผ์„ ์ œ๊ณตํ•˜๊ณ  v1 ์ด์ „์— ์ „์ฒด ECMAScript 2015 ํŒŒ์„œ๋ฅผ PEG.js ๋ฌธ๋ฒ• ํŒŒ์„œ์— ๊ตฌํ˜„ํ•˜๋„๋ก ๋…ธ๋ ฅํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  13 ๋Œ“๊ธ€

ํฅ๋ฏธ๋กœ์šด ์•„์ด๋””์–ด์ง€๋งŒ ๊ฐœ์ธ์ ์œผ๋กœ ๊ทธ๊ฒƒ์ด ํ•จ์ˆ˜์— ์ „๋‹ฌ๋˜๋Š” ์ธ์ˆ˜๊ฐ€ ๋ช…ํ™•ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋” ๋ช…ํ™•ํ•œ ๋ฐฉ๋ฒ•์ด ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ "์‚ฌ์šฉ์ž ์ •์˜" ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์ผ๋ฐ˜ ํ•จ์ˆ˜ ํ˜ธ์ถœ๊ณผ ํ˜ผํ•ฉํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๊ฐ„๋‹จํ•œ ๊ฒฝ์šฐ์ฒ˜๋Ÿผ ๊นจ๋—ํ•ด ๋ณด์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

#235์˜ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ => ๊ตฌ๋ฌธ์„ ํ™”์‚ดํ‘œ ๊ธฐ๋Šฅ๊ณผ ํ•จ๊ป˜ ์ œ์•ˆํ–ˆ๋Š”๋ฐ, ์ƒ๋‹นํžˆ ๊น”๋”ํ•˜๊ณ  ๊ฐ„๊ฒฐํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

  = '(' expr:some_expression ')' => expr
  ;

์ €๋Š” ์†๊ธฐ ๊ตฌ๋ฌธ์— ๋Œ€ํ•ด ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

  • => expr; _(๊ตฌ๋ฌธ ์ง€์› ํ•„์š”)_
  • { => expr } _(์ง€๊ธˆ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ํฌ์žฅ์„ ํ’€์–ด์•ผ ํ•จ)_
  • { > expr } _(๊ตฌ๋ฌธ ์ง€์› ํ•„์š”)_

์•„์ง ๊ฒฐ์ •๋˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ๋…ผ์˜๋ฅผ ์œ„ํ•ด ์—ด๋ ค ์žˆ์Šต๋‹ˆ๋‹ค.

OP๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์— ๊ด€ํ•ด์„œ๋Š” Acorn ๋˜๋Š” @babel/parser๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹๋ณ„์ž ๋˜๋Š” ๋ฉค๋ฒ„ ํ‘œํ˜„์‹์˜ ๋ž˜ํ•‘์„ ํ’€๊ณ  ํ˜ธ์ถœ ํ‘œํ˜„์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค. ๋ ˆ์ด๋ธ”์„ ์ธ์ˆ˜๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์ƒ์„ฑ๋œ ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

=> expr;

๋‚ด ์˜๊ฒฌ์œผ๋กœ๋Š” ์ตœ๊ณ .

{ => expr }

Javascript ๊ตฌ๋ฌธ IMO์™€ ์ถฉ๋Œํ•ฉ๋‹ˆ๋‹ค. { } ์žˆ์œผ๋ฏ€๋กœ ์ „์ฒด ํ™”์‚ดํ‘œ ํ•จ์ˆ˜( () => )

{ > expr}

PegJS ๋˜๋Š” Javascript์˜ ๋‹ค๋ฅธ ๊ตฌ๋ฌธ๊ณผ ์•ฝ๊ฐ„ ์ง๊ตํ•˜์ง€๋งŒ ์ฃผ๋กœ ์ค‘๊ด„ํ˜ธ ์•ˆ์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— "์ด๋Š” ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์•ฝ์‹" IMO๋ฅผ ์ฆ‰์‹œ ์ฝ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. {=> expr} ์™€ ๊ฐ™์€ ์ธ์ˆ˜ , Javascript๊ฐ€ ์žˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค.


๋˜ํ•œ {} ์— non-JS ๊ตฌ๋ฌธ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ๊ตฌ๋ฌธ ํ•˜์ด๋ผ์ดํ„ฐ, ๋ฆฐํ„ฐ ๋“ฑ์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์ €๋Š” ๋ฐ˜๋Œ€ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋˜ ๋‹ค๋ฅธ ์˜ต์…˜์„ ์ œ์•ˆํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์•„๋งˆ๋„ > ์ž์ฒด(์ˆ ์–ด ๋ธ”๋ก ๋‚ด๋ถ€๊ฐ€ ์•„๋‹˜)์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทœ์น™์„ ์„ธ๋กœ๋กœ ๋ฐฐ์น˜ํ•  ๋•Œ ์ •๋ ฌ์„ ์œ ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

    = foo:bar qux:(' '+ @qix)+
    > {foo, qux}
    ;

๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ธ๋ผ์ธ

some_rule = foo:bar qux:(' '+ @qix)+ > {foo, qux};

'=>'์— ์„ธ๋ฏธ์ฝœ๋ก ์ด ํ•„์š”ํ•œ ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์˜ˆ๋ฅผ ๋“ค์–ด buildList()๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ์ค‘์ฒฉ ์ฝ”๋“œ์—์„œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

  = "(" _ head:Expression _ tail:("," _ expr:Expression => expr)* ")" {
      return [head, ...tail]
    }

๋งค์ง ์ธ๋ฑ์Šค(์•„๋ž˜)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์ด๊ฒƒ์ด ๋” ๊น”๋”ํ•ฉ๋‹ˆ๋‹ค. ๋˜ ๋‹ค๋ฅธ ์˜ต์…˜์€ ์ค‘์ฒฉ ๋ ˆ์ด๋ธ”์„ ์ฐธ์กฐํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์˜ˆ: ("," _ tail:Expression)* ")"

  = "(" _ head:Expression _ tail:("," _ Expression)* ")" {
      return buildList(head, tail, 2)
    }

parser.pegjs๋ฅผ ๋ณด๊ณ  ์žˆ์—ˆ๋Š”๋ฐ 434ํ–‰ ์ฃผ์œ„์— CodeBlock์ด ์žˆ๋Š” ๊ฒƒ์„ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์„ ์‹œ๋„ํ•˜๋ ค๋ฉด ๋ฌด์—‡์„ํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ? ๊ทœ์น™ ์ฝ”๋“œ๋Š” ๋‹จ์ˆœํžˆ '.'์ธ SourceCharacter๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค.

CodeBlock "code block"
  = "=>" __ <strong i="13">@Code</strong> // this?
  / "{" <strong i="14">@Code</strong> "}"

@mikeaustin ๋„ค, ๋งž์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ์‹œํ€€์Šค๋ฅผ ๋๋‚ผ ์œ„์น˜๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์œผ๋ฏ€๋กœ => ์ดํ›„์— ๋ชจ๋“  ๊ฒƒ์„ ์†Œ๋น„ํ•ฉ๋‹ˆ๋‹ค.

"์ฝ”๋“œ"๊ฐ€ ๋Œ€๊ด„ํ˜ธ์™€ ์ค‘๊ด„ํ˜ธ์˜ ๊ท ํ˜•์„ ๋งž์ถ”๊ณ  LineTerminator๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์ข€ ๋” ๋˜‘๋˜‘ํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? ์ „์ฒด JavaScript์— ๋Œ€ํ•ด ์•Œ ํ•„์š”๋Š” ์—†์ง€๋งŒ ์ƒ๊ฐ๋ณด๋‹ค ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์‹ค, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํšจ๊ณผ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

CodeBlock "code block"
  = "=>" _ expession:CallExpression {
       return `return ${ expession };`;
     }
  / "{" <strong i="6">@Code</strong> "}"
  / "{" { error("Unbalanced brace."); }

// Will be based on ECMAScript's CallExpression
CallExpression
  = ...
  / MemberExpression

// Will be based on ECMAScript's MemberExpression
MemberExpression
  = ...
  / ValidIdentifier

// Change `LabelIdentifier` into `ValidIdentifier`

์ด ๋ฐฉ๋ฒ•์€ ์—ฌ์ „ํžˆ โ€‹โ€‹ECMAScript์˜ ๊ธฐ๋ณธ ํ‘œํ˜„์‹(์ˆซ์ž, ๋ถ€์šธ, ๋ฐฐ์—ด ๋“ฑ)๊ณผ ๊ฐ™์€ ์ผ๋ถ€ ํ•ญ๋ชฉ์„ ์ธ์ˆ˜๋กœ ์‚ฌ์šฉํ•˜์—ฌ ํ†ตํ•ฉํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ถ”๊ฐ€ํ•  ํ•ญ๋ชฉ์„ ์‹ ์ค‘ํ•˜๊ฒŒ ํŒŒ์•…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.


๊ท ํ˜• ๋ธŒ๋ž˜ํ‚ท ๋ฐ ์ค‘๊ด„ํ˜ธ

์ด๊ฒƒ์€ ์ ์ ˆํ•œ JavaScript ํŒŒ์„œ๊ฐ€ PEG.js ํŒŒ์„œ์— ๋‚ด์žฅ๋  ๋•Œ๊นŒ์ง€ ์ˆ˜์ •๋˜์ง€ ์•Š์„ ๊ฒƒ์ด์ง€๋งŒ, ์†”์งํžˆ ๋งํ•ด์„œ ๋‹ค๋ฅธ ์–ธ์–ด(C, PHP, TypeScript ๋“ฑ), ๊ทธ๋ฆฌ๊ณ  ์–ธ์  ๊ฐ€๋Š” ํŒŒ์„œ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์ปดํ“จํ„ฐ ์–ธ์–ด๋„ ์ž‘์—…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


_PEG.js์ด v0.12_ ์™ธ์—๋„, ๋‚˜๋Š”์— ์ž‘์—… ํ•  OpenPEG ์ถฉ๋ถ„ํ•œ ๊ธฐ๋Šฅ์ด ๊ฐ™์€ ํ”„๋กœ์ ํŠธ๋ฅผ ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋ฐ˜ ์žˆ๋„๋ก ๊ธฐ๋ณธ์ ์œผ๋กœ ํฌํ•จ ๋œ ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ ํŒŒ์„œ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ณ  PEG.js์˜ ๋ฒ„์ „์„ ๋ฐ•ํƒˆ ์ธ NPM ํŒจํ‚ค์ง€๋ฅผ ์ œ๊ณต ํ•  ๊ฒƒ์ด๋‹ค,ํ•˜์ง€๋งŒ, PEG.js๋Š” ๋ฐฑ์—”๋“œ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. _v0.12_๊ฐ€ ๋‚˜์˜ค๋ฉด ์ปค์Šคํ…€ ํŒŒ์„œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ชจ๋“  ํ”Œ๋Ÿฌ๊ทธ์ธ ํ”„๋กœ์ ํŠธ์— OpenPEG์— ๋Œ€ํ•œ ์•Œ๋ฆผ์„ ์ œ๊ณตํ•˜๊ณ  v1 ์ด์ „์— ์ „์ฒด ECMAScript 2015 ํŒŒ์„œ๋ฅผ PEG.js ๋ฌธ๋ฒ• ํŒŒ์„œ์— ๊ตฌํ˜„ํ•˜๋„๋ก ๋…ธ๋ ฅํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

FWIW, ๋‚˜๋Š” ์ด๊ฒƒ์„ ์œ„ํ•ด ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด์„ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋‚ด ํ…์ŠคํŠธ ํŽธ์ง‘๊ธฐ์—์„œ JS์˜ ๊ตฌ๋ฌธ ๊ฐ•์กฐ ํ‘œ์‹œ๋ฅผ ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค...

exports = module.exports = functionBodies`${grammarScript}
...
objectText =
    head:word
    rest:(_txt_ word)*
    ${f=>{
        return new Txt(rest.reduce((a,b)=>([...a,...b]),[head]))
        }}
word = ch:(wordCharacter/escapedCharacter)+ ${chJoin}
...
`
function functionBodies(glue, ...fns){
    return glue.map( (str,i) => str + (fns[i]||'').toString().replace(/^[^{]*/,'').replace(/[^}]*$/, '') ).join('')
    }

function chJoin(ch){return ch.join('')}

์ œ์•ˆ๋œ ํŒŒ์ดํ”„ ์—ฐ์‚ฐ์ž(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Pipeline_operator)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ฅผ ์š”์ฒญํ•˜๊ธฐ ๋•Œ๋ฌธ์—?

{
  function extract(value) {
    return value;
  }
  function concat(head, tail) {
    return head ? [head].concat(tail) : [];
  }
  function toAddExpr(head, tail) {
    return { type: 'addExpr', expressions: concat(head, tail) };
  }
}

List
  = '(' _ head:Item? tail:( _ ',' _ value:Item |> extract )* _ ')' |> concat

// Another kind of list
Add
  = '(' _ head:Multiply? tail:( _ '+' _ value:Multiply |> extract  )* _ ')' |> toAddExpr

์ด๋Ÿฐ ์ผ์ด ์ผ์–ด๋‚˜์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์งง์€ ๊ตฌ๋ฌธ์ด ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ™”์‚ดํ‘œ๋ฅผ ์˜†์œผ๋กœ ๋ผ์šฐ๋ ค๊ณ  ํ•˜๋Š” ๋Œ€์‹  ์ •์ƒ์ ์œผ๋กœ ํ™”์‚ดํ‘œ๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์ด ์ค‘ ์–ด๋Š ๊ฒƒ๋„ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๊น”๋”ํ•œ ์•„์ด๋””์–ด์ด์ง€๋งŒ JavaScript์— ๋น„ํ•ด ๊ด‘๋ฒ”์œ„ํ•œ ๋ฌธ๋ฒ• ๋ชจํ˜ธ์„ฑ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. JS๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๊ณ  with ์‚ฌํƒœ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๊ธฐ์–ตํ•˜๋Š” ์‚ฌ๋žŒ์€ ์ด๊ฒƒ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ํŒŒ์„œ๋ฅผ ์ฃฝ์ผ ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฉ‹์ง„ ์ƒˆ ๊ฒƒ์„ ๋งŒ๋“ค๋ ค๊ณ  ํ•˜๋Š” ๋Œ€์‹  Javascript๋ฅผ ์ง€์›ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ES6๋ณด๋‹ค ์˜ค๋ž˜๋œ ๊ฒƒ์ด๊ณ  ES6์€ 2015๋…„๋ถ€ํ„ฐ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ 6๋…„ ์ „์— ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์–ด๋–ค ๋ฐœ๋ช…๋„ ์ผ์–ด๋‚˜์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

ํŒŒ์ดํ”„ ์—ฐ์‚ฐ์ž๋Š” ์‹ฌ๊ฐํ•œ ๊ฒฐํ•จ์ด ์žˆ์œผ๋ฉฐ ์•„๋งˆ๋„ ์‹ค์ œ๋กœ Javascript๋กœ ๋งŒ๋“ค์ง€ ๋ชปํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํŒŒ์ดํ”„ ์—ฐ์‚ฐ์ž๊ฐ€ ์›๋ž˜ ํŒŒ์ƒ๋œ ์–ธ์–ด(F#)์™€ ์ด๋ฅผ ๋Œ€์ค‘ํ™”ํ•œ ์–ธ์–ด(Elixir)๋Š” ๋ชจ๋‘ ์ด๋ฅผ ๊ฑฐ๋ถ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ์ด๊ฒƒ์€ ์–ด๋–ค ์˜๋ฏธ์—์„œ ๋ฐฐ๊ด€์ด ์•„๋‹™๋‹ˆ๋‹ค.

PEG๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ์„ฑ๊ณต์ ์ธ ์ด์œ ๋Š” ๊ทธ๊ฒƒ์ด ์ตœ์†Œํ™”๋˜๊ณ  ์–ธ์–ด์— ๊ฐ€๊น๊ธฐ ๋•Œ๋ฌธ์— ๋น ๋ฅด๊ณ  ์ž‘์œผ๋ฉฐ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ES6๋ณด๋‹ค ์˜ค๋ž˜๋œ ๊ฒƒ์ด๊ณ  ES6์€ 2015๋…„๋ถ€ํ„ฐ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ 6๋…„ ์ „์— ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์–ด๋–ค ๋ฐœ๋ช…๋„ ์ผ์–ด๋‚˜์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

์Œ. ๊ทธ๊ฒƒ์€ ๋‚˜์—๊ฒŒ ์ƒˆ๋กœ์šด ์†Œ์‹์ด๋‹ค. ํ™•์žฅํ•  ์ƒ๊ฐ?

PEG๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ์„ฑ๊ณต์ ์ธ ์ด์œ ๋Š” ๊ทธ๊ฒƒ์ด ์ตœ์†Œํ™”๋˜๊ณ  ์–ธ์–ด์— ๊ฐ€๊น๊ธฐ ๋•Œ๋ฌธ์— ๋น ๋ฅด๊ณ  ์ž‘์œผ๋ฉฐ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

PEG(์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ฐœ๋…์œผ๋กœ)๊ฐ€ ์„ฑ๊ณตํ•œ ์ด์œ ๋Š” ๋ณต์žกํ•œ ๋ฌธ๋ฒ•(์žฌ๊ท€ ๋“ฑ)์„ ๋‹จ์ˆœํ•œ ๋ฐฉ์‹์œผ๋กœ ํ‘œํ˜„ํ•˜๋Š” ๋Šฅ๋ ฅ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. Packrat์€ ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋ฐœ๋ช…๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ตฌ๋ฌธ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค.

ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ES6๋ณด๋‹ค ์˜ค๋ž˜๋œ ๊ฒƒ์ด๊ณ  ES6์€ 2015๋…„๋ถ€ํ„ฐ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ 6๋…„ ์ „์— ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์–ด๋–ค ๋ฐœ๋ช…๋„ ์ผ์–ด๋‚˜์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

์Œ. ๊ทธ๊ฒƒ์€ ๋‚˜์—๊ฒŒ ์ƒˆ๋กœ์šด ์†Œ์‹์ด๋‹ค. ํ™•์žฅํ•  ์ƒ๊ฐ?

๋‚˜๋Š” ๋‹น์‹ ์ด ๋ฌด์—‡์„ ๋ฌป๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ES6๋ณด๋‹ค ์˜ค๋ž˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ES6์—์„œ ๋‘ ๋ฒˆ์งธ๋กœ ํฐ ์‹ธ์›€์ด์—ˆ๊ณ , ES4๋ฅผ ํƒˆ์„ ์‹œํ‚จ ๊ฒƒ๊ณผ ES5+๋ฅผ ํƒˆ์„ ์‹œํ‚จ ๊ฒƒ์ž…๋‹ˆ๋‹ค. 90๋…„๋Œ€ ์ค‘๋ฐ˜๋ถ€ํ„ฐ ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์ด ๊ทธ ์‹œ์ ์—์„œ E4X์— ์ด๋ฏธ ์กด์žฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๊ฒƒ๋“ค์„ ์š”๊ตฌํ•ด ์™”์œผ๋ฉฐ, ๊ตฌ๊ธ€๊ณผ ์• ํ”Œ์ด ๋งˆ์ดํฌ๋กœ์†Œํ”„ํŠธ๊ฐ€ ๋ฌด์—‡์ด๋“  ๋ฐœ๋ช…ํ•œ ์ ์ด ์žˆ๋‹ค๊ณ  Hixie๋ฅผ ๋น„๋‚œํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ œ๊ฑฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ E4X๋ฅผ React๋กœ ์•Œ๊ณ  ์žˆ๊ณ  Facebook์ด ๊ทธ๊ฒƒ์„ ๋ฐœ๋ช…ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํŽ˜์ด์Šค๋ถ์€ ํ•˜์ดํผ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋„์šฉํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. Hyperscript ์‚ฌ๋žŒ์€ ๊ทธ๊ฐ€ ์ด์ „ IE์—์„œ ์œ ์šฉํ•œ ๊ฒƒ์„ ๋‹ค์‹œ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์ด ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค.

ํ…œํ”Œ๋ฆฟ ๋ฌธ์ž์—ด๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ES6์—์„œ ์™„์ „ํžˆ ์ œ์™ธ๋  ์˜ˆ์ •์ด์—ˆ์ง€๋งŒ Coffeescript๊ฐ€ ๋“ฑ์žฅํ•˜์—ฌ JS ์ปค๋ฎค๋‹ˆํ‹ฐ์— ๋‘ ๊ฐ€์ง€๋ฅผ ๋ชจ๋‘ ์ œ๊ณตํ–ˆ์œผ๋ฉฐ JS ์ปค๋ฎค๋‹ˆํ‹ฐ๋Š” ECMA ์‚ฌ๋žŒ๋“ค์ด ์›€์ง์ผ ๋•Œ๊นŒ์ง€ ์†Œ๋ฆฌ์ณค์Šต๋‹ˆ๋‹ค. 18๊ฐœ์›”๋ฐ–์— ๊ฑธ๋ฆฌ์ง€ ์•Š์•˜๋‹ค

ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์—ฌ๊ธฐ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ชจ๋“  ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. 2018๋…„์— ์ด ์Šค๋ ˆ๋“œ์—์„œ ๋ฌธ์ œ๋ฅผ ์ œ๊ธฐํ•œ ์‚ฌ๋žŒ์ด ๋ฐ”๋กœ ๋‹น์‹ ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์‹ ์„ ์ง€์›ํ•˜๋ ค๊ณ ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚˜์—๊ฒŒ ๋” ์ค‘์š”ํ•œ ๊ฒƒ์€ ํ™”์‚ดํ‘œ ๊ธฐ๋Šฅ์œผ๋กœ ์™„๋ฃŒ๋˜๋ฉด ์•„๋ฌด๊ฒƒ๋„ ์ถ”๊ฐ€๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

JS์™€ Peg์˜ ์ฐจ์ด์ ์€ ์ ˆ๋Œ€์ ์œผ๋กœ ๋ฏธ๋ฏธํ•ฉ๋‹ˆ๋‹ค. ES6 ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ์ด๋ฅผ ์ง€์›ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๋ชฉ๋ก์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ๋งค์šฐ ๊ฐ€์น˜ ์žˆ๋Š” ์ผ์ž…๋‹ˆ๋‹ค.


PEG(์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ฐœ๋…์œผ๋กœ)๊ฐ€ ์„ฑ๊ณตํ•œ ์ด์œ ๋Š” ๋ณต์žกํ•œ ๋ฌธ๋ฒ•(์žฌ๊ท€ ๋“ฑ)์„ ๋‹จ์ˆœํ•œ ๋ฐฉ์‹์œผ๋กœ ํ‘œํ˜„ํ•˜๋Š” ๋Šฅ๋ ฅ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋™์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋งŽ์€ ํŒŒ์„œ๊ฐ€ ์ด๊ฒƒ์— ๋Œ€ํ•ด ํ›จ์”ฌ ๋” ์ž˜ ์ˆ˜ํ–‰ํ•˜๋ฉฐ ๊ทธ๋“ค์— ๋Œ€ํ•ด ์•„๋Š” ์‚ฌ๋žŒ๋“ค(Earley์™€ ๊ฐ™์€)์—๊ฒŒ๋„ ์•ฝ๊ฐ„ ์ธ๊ธฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์ „ํ†ต์ ์ธ ์„ค๋ช…์€ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ํ’ˆ์งˆ๊ณผ ์†๋„์˜ ์กฐํ•ฉ์ด์ง€๋งŒ, ๋งŽ์€ ํŒŒ์„œ๊ฐ€ ๋” ๋‚˜์€ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋” ๋นจ๋ฆฌ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ (Earley์™€ ๊ฐ™์ด) ์‚ฌ๋žŒ๋“ค ์‚ฌ์ด์—์„œ๋„ ์•ฝ๊ฐ„ ์ธ๊ธฐ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ €๋„ ๋™์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋“ค์— ๋Œ€ํ•ด ์•„๋Š” ์‚ฌ๋žŒ

๋˜ํ•œ PEG์—๋Š” ์„ธ ๊ฐ€์ง€ ์‹ฌ๊ฐํ•œ ๋ณต์žก์„ฑ ํ•œ๊ณ„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฒซ์งธ, ํŽ˜๊ทธ ๋ฌธ๋ฒ•์„ ํ†ตํ•ด ์ž…๋ ฅํ•˜๋ ค๋Š” ๋ชจ๋“  ํ•ญ๋ชฉ์—๋Š” ๋กœ์ปฌ ์‹œ์Šคํ…œ์˜ ์บ์‹œ ๋ฐ ํ‰๊ฐ€ ์ฒ˜๋ฆฌ๋Ÿ‰์„ ์••๋„ํ•˜์ง€ ์•Š๋Š” ์กฐํ•ฉ ํ‘œํ˜„์‹์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ์ œ #623).

๋‘ ๋ฒˆ์งธ, BNF ๊ตฌ๋ฌธ ๋ถ„์„๊ณผ ๊ฐ™์€ ๋งŽ์€ ์ผ๋ฐ˜์ ์ธ ์ž‘์—…์€ ์ข…์ข… peg์—์„œ ๋งค์šฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค(์˜ˆ์ œ #489).

์„ธ ๋ฒˆ์งธ, ํ›จ์”ฌ ๋” ๊ฐ•๋ ฅํ•œ ๋ชจ๋“  ๋‹ค๋ฅธ JS PEG ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์‹คํŒจํ–ˆ๋‹ค๋Š” ์ ์€ ์ฃผ๋ชฉํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์—ฌ๋Ÿฌ ๋ฒˆ ์ „ํ™˜ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๊ณ  ๋Œ์•„ ์™”์Šต๋‹ˆ๋‹ค. ํŠนํžˆ, c , ruby ๋ฐ python ๋ฅผ ์ถ”๊ฐ€๋กœ ํƒ€๊ฒŸํŒ…ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— canopy ๋กœ ์ „ํ™˜์„ ์—ฌ๋Ÿฌ ๋ฒˆ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค. javascript

๋ฌผ๋ก  ์ œ๊ฐ€ ๋งํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์ด ์ œํ’ˆ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” 24๋ช… ์ •๋„์˜ ์‚ฌ๋žŒ๋“ค๋ฟ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋Š” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋ฉฐ์น  ์ „์— ์ƒˆ๋กœ์šด ๋น„ ์œ ์ง€ ๊ด€๋ฆฌ์ž๊ฐ€ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๋ฒ„๋ฆฌ๊ณ  ๋ช‡ ๋…„ ๋™์•ˆ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๊ฒŒ์‹œ๋˜์ง€ ์•Š์€ ํ›„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋งŒ๋“  ๊ฒƒ์œผ๋กœ ๊ต์ฒดํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์„ ๋•Œ

ํ•˜์ง€๋งŒ ๊ทธ๋“ค ๋ชจ๋‘๋Š” ๊ธฐ๋ณธ ๊ฐœ๋…์  ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋งŽ์ง€ ์•Š์€ ํŒŒ์„œ๊ฐ€ ํ•„์š”ํ•˜๊ฑฐ๋‚˜ ๋™์ž‘์ด ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ๋น ๋ฅด๊ณ  ์ž‘์€ ๋ฌด์–ธ๊ฐ€๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ๋‚˜์—๊ฒŒ ๋งํ–ˆ์Šต๋‹ˆ๋‹ค.

์ถœ์‹œ๋˜์ง€ ์•Š์€ 0.11์€ ๋…ธ๋“œ ๋Œ€ ํฌ๋กฌ์—์„œ ์˜๋ฏธ ์žˆ๊ฒŒ ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋ฉฐ ๋…ธ๋“œ๋Š” ํฌ๋กฌ์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๋ช‡ ๊ฐ€์ง€ ์†์„ฑ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด์‹ญ์‹œ์˜ค. ์†”์งํžˆ ์ข€ ๋ฌด์„ญ์Šต๋‹ˆ๋‹ค.

.

Packrat์€ ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋ฐœ๋ช…๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ตฌ๋ฌธ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค.

๋‚œ ํŒฉ๋žซ์— ๋Œ€ํ•ด ์•„๋ฌด ๋ง๋„ ํ•˜์ง€ ์•Š์•˜์–ด, ์นœ๊ตฌ. ๋ฌด์—‡์„ ์ˆ˜์ •ํ•˜๋ ค๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ Packrat ๊ตฌ๋ฌธ ๋ถ„์„์€ ์ •๋ ฌ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์•„๋‹Œ ๊ฒƒ๊ณผ ๊ฐ™์€ ์ด์œ ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์•„๋‹™๋‹ˆ๋‹ค. Packrat ๊ตฌ๋ฌธ ๋ถ„์„์€ ์ž‘์—…์ด๋ฉฐ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ, ๋Œ€๋ถ€๋ถ„์˜ ์†Œ๊ฐœ Haskell ์ฑ…์€ ๋‹น์‹ ์ด 3-4๊ฐœ์˜ ๋‹ค๋ฅธ packrat ํŒŒ์„œ๋ฅผ ํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ทธ๊ฒƒ๋“ค์€ ๋ชจ๋‚˜๋“œ์— ๋Œ€ํ•œ haskell์˜ ์ ‘๊ทผ ๋ฐฉ์‹์˜ ์„ฑ๋Šฅ ๋ฌธ์ œ์— ์ •๋ง๋กœ ๋งค๋‹ฌ๋ฆด ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. packrats(์ฆ‰, ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ณ€๊ฒฝ)๋Š” ๋” ๋‚˜์€ ๊ฒฐ๊ณผ๋ฅผ ์‚ฐ์ถœํ•ฉ๋‹ˆ๋‹ค.

.

๊ทธ ์—„์ง€์†๊ฐ€๋ฝ์„ ๋‹ค์‹œ ์ƒ๊ฐํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ฃฝ์€ ์ง€ 3๋…„์ด ๋˜์—ˆ๋Š”๋ฐ ์ง€๊ธˆ ๋‹ค์‹œ ๋ถ€ํ™œ์‹œํ‚ค๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ฃฝ์€ ์ด์œ  ์ค‘ ์ผ๋ถ€๋Š” ์‚ฌ๋žŒ๋“ค์ด 2๋…„ ๋™์•ˆ dev์— ์žˆ๋˜ es() ๋ชจ๋“ˆ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๊ฐ„๋‹จํ•œ ์œ ์ง€ ๊ด€๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋Œ€์‹  ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•˜๊ธฐ ์œ„ํ•ด ๊ณ„์† ์‹œ๋„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋ผ์ธ์„ ์ž๋ฅด๊ณ  ์†์œผ๋กœ ์“ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋์— ์Šคํ…Œ์ดํ”Œ๋งํ•˜์—ฌ PEG ํŒŒ์„œ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ณ„์ด ๋น›๋‚˜๋Š” ๋ˆˆ์€ ์ž ์‹œ ๋™์•ˆ ๊ฐ๊ณ  ์‹ค์šฉ์ ์ธ ๊ธฐ๋ฆ„๊ธฐ ๋งŽ์€ ํŒ”๊ฟˆ์น˜๊ฐ€ ์‹œ์ž‘๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. PEG๋Š” ์‚ฌ์šฉ์ด ๊ฐ์†Œํ•˜๋ฉด์„œ ๋‚ด๊ฐ€ ๋ณธ ์œ ์ผํ•œ ์ฃผ์š” NPM ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ํ•ฉ๋ฆฌ์ ์ธ ๋Œ€์•ˆ์„ ์•Œ์ง€ ๋ชปํ•œ๋‹ค๋Š” ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ, ๊ทธ๊ฒƒ์€ ๋‚˜์—๊ฒŒ ์ด์ƒํ•˜๊ณ  ํ˜ผ๋ž€์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

image

์ง€๊ธˆ ๋‹น์žฅ ๊ธฐ์—ฌํ•˜๊ณ  ์‹ถ์€ ๋ฒ„๊ทธ ์ˆ˜์ •์ด ์žˆ์ง€๋งŒ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

  1. 0.10 ์€ dmajda๊ฐ€ ๋– ๋‚œ ํ›„ ๊ฒŒ์‹œ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
  2. 0.11 ์€(๋Š”) 3๋…„ ๋™์•ˆ ๋ฐœํ–‰๋œ ์ ์ด ์—†์œผ๋ฉฐ ํ•œ ๋‹ฌ ์ „์— ๋ฐœํ–‰๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ๋ฐœํ‘œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  3. ๋Œ€์ฒด 0.12 ๋Š” peg๊ฐ€ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋กœ ์ž‘์„ฑํ•œ ๊ฒƒ์ด๋ฏ€๋กœ ์•„๋ฌด๋„ ๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋ฌด๋ก€ํ•˜๋‹ค๋Š” ๊ฑด ์•Œ์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์ด ๋„์„œ๊ด€์ด ์ฃฝ์–ด๊ฐ€๊ณ  ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์ง์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋‹ค์‹œ ์—…๋ฐ์ดํŠธ๋ฅผ ๋ณด๊ฒŒ ๋œ๋‹ค๋ฉด ์ •์ƒ์ ์ธ ๊ฐœ๋ฐœ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ฐ›์•„๋“ค์—ฌ์•ผ ํ•  ๋•Œ์ž…๋‹ˆ๋‹ค. 2020๋…„์ž…๋‹ˆ๋‹ค. 2017๋…„ ์ดํ›„๋กœ ์•„๋ฌด๊ฒƒ๋„ ๋ณด์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

์•„๋‹ˆ์š”, dev ๋ถ„๊ธฐ๋Š” ๊ณ„์‚ฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  0.11 ์˜ ํ’ˆ์งˆ์ด ์ถฉ๋ถ„ํ•˜์ง€ ์•Š๊ณ  10 ์—์„œ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์ด 11 ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ์ ์€ ์ž‘์—…์ด๊ธฐ ๋•Œ๋ฌธ์— ์ƒˆ ์œ ์ง€ ๊ด€๋ฆฌ์ž๋Š” ๋งŽ์€ ๋ฌธ์ œ๋ฅผ ๋‹ค์‹œ ์—ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค 10 11

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰