Pegjs: ๋“ค์—ฌ์“ฐ๊ธฐ ๊ธฐ๋ฐ˜ ์–ธ์–ด์˜ ๊ตฌ๋ฌธ ๋ถ„์„ ์ง€์›

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

์ €๋Š” CoffeeScript, Jade์™€ ๊ฐ™์€ ๋“ค์—ฌ์“ฐ๊ธฐ ๊ธฐ๋ฐ˜ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๊ณ  DSL์„ ์ง์ ‘ ๋งŒ๋“ค๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.
๊ฒ€์ƒ‰ํ•˜์—ฌ pegjs์—์„œ ๋“ค์—ฌ์“ฐ๊ธฐ๋ฅผ ์œ ์ง€ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ํŠธ๋ฆญ์„ ์ฐพ์•˜๊ณ  ์ผ๊ด€๋œ ์†”๋ฃจ์…˜์ด ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ–ˆ์Šต๋‹ˆ๋‹ค.
http://stackoverflow.com/questions/11659095/parse-indentation-level-with-peg-js
http://stackoverflow.com/questions/4205442/peg-for-python-style-indentation
https://gist.github.com/jakubkulhan/3192844
https://groups.google.com/forum/#!searchin/pegjs/indent/pegjs/RkbAB4rPlfU/xxafrY5wGCEJ
ํ•˜์ง€๋งŒ pegjs๊ฐ€ ์ด ๊ธฐ๋Šฅ์„ ์ง€์›ํ• ๊นŒ์š”?

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

๋“ค์—ฌ์“ฐ๊ธฐ ๊ธฐ๋ฐ˜ ๋ฌธ๋ฒ•์„ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ์ž ์ •์˜ ์ฒ˜๋ฆฌ๊ธฐ์— ์ถ”๊ฐ€ํ•˜๋Š” ๋ถ€์ž‘์šฉ์— ์˜์กดํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์œ„ํ—˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ƒฅ ํ•˜์ง€ ๋งˆ์„ธ์š”. Pegjs๋Š” ๊ตฌ๋ฌธ ๋ถ„์„ ๋“ค์—ฌ์“ฐ๊ธฐ(๋ฐ ๊ธฐํƒ€ ์ƒํ™ฉ์— ๋งž๋Š” ๋ฌธ๋ฒ•)๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์กฐ๊ฑด๋ถ€ ์ƒํƒœ๋ฅผ ํ‘ธ์‹œํ•˜๊ณ  ํŒํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ์ง€๊ธˆ ํ•˜๋Š” ์ผ์ด๋ฉฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ž…๋ ฅ ํŒŒ์ผ์„ ์‚ฌ์ „ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ณ ์œ ํ•œ ๋“ค์—ฌ์“ฐ๊ธฐ/๋‚ด์–ด์“ฐ๊ธฐ ํ† ํฐ์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ๊ฐ๊ฐ {{{{ ๋ฐ }}}}๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ฌธ๋ฒ•์ด ์ปจํ…์ŠคํŠธ๊ฐ€ ์—†๊ณ  ์ •์ƒ์ ์œผ๋กœ ๊ตฌ๋ฌธ ๋ถ„์„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ–‰/์—ด ๊ฐ’์„ ์—‰๋ง์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ง€๋งŒ ํ›„์ฒ˜๋ฆฌ๊ธฐ์—์„œ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

๋“ค์—ฌ์“ฐ๊ธฐ ๊ธฐ๋ฐ˜ ๋ฌธ๋ฒ•์„ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ์ž ์ •์˜ ์ฒ˜๋ฆฌ๊ธฐ์— ์ถ”๊ฐ€ํ•˜๋Š” ๋ถ€์ž‘์šฉ์— ์˜์กดํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์œ„ํ—˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ƒฅ ํ•˜์ง€ ๋งˆ์„ธ์š”. Pegjs๋Š” ๊ตฌ๋ฌธ ๋ถ„์„ ๋“ค์—ฌ์“ฐ๊ธฐ(๋ฐ ๊ธฐํƒ€ ์ƒํ™ฉ์— ๋งž๋Š” ๋ฌธ๋ฒ•)๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์กฐ๊ฑด๋ถ€ ์ƒํƒœ๋ฅผ ํ‘ธ์‹œํ•˜๊ณ  ํŒํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ์ง€๊ธˆ ํ•˜๋Š” ์ผ์ด๋ฉฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ž…๋ ฅ ํŒŒ์ผ์„ ์‚ฌ์ „ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ณ ์œ ํ•œ ๋“ค์—ฌ์“ฐ๊ธฐ/๋‚ด์–ด์“ฐ๊ธฐ ํ† ํฐ์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ๊ฐ๊ฐ {{{{ ๋ฐ }}}}๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ฌธ๋ฒ•์ด ์ปจํ…์ŠคํŠธ๊ฐ€ ์—†๊ณ  ์ •์ƒ์ ์œผ๋กœ ๊ตฌ๋ฌธ ๋ถ„์„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ–‰/์—ด ๊ฐ’์„ ์—‰๋ง์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ง€๋งŒ ํ›„์ฒ˜๋ฆฌ๊ธฐ์—์„œ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋ฉด C#์šฉ ๋‚ด pegjs ํด๋ก ์ธ Pegasus ๊ฐ€ ํ‘ธ์‹œ/ํŒํ•‘ ์ƒํƒœ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ์›ํ•˜๋Š” ์ž‘์—…์„ ์ •ํ™•ํžˆ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์œ„ํ‚ค ๋ฌธ์„œ์ž…๋‹ˆ๋‹ค. https://github.com/otac0n/Pegasus/wiki/Significant-Whitespace-Parsing

pegjs๊ฐ€ ๋‚ด ๊ตฌ๋ฌธ์„ ์ƒํƒœ ๊ธฐ๋ฐ˜ ๊ตฌ๋ฌธ ๋ถ„์„์˜ ์‹œ์ž‘์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋„๋ก ์ œ์•ˆํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์•ˆ์ „ํ•˜๊ฒŒ ๋ฐ€๊ณ  ํ„ฐ์ง€๋Š” ๋Šฅ๋ ฅ์ด ์ข‹๋‹ค. Javascript ๊ธฐ๋ฐ˜์ด๋ผ๋ฉด ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ตฌ๋ฌธ ๋ถ„์„์„ ์œ„ํ•ด CLR์„ ํ†ตํ•ฉํ•  ๊ฐ€์น˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๊ฒŒ ๋‚ด๊ฐ€ ์ƒ๊ฐํ•œ๊ฑฐ์•ผ. ์ด ๊ฒฝ์šฐ ๊ฐœ์„  ์‚ฌํ•ญ์„ pegjs๋กœ ๋ฐฑํฌํŠธํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ @dmajda์™€ ๋Œ€ํ™”ํ•˜์ง€ ์•Š๊ณ  ๋ฐ˜๋“œ์‹œ ๊ทธ๋ ‡๊ฒŒ ํ•˜๊ณ  ์‹ถ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

@otac0n ๋ฐ˜๊ฐ‘์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” C#์„ ์“ฐ์ง€ ์•Š๋Š”๋‹ค. JavaScript๊ฐ€ ์ €์—๊ฒŒ ํ›จ์”ฌ ์ข‹์Šต๋‹ˆ๋‹ค.

๋“ค์—ฌ์“ฐ๊ธฐ ๊ธฐ๋ฐ˜ ์–ธ์–ด๊ฐ€ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. 1.0.0 ์ดํ›„์˜ ๊ตฌ๋ฌธ ๋ถ„์„์„ ๋‹จ์ˆœํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” Pegasus๊ฐ€ #285์—์„œ ์ œ์•ˆํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์ผ๋ฐ˜์ ์œผ๋กœ ์ƒํƒœ๋ฅผ ํ—ˆ์šฉํ•จ์œผ๋กœ์จ ๊ฐ€์žฅ ์ž˜ ํ•ด๊ฒฐ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ์•„์ด๋””์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค(๋‹ค์Œ์€ pegjs๋กœ ๋ฒˆ์—ญ๋˜๊ณ  ๋‚ด ๊ตฌ๋ฌธ ์•„์ด๋””์–ด๊ฐ€ ์ถ”๊ฐ€๋œ Pegasus์˜ ์ค‘์š”ํ•œ ๊ณต๋ฐฑ ๋ฌธ๋ฒ•์ž…๋‹ˆ๋‹ค):

{var indentation = 0}

program
  = s:statements eof { return s }

statements
  = line+

line
  = INDENTATION s:statement { return s }

statement
  = s:simpleStatement eol { return s }
  / "if" _ n:name _? ":" eol INDENT !"bar " s:statements UNDENT {
      return { condition: n, statements: s }
    }
  / "def" _ n:name _? ":" eol INDENT s:statements UNDENT {
      return { name: n, statements: s }
    }

simpleStatement
  = a:name _? "=" _? b:name { return { lValue: a, expression: b } }

name
  = [a-zA-Z] [a-zA-Z0-9]* { return text() }

_ = [ \t]+

eol = _? comment? ("\r\n" / "\n\r" / "\r" / "\n" / eof)

comment = "//" [^\r\n]*

eof = !.

INDENTATION
  = spaces:" "* &{ return spaces.length == indentation }

INDENT
  = #STATE{indentation}{ indentation += 4 }

UNDENT
  = #STATE{indentation}{ indentation -= 4 }

๋ฐ”๋‹ฅ ๊ทผ์ฒ˜์˜ #STATE{indentation} ๋ธ”๋ก์— ์ฃผ๋ชฉํ•˜์‹ญ์‹œ์˜ค(ํŽ˜๊ฐ€์ˆ˜์Šค์—์„œ ์˜๊ฐ์„ ๋ฐ›์€ ๊ฒƒ์ด ๋ถ„๋ช…ํ•จ). ๋‚˜๋Š” ๊ทธ ์ƒํƒœ ๋ธ”๋ก์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์•„์ด๋””์–ด๋Š” ์ž‘์—… ์ „์— ์ƒํƒœ ์ฐจ๋‹จ์„ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๋” ๋ณต์žกํ•œ ์ƒํƒœ ๋ธ”๋ก์ž…๋‹ˆ๋‹ค.

#STATE{a, b, arr: {arr.slice()}, obj: {shallowCopy(obj)}, c}

๋‹ค์Œ์˜ ์ค„์ž„๋ง์ž…๋‹ˆ๋‹ค.

#STATE{a: {a}, b: {b}, arr: {arr.slice()}, obj: {shallowCopy(obj)}, c: {c}}

์ฆ‰, ์†๊ธฐ ํ™•์žฅ์ด ์ ์šฉ๋œ ํ›„ ์ƒํƒœ ๋ธ”๋ก์˜ ๋‚ด์šฉ์€ identifier ":" "{" code "}" ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค. ์ž‘์—… ์•ž์— ์ƒํƒœ ๋ธ”๋ก์„ ์ถ”๊ฐ€ํ•˜๋ฉด pegjs์— ์ด ์ž‘์—…์ด ๋‚˜์—ด๋œ ์‹๋ณ„์ž๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ๊ทœ์น™์ด ์—ญ์ถ”์ ๋˜๋ฉด ํ•ด๋‹น ์‹๋ณ„์ž๊ฐ€ ์ค‘๊ด„ํ˜ธ ์‚ฌ์ด์˜ ์ฝ”๋“œ๋กœ ์žฌ์„ค์ •๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์•Œ๋ ค์ค๋‹ˆ๋‹ค.

indentation ๋ณ€์ˆ˜ ์žฌ์„ค์ •์ด ์ถ”๊ฐ€๋œ ์œ„์˜ ๋ฌธ๋ฒ•์—์„œ INDENT ๋ฐ UNDENT์— ๋Œ€ํ•ด ์ปดํŒŒ์ผ๋œ ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    function peg$parseINDENT() {
      var s0, s1, t0;

      s0 = peg$currPos;
      t0 = indentation;
      s1 = [];
      if (s1 !== peg$FAILED) {
        peg$reportedPos = s0;
        s1 = peg$c41();
      } else {
        indentation = t0;
      }
      s0 = s1;

      return s0;
    }

    function peg$parseUNDENT() {
      var s0, s1, t0;

      s0 = peg$currPos;
      t0 = indentation;
      s1 = [];
      if (s1 !== peg$FAILED) {
        peg$reportedPos = s0;
        s1 = peg$c42();
      } else {
        indentation = t0;
      }
      s0 = s1;

      return s0;
    }

๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ์€ ์œ„์˜ "๋ณต์žกํ•œ ์ƒํƒœ ๋ธ”๋ก"์„ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

s0 = peg$currPos;
t0 = a;
t1 = b;
t2 = arr.slice();
t3 = shallowCopy(obj);
t4 = c;
// ...
if (s1 !== peg$FAILED) {
  // ...
} else {
  peg$currPos = s0;
  a = t0;
  b = t1;
  arr = t2;
  obj = t3;
  c = t4;
}

๋‹ค์Œ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์•„์ด๋””์–ด์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์„ธ์š”?

  • ์ž‘์—…์— ์˜ํ•ด ์ˆ˜์ •๋  ์ƒํƒœ ์ €์žฅ ๋ณ€์ˆ˜์— ๋Œ€ํ•ด pegjs์— ์•Œ๋ฆฝ๋‹ˆ๋‹ค.
  • ์žฌ์„ค์ •ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์ฝ”๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. (๋ณ€์ˆ˜๊ฐ€ ๊ธฐ๋ณธ ๊ฐ’์ธ ๊ฐ„๋‹จํ•œ ๊ฒฝ์šฐ์— ๋Œ€ํ•œ ์•ฝ์‹ ๊ตฌ๋ฌธ ํฌํ•จ)

๊ทธ๋ฆฌ๊ณ  ๊ตฌ๋ฌธ์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ?

ํŽธ์ง‘: ๋‹ค์Œ์€ ์ œ์•ˆ๋œ ๊ตฌ๋ฌธ ๋ฌธ๋ฒ•์ž…๋‹ˆ๋‹ค(์žฌ๋ฏธ๋กœ):

diff --git a/src/parser.pegjs b/src/parser.pegjs
index 08f6c4f..09e079f 100644
--- a/src/parser.pegjs
+++ b/src/parser.pegjs
@@ -116,12 +116,31 @@ ChoiceExpression
     }

 ActionExpression
-  = expression:SequenceExpression code:(__ CodeBlock)? {
+  = expression:SequenceExpression code:((__ StateBlock)? __ CodeBlock)? {
       return code !== null
-        ? { type: "action", expression: expression, code: code[1] }
+        ? {
+            type:       "action",
+            expression: expression,
+            code:       code[2],
+            stateVars:  (code[0] !== null ? code[0][1] : [])
+          }
         : expression;
     }

+StateBlock "state block"
+  = "#STATE{" __ first:StateBlockItem rest:(__ "," __ StateBlockItem)* __ "}" {
+      return buildList(first, rest, 3);
+    }
+
+StateBlockItem
+  = varName:Identifier expression:(__ ":" __ CodeBlock)? {
+      return {
+        type:       "stateVar",
+        name:       varName,
+        expression: expression !== null ? expression[3] : varName
+      };
+    }
+
 SequenceExpression
   = first:LabeledExpression rest:(__ LabeledExpression)* {
       return rest.length > 0

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„,
๋ช…ํ™•ํžˆ ํ•˜์ž๋ฉด, ์ด ๋ฌธ์ œ๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋“ค์—ฌ์“ฐ๊ธฐ ๊ธฐ๋ฐ˜ ์–ธ์–ด์™€ ํ•จ๊ป˜ PEG.js(์ด ๋ฌธ์ œ์˜ ์ƒ๋‹จ์—์„œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• ํฌํ•จ)๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ๋” ๋‚ซ๋‹ค๋Š” ๊ฒƒ์ด ๋งž์Šต๋‹ˆ๊นŒ?
๊ฐ์‚ฌ ํ•ด์š”.

@hoho ๋‚˜๋Š” ๋‹น์‹ ์—๊ฒŒ ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‚˜์ค‘์— ์†”๋ฃจ์…˜ ๊ณผ ๊ฒฐํ•ฉ๊ธฐ๋กœ ๋“ค์—ฌ์“ฐ๊ธฐ ๋ฅผ

๋‚ด ๋ง์€ ๋“ค์—ฌ์“ฐ๊ธฐ๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋Š” ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์žˆ์ง€๋งŒ ์˜๊ฒฌ์— ๋”ฐ๋ฅด๋ฉด ์ด๋Ÿฌํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ํŠน์ • ๊ฒฝ์šฐ์— ์‹คํŒจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒํ™ฉ์„ ๋ช…ํ™•ํžˆ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. PEG.js์—์„œ ๋“ค์—ฌ์“ฐ๊ธฐ ๊ธฐ๋ฐ˜ ์–ธ์–ด๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๋‹ค์–‘ํ•œ ์†”๋ฃจ์…˜์ด ์žˆ์œผ๋ฉฐ ์ด์— ๋Œ€ํ•œ "๋Š๋‚Œ"์„ ์–ป์œผ๋ ค๊ณ  ํ•  ๋•Œ ๋‹ค๋ฅธ ์†”๋ฃจ์…˜์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: if ์™€ ์œ ์‚ฌํ•œ ๋“ค์—ฌ์“ฐ๊ธฐ๋œ ํ•˜์œ„ ๋ช…๋ น๋ฌธ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” ๋‘ ๊ฐœ์˜ ๋ช…๋ น๋ฌธ์ด ์žˆ๋Š” ๊ฐ„๋‹จํ•œ ์–ธ์–ด์˜ ๋ฌธ๋ฒ•์ž…๋‹ˆ๋‹ค

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

  1. ์บ์‹ฑ์œผ๋กœ ๋ฌธ๋ฒ•์„ ์•ˆ์ „ํ•˜๊ฒŒ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค(ํŒŒ์„œ๊ฐ€ ์ƒํƒœ ์กฐ์ž‘ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋Œ€์‹  ์บ์‹œ๋œ ๊ฒฐ๊ณผ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค).
  2. ๋“ค์—ฌ์“ฐ๊ธฐ ์ˆ˜์ค€์—์„œ ์—ญ์ถ”์ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค(ํ˜„์žฌ ์—ญ์ถ”์ ํ•  ๋•Œ ์ƒํƒœ๋ฅผ ํ•ด์ œํ•  ๋ฐฉ๋ฒ•์ด ์—†๊ธฐ ๋•Œ๋ฌธ์—). ์ฆ‰, ๊ฐœํ–‰ ๋ฐ ๋“ค์—ฌ์“ฐ๊ธฐ ์ˆ˜์ค€ ๋ณ€๊ฒฝ ํ›„์—๋งŒ ๋ช…ํ™•ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š” ๋‘ ๊ฐœ์˜ ์œ ํšจํ•œ ๊ตฌ๋ฌธ์ด ์žˆ๋Š” ์–ธ์–ด๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ œํ•œ 1์€ ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์ง€๋งŒ ์ œํ•œ 2๊ฐ€ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ์–ธ์–ด๋Š” ๋งŽ์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” 1.0.0๊นŒ์ง€๋Š” ์ด ์ƒํƒœ์— ๋งŒ์กฑํ•˜๊ณ  ๋‚˜์ค‘์— ์–ธ์  ๊ฐ€ ์ด ์ฃผ์ œ๋กœ ๋Œ์•„๊ฐˆ ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ๊ฐœ์„ ์˜ ์ฒซ ๋ฒˆ์งธ ์ˆ˜์ค€์€ ๋ณด๋‹ค ๋ช…์‹œ์ ์ธ ์ƒํƒœ ์ถ”์ (์œ„์—์„œ ์ œ์•ˆํ•œ ๋Œ€๋กœ)์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์—ญ์ถ”์  ํ›„ํฌ๋ฅผ ์ œ๊ณตํ•˜์—ฌ(์ƒํƒœ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ•ด์ œํ•  ์ˆ˜ ์žˆ๋„๋ก) ์ œํ•œ 2๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ์ˆ˜์ค€์€ ๋ช‡ ๊ฐ€์ง€ ์„ ์–ธ์  ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜์—ฌ ๋“ค์—ฌ์“ฐ๊ธฐ ์ƒํƒœ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ถ”์ ํ•  ํ•„์š”์„ฑ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ œํ•œ ์‚ฌํ•ญ 1์— ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

H, ์—ฌ๊ธฐ์— ์„ค๋ช…๋œ ๋Œ€๋กœ ์ ์ ˆํ•œ ์—ญ์ถ”์ ์„ ์ง€์›ํ•˜๋Š” PEG.js์šฉ (์ž‘๊ณ  ํ•ดํ‚น๋œ) ํŒจ์น˜๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. https://github.com/pegjs/pegjs/issues/45

๋ฒ”ํ”„ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค ๐Ÿ˜œ

์ €๋Š” ๋””์ž์ธ ์ค‘์ธ ์–ธ์–ด์— ๋Œ€ํ•œ CSON ๋ฐ YAML ํŒŒ์„œ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ  ์žˆ์—ˆ๋Š”๋ฐ PEG.js๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋“ค์—ฌ์“ฐ๊ธฐ ๊ธฐ๋ฐ˜ ํŒŒ์„œ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ๋Š” ๋™์•ˆ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์„ ์ƒ๊ฐํ•ด๋ƒˆ์Šต๋‹ˆ๋‹ค.

1) ํ‘ธ์‹œ/ํŒ ์ƒํƒœ์— ์˜์กดํ•˜์ง€ ์•Š์Œ
2) ์ž‘์—… ๋‚ด ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ๋“ค์—ฌ์“ฐ๊ธฐ ์ˆ˜์ค€ ์ฃผ์žฅ

์œ„์˜ ๋‘ ๊ฐ€์ง€ ์†”๋ฃจ์…˜ ์ค‘ ํ•˜๋‚˜๊ฐ€ ์‹ค์ œ๋กœ ์ƒ์„ฑ๋œ ํŒŒ์„œ์— ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์ถ”๊ฐ€๋กœ ์ œ ์ƒ๊ฐ์—๋Š”:

1) ์ƒํƒœ์— ์˜์กดํ•˜๋ฉด ๋ชป์ƒ๊ธด PEG.js ๊ตฌ๋ฌธ์ด ์ถ”๊ฐ€๋  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ž‘์—… ๊ธฐ๋ฐ˜ ์ƒํƒœ ์ฒ˜๋ฆฌ๋ฅผ ์ง€์›ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ํŒŒ์„œ ์œ ํ˜•์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
2) ๋•Œ๋•Œ๋กœ ์•ก์…˜์— ์ผ๋ถ€ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์–ธ์–ด ์ข…์† ๊ทœ์น™์ด ์ƒ์„ฑ๋˜๋ฉฐ, ์ผ๋ถ€ ๊ฐœ๋ฐœ์ž์˜ ๊ฒฝ์šฐ ๊ทœ์น™์— ๋Œ€ํ•œ ์•ก์…˜์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋” ๋งŽ์€ ํ”Œ๋Ÿฌ๊ทธ์ธ์— ์˜์กดํ•˜์ง€ ์•Š๊ณ ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜์—ฌ C ๋˜๋Š” PHP์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ์–ธ์–ด์šฉ ํŒŒ์„œ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์—†์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. 1 ๋˜๋Š” 2๊ฐœ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•œ ๋” ํฐ ๋นŒ๋“œ ์‹œ์Šคํ…œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์ž ์‹œ ํ›„ ๋‚˜๋Š” PEG.js ํŒŒ์„œ์˜ ๋ณ€ํ˜•์„ ๋งŒ๋“ค๊ธฐ ์‹œ์ž‘ํ–ˆ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฆ๊ฐ€("++") ๋ฐ ๊ฐ์†Œ("--") ์ ‘๋‘์‚ฌ ์—ฐ์‚ฐ์ž(__++ expression__ ๋ฐ __-- expression__ ) ์ผ์น˜ ํ‘œํ˜„์‹(__expression *__ ๋˜๋Š” __expression +__)์˜ ๊ฒฐ๊ณผ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ @dmajda์˜ ๊ธฐ๋ฐ˜์œผ๋กœ ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฌธ๋ฒ•์ด๋‹ค ๊ฐ„๋‹จํ•œ intentation ๊ธฐ๋ฐ˜ ์–ธ์–ด ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์‹œ ์ž‘์„ฑ, ์ƒˆ๋กœ์šด __ ++ expression__ ๋ฐ __-- expression__ ๋Œ€์‹  __ & {์กฐ๊ฑด} __ :

Start
  = Statements

Statements
  = Statement*

Statement
  = Indent* statement:(S / I) { return statement; }

S
  = "S" EOS {
      return "S";
    }

I
  = "I" EOL ++Indent statements:Statements --Indent { return statements; }
  / "I" EOS { return []; }

Indent "indent"
  = "\t"
 / !__ "  "

__ "white space"
 = " \t"
 / " "

EOS
  = EOL
  / EOF

EOL
  = "\n"

EOF
  = !.

ํ›จ์”ฌ ๋ˆˆ์ด ์ฆ๊ฒ์ฃ ? ์ธ๊ฐ„๊ณผ ์†Œํ”„ํŠธ์›จ์–ด ๋ชจ๋‘ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ? ๋‹จ์ˆœํ•œ:

1) Indent* ๋Š” ํŒŒ์„œ์—๊ฒŒ Indent ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ ์ค‘ 0๊ฐœ ์ด์ƒ์„ ์›ํ•œ๋‹ค๊ณ  ์•Œ๋ ค์ค๋‹ˆ๋‹ค.
2) ++Indent ๋Š” ํŒŒ์„œ์—๊ฒŒ Indent ํ•„์š”ํ•œ ์ตœ์†Œ ์ผ์น˜ ์ˆ˜๋ฅผ ๋Š˜๋ฆฌ๋„๋ก ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค.
3) ์ด์ œ ํŒŒ์„œ๋Š” Indent ๋Œ€ํ•œ ์ผ์น˜ ํ•ญ๋ชฉ์„ ๋ฐ˜ํ™˜ํ•˜๋ ค๊ณ  ํ•  ๋•Œ๋งˆ๋‹ค ๋จผ์ € ์ด์ „๋ณด๋‹ค __1๊ฐœ ๋”__ ์ผ์น˜ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด _peg$SyntaxError_๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
4) --Indent ๋Š” ํŒŒ์„œ์—๊ฒŒ Indent ํ•„์š”ํ•œ ์ตœ์†Œ ์ผ์น˜ ์ˆ˜๋ฅผ ์ค„์ด๋„๋ก ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค.
5) ์ด์ œ ํŒŒ์„œ๊ฐ€ Indent ์ฐพ๊ณ  ์ด์ „๋ณด๋‹ค __1๊ฐœ ์ ์€__ ์ผ์น˜ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•˜๋Š” ์ผ์น˜ ํ•ญ๋ชฉ์„ ๋ฐ˜ํ™˜ํ•  ๋•Œ๋งˆ๋‹ค, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด _peg$SyntaxError_๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ด ์†”๋ฃจ์…˜์€ PEG.js ๋ฌธ๋ฒ•์— ์ถ”์•…ํ•œ ๊ตฌ๋ฌธ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ํƒ€์‚ฌ ์ƒ์„ฑ๊ธฐ๋ฅผ ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ณ  '์ค‘์š”ํ•œ ๊ณต๋ฐฑ ๊ตฌ๋ฌธ ๋ถ„์„'์— ๋Œ€ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ์€ _src/parser.pegjs_์—์„œ ๊ตฌ๋ฌธ ๋ถ„์„ ์ง€์›์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ๋ณ€๊ฒฝ๋œ ๊ทœ์น™์ž…๋‹ˆ๋‹ค.

{
  const OPS_TO_PREFIXED_TYPES = {
    "$": "text",
    "&": "simple_and",
    "!": "simple_not",
    "++": "increment_match",
    "--": "decrement_match"
  };
}

PrefixedOperator
  = "$"
  / "&"
  / "!"
  / "++"
  / "--"

SuffixedOperator
  = "?"
  / "*"
  / "+" !"+"

์ปดํŒŒ์ผ๋Ÿฌ/์ƒ์„ฑ๊ธฐ ์ชฝ์„ ์ง€์›ํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋Š” ๊ฒƒ์ด ๋งž์Šต๋‹ˆ๊นŒ?

1) __++ expression__ ๋˜๋Š” __-- expression__์ด __expression *__ ๋˜๋Š” __expression +__์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋„๋ก ํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ ํŒจ์Šค๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ __expression__์€ ์„ ํƒ, ์‹œํ€€์Šค ๋˜๋Š” ๊ทœ์น™_ref ์œ ํ˜•์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
2) ์ผ์น˜ ํ•ญ๋ชฉ์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์ „์— ํ•„์š”ํ•œ ์ตœ์†Œ ์ผ์น˜ ํ•ญ๋ชฉ์ด ์ถฉ์กฑ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” __expression *__ ๋˜๋Š” __expression +__์— ๋Œ€ํ•ด ์ƒ์„ฑ๋œ ํŒŒ์„œ์— ์บ์‹œ ๊ธฐ๋ฐ˜ ๊ฒ€์‚ฌ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
3) ์ฃผ์–ด์ง„ ๊ทœ์น™์— ํ•„์š”ํ•œ ์ผ์น˜ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ƒ์„ฑ๋œ ํŒŒ์„œ์— ๋Œ€ํ•œ ๋„์šฐ๋ฏธ ๋ฉ”์„œ๋“œ๋ฅผ ์„ ํƒ์ ์œผ๋กœ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. nMatches( name: String ): Number

@futagoza , ์ด๊ฒƒ์€ ๊นจ๋—ํ•˜๊ณ  ์˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ข‹์•„์š”. ์ €๋Š” ์ƒํƒœ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํŒŒ์„œ์—์„œ ์ž‘์—…ํ•˜๊ณ  ์žˆ์ง€๋งŒ ์‹ค์ œ๋กœ ํ•„์š”ํ•œ ์œ ์ผํ•œ ์ƒํƒœ๋Š” ๋“ค์—ฌ์“ฐ๊ธฐ ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด ์•„์ด๋””์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋‹น์‹ ์—๊ฒŒ ๊ทธ๊ฒƒ์— ๋Œ€ํ•œ ํฌ๋ ˆ๋”ง์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋“ค์—ฌ์“ฐ๊ธฐ ์ˆ˜์ค€์„ ์ถ”์ ํ•˜๋ ค๋ฉด ์—ฌ์ „ํžˆ ํšจ๊ณผ์ ์œผ๋กœ ํ‘ธ์‹œ/ํŒํ•‘ ์ƒํƒœ๊ฐ€ ํ•„์š”ํ•˜๋ฏ€๋กœ ์ผ๋ถ€ ์ตœ์ ํ™”๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๊ฒƒ์˜ ์˜๋ฏธ๋Š” ๋งค์šฐ ์ข‹์Šต๋‹ˆ๋‹ค.

๋ฌธ๋ฒ•์— ์—ฐ์‚ฐ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ @ ์ ‘๋‘์‚ฌ ์—ฐ์‚ฐ์ž๋„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ ๋ชฉ์ ์€ ๋‹จ์ˆœํžˆ ์‹œํ€€์Šค์—์„œ ๋‹จ์ผ ๊ทœ์น™ ๊ฒฐ๊ณผ๋ฅผ ์ถ”์ถœํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ƒ˜ํ”Œ ๋ฌธ๋ฒ•์ด ๋”์šฑ ๊น”๋”ํ•ด์ง‘๋‹ˆ๋‹ค. ๋” ์ด์ƒ ์‚ฌ์†Œํ•œ { return x } ์ž‘์—…์ด ์—†์Šต๋‹ˆ๋‹ค.

Start
  = Statements

Statements
  = Statement*

Statement
  = Indent* @(S / I)

S
  = "S" EOS {
      return "S";
    }

I
  = "I" EOL ++Indent <strong i="8">@Statements</strong> --Indent
  / "I" EOS { return []; }

Indent "indent"
  = "\t"
 / !__ "  "

__ "white space"
 = " \t"
 / " "

EOS
  = EOL
  / EOF

EOL
  = "\n"

EOF
  = !.

@kodyjking ์ด๊ฑฐ ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์„ธ์š”?

@futagoza ๋“ค์—ฌ์“ฐ๊ธฐ ํŒจ์น˜๊ฐ€ ํ™œ์„ฑํ™”๋œ ํฌํฌ/๋ถ„๊ธฐ์™€ ์ž‘์€ ์ƒ˜ํ”Œ ๋ฌธ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์ด ํฌํฌ/๋ถ„๊ธฐ ๋“ค์—ฌ์“ฐ๊ธฐ ์ž‘์—… ์ค‘์ž…๋‹ˆ๋‹ค.

@krinye " @ ์ ‘๋‘์‚ฌ ์—ฐ์‚ฐ์ž๋„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ ๋ชฉ์ ์€ ๋‹จ์ˆœํžˆ ์‹œํ€€์Šค์—์„œ ๋‹จ์ผ ๊ทœ์น™ ๊ฒฐ๊ณผ๋ฅผ ์ถ”์ถœํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค."

์—ฌ๋Ÿฌ๋ถ„ ์ค‘ ํ•œ ๋ช…์ด ๋ณด๊ณ  ์ˆ˜์ • ์‚ฌํ•ญ์— ๋Œ€ํ•ด ์˜๊ฒฌ์„ ๋งํ•˜๊ฑฐ๋‚˜ PR์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ฐ์‚ฌ ํ•ด์š” :)

์ฝ์–ด๋ณด๊ธฐ: ํฌํฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ

๋””๋ฒ„๊น…ํ–ˆ์Šต๋‹ˆ๋‹ค... increment_match-not-found

์•„, ์ฃผ์˜ ์‚ฌํ•ญ์„ ๋ˆˆ์น˜์ฑ„์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

์ปดํŒŒ์ผ๋Ÿฌ/์ƒ์„ฑ๊ธฐ ์ชฝ์„ ์ง€์›ํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋Š” ๊ฒƒ์ด ๋งž์Šต๋‹ˆ๊นŒ?

  • ++ ํ‘œํ˜„์‹ ๋˜๋Š” -- ํ‘œํ˜„์‹์ด ํ‘œํ˜„์‹ * ๋˜๋Š” ํ‘œํ˜„์‹ +์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋„๋ก ํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ ํŒจ์Šค๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ํ‘œํ˜„์‹์€ ์„ ํƒ, ์‹œํ€€์Šค ๋˜๋Š” ๊ทœ์น™_ref ์œ ํ˜•์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ผ์น˜ ํ•ญ๋ชฉ์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์ „์— ํ•„์š”ํ•œ ์ตœ์†Œ ์ผ์น˜ ํ•ญ๋ชฉ์ด ์ถฉ์กฑ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ํ‘œํ˜„์‹ * ๋˜๋Š” ํ‘œํ˜„์‹ +์— ๋Œ€ํ•ด ์ƒ์„ฑ๋œ ํŒŒ์„œ์— ์บ์‹œ ๊ธฐ๋ฐ˜ ๊ฒ€์‚ฌ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • ์„ ํƒ์ ์œผ๋กœ ์ฃผ์–ด์ง„ ๊ทœ์น™์— ํ•„์š”ํ•œ ์ผ์น˜ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ƒ์„ฑ๋œ ํŒŒ์„œ์— ๋Œ€ํ•œ ๋„์šฐ๋ฏธ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. nMatches(์ด๋ฆ„: ๋ฌธ์ž์—ด): ์ˆซ์ž

๊ทธ๋ƒฅ ํ‚ฅ์„ ์œ„ํ•ด visitor.js ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค.

      increment_match: visitExpression,
      decrement_match: visitExpression,

์ด์ œ Invalid opcode: undefined. ๋ฐ›์Šต๋‹ˆ๋‹ค.

์‹œํ€€์Šค์—์„œ ๋‹จ์ผ ๊ฐ’์„ ์ถ”์ถœํ•˜๋Š” @ ์—ฐ์‚ฐ์ž์™€ ๊ด€๋ จ๋œ @kristianmandrup , ์—ฌ๊ธฐ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” PegJS์— ํ•ด๋‹น ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋œ ํฌํฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

https://github.com/krisnye/pegjs

์•„์ฃผ ๊ฐ„๋‹จํ•œ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

@krisnye +1 ๋ฌธ๋ฒ• ๊ธฐ๋ฐ˜ ๊ตฌํ˜„, ํ›Œ๋ฅญํ•˜๊ณ  ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๊ดœ์ฐฎ์œผ์‹œ๋‹ค๋ฉด PEG.js ๋ณ€ํ˜•์— ์ด๊ฒƒ์„ ์ถ”๊ฐ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค ๐Ÿ˜„

@kristianmandrup ๋‹น์‹ ์ด ๋‚ด ์ œ์•ˆ์— ๋Œ€ํ•œ ์ปค๋ฐ‹์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค

@futagoza ํ•ด์ฃผ์„ธ์š”.

๋‚˜๋Š” ๋™๋ฃŒ์™€ ๋“ค์—ฌ์“ฐ๊ธฐ ๋…ผ๋ฆฌ์— ๋Œ€ํ•ด ๋…ผ์˜ํ•˜๊ณ  ์žˆ์—ˆ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ๋ฌธ ์š”์†Œ๋ฅผ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.

// ๋ช…๋ช…๋œ ์ƒํƒœ ๋ณ€์ˆ˜๋ฅผ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค.
์‹๋ณ„์ž++
// ๋ช…๋ช…๋œ ์ƒํƒœ ๋ณ€์ˆ˜๋ฅผ ๊ฐ์†Œ์‹œํ‚ต๋‹ˆ๋‹ค.
์‹๋ณ„์ž--

// ์ผ์ •ํ•œ ์–‘ ๋˜๋Š” ์ƒํƒœ ๋ณ€์ˆ˜๋ฅผ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค(๋ณ€์ˆ˜๊ฐ€ ์•„์ง ์ฆ๊ฐ€ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๊ธฐ๋ณธ๊ฐ’์€ 0).
๊ทœ์น™{์ •์ˆ˜ | ์‹๋ณ„์ž}
// ์ƒ์ˆ˜ ๋˜๋Š” ์ƒํƒœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์†Œ/์ตœ๋Œ€ ๋ฐ˜๋ณต
๊ทœ์น™{์ •์ˆ˜ | ์‹๋ณ„์ž, ์ •์ˆ˜ | ์‹๋ณ„์ž}

์šฐ๋ฆฌ๊ฐ€ ์ž‘์—…ํ•˜๊ณ  ์žˆ๋Š” ํŒŒ์„œ๋Š” ์ž„์˜์˜ ์ƒํƒœ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์†”์งํžˆ ์œ„์˜ ๋‚ด์šฉ์€ ๋“ค์—ฌ์“ฐ๊ธฐ ํŒŒ์‹ฑ์— ํ•„์š”ํ•œ ์ „๋ถ€์ž…๋‹ˆ๋‹ค.

๊ณ ๋งˆ์›Œ์š”! ๊ทธ๋ ‡๊ฒŒ ํ•˜๊ธฐ ์‰ฝ๋‹ค๋ฉด ์–ธ๊ธ‰ํ•œ ๊ฒƒ์ด "๊ทธ๋ƒฅ ์ž‘๋™"ํ•˜๋Š” "์ „์šฉ" ํฌํฌ๋ฅผ ๋งŒ๋“œ์‹ญ์‹œ์˜ค. ;)
๊ฑด๋ฐฐ!

@krisnye

  1. __identifier++__๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐœ๋ฐœ์ž๊ฐ€ __identifier+__๋ฅผ ์˜๋ฏธํ•˜๋Š” ๊ฒฝ์šฐ ์‰ฝ๊ฒŒ ์ง€์ €๋ถ„ํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ __++identifier__์™€ ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด __--identifier__๋ฅผ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.
  2. ๋ฒ”์œ„์— ๋Œ€ํ•œ ๋‹ค๋ฅธ ๋ฌธ์ œ์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด rule{ STATE_REPEAT / RANGE } ๋Š” rule{ ACTION } ์™€ ํ˜ผ๋™๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ PEG.js์šฉ ๊ตฌ๋ฌธ ํ˜•๊ด‘ํŽœ์„ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒฝ์šฐ ์ด ์ ‘๊ทผ ๋ฐฉ์‹์€ @dmajda ์—์„œ ๊ฑฐ๋ถ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค

@kristianmandrup _(OFF TOPIC)_ ์ €๋Š” ๊ธฐ๋Šฅ์„ ์„ค๊ณ„ํ•˜๊ณ  ๋•Œ๋กœ๋Š” ๊ตฌํ˜„์„ ํ•˜๋Š” ๋ฐ ๋Šฅ์ˆ™ํ•˜์ง€๋งŒ ํ…Œ์ŠคํŠธ ๋ฐ ๋ฒค์น˜๋งˆํ‚น์—๋Š” ๋”์ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ผ๋ฐ˜์ ์œผ๋กœ ๋‚ด PC์˜ private non-repo ๋””๋ ‰ํ† ๋ฆฌ์— ์ž‘์—… ๋ณ€ํ˜•(ํ…Œ์ŠคํŠธ ๋˜๋Š” ๋ฒค์น˜๋งˆํฌ ์—†์ด)์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. , ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ๋“ค์„ ์žŠ์–ด๋ฒ„๋ฆฌ์„ธ์š” ๐Ÿคฃ. PEG.js์˜ ํ˜„์žฌ ๋ณ€ํ˜•(ePEG.js ๐Ÿ˜, PEG.js์˜ ํ™•์žฅ๋œ ์žฌ์ž‘์„ฑ)์˜ ๊ฒฝ์šฐ ์—ฌ๊ธฐ์— ์–ธ๊ธ‰๋œ ํ•ญ๋ชฉ๊ณผ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ(๋ฒ”์œ„, ๊ฐ€์ ธ์˜ค๊ธฐ, ํ…œํ”Œ๋ฆฟ ๋“ฑ)์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์ถ”๊ฐ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ๋ฐ ๋ฒค์น˜๋งˆํฌ, ํ•˜์ง€๋งŒ ํ˜„์žฌ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋Š” C++ ํ”„๋กœ์ ํŠธ๋„ ์ง„ํ–‰ ์ค‘์ด๋ฏ€๋กœ ETA๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

@futagoza ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ๋ฉ”์ดํŠธ :) ๊ธฐ๋Šฅ ํ™•์žฅ์„ ์‚ดํŽด๋ณด๊ณ  ์žˆ์ง€๋งŒ ๋“ค์—ฌ์“ฐ๊ธฐ ์ง€์›์€ ์–ธ๊ธ‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํฌํ•จ๋˜์–ด ์žˆ์ง€๋งŒ ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜ ์•ž์œผ๋กœ ๋‚˜์˜ฌ ์˜ˆ์ •์ž…๋‹ˆ๊นŒ?

์ด ๋ชฉ๋ก์˜ ๋‹ค๋ฅธ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๋‚ด๊ฐ€ ์กฐ์‚ฌํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ํŒŒ์„œ ๋นŒ๋”/์ƒ์„ฑ๊ธฐ ์†”๋ฃจ์…˜์„ ์•Œ๋ ค ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ณ„์† ์•Œ๋ ค์ฃผ์„ธ์š”! ๊ฑด๋ฐฐ!

@kristianmandrup ๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ ํฌํ•จ๋˜์–ด ์žˆ์ง€๋Š” ์•Š์ง€๋งŒ ๋Š” 3๋…„ ์ „์— PEG.js v1์„ ์ถœ์‹œํ•œ ํ›„ ์ด๋ฅผ ์กฐ์‚ฌํ•  ๊ฒƒ์ด๋ผ๊ณ  ๋ฐํ˜”์ง€๋งŒ ๊ทธ๊ฐ€ ๊ณ„ํšํ•˜์ง€ ์•Š๋Š” ํ•œ ์•ž์œผ๋กœ 2๋…„ ๋™์•ˆ์€ ๊ทธ๋ ‡์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ๋งํ–ˆ์Šต๋‹ˆ๋‹ค. PEG.js v0(_0.12_, _0.13_, _etc_)์˜ ๋” ๋งŽ์€ ๋งˆ์ด๋„ˆ ๋ฒ„์ „ ์ถœ์‹œ

ePEG์— ๋“ค์—ฌ์“ฐ๊ธฐ ์ง€์›์„ ์ด๋ฏธ ํฌํ•จํ–ˆ๊ฑฐ๋‚˜ ๋กœ๋“œ๋งต์— ํฌํ•จํ–ˆ๋‹ค๋ฉด?

@kristianmandrup ์˜ค ๐Ÿ˜†, ๋กœ๋“œ๋งต์— ์žˆ์Šต๋‹ˆ๋‹ค. ํ•œ๋™์•ˆ ePEG.js ์ €์žฅ์†Œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์ง€ ์•Š์•˜๊ณ  ์ตœ๊ทผ์— ํ”Œ๋Ÿฌ๊ทธ์ธ ๋Œ€์‹  PEG.js๋ฅผ ์™„์ „ํžˆ ๋‹ค์‹œ ์ž‘์„ฑํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

@futagoza ๋Š” ์‚ฌ์ „ ์ž‘์—…์œผ๋กœ ++/--์— ๋™์˜ํ–ˆ๊ณ  ์ž‘์—… ๊ตฌ๋ฌธ์„ ์žŠ์–ด๋ฒ„๋ ธ๊ณ  [min,max]๋กœ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ

++identifier
--identifier
rule[integer | identifier]
rule[integer | identifier, integer | identifier]

@krisnye [ ... ] ๋Š” ๋ฌธ์ž ํด๋ž˜์Šค์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค( https://github.com/pegjs/pegjs#characters ์ฐธ์กฐ).

๋‚ด๊ฐ€ ePEG.js์—์„œ ํ•˜๊ณ  ์žˆ๋Š” ์ผ์€ ๋ฒ”์œ„(๋กœ๋“œ๋งต์—๋„ ์žˆ์Œ)๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๊ท€ํ•˜๊ฐ€ ์„ค๋ช…ํ•˜๋Š” ๋ฐ”๋ฅผ ๋‹ฌ์„ฑํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

space = [ \t]*
rule = range|expression
  • __expression__์€ __++space__, __--space__ ๋˜๋Š” __space__ ์ค‘ ํ•˜๋‚˜์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • __๋ฒ”์œ„__๋Š” __ min.. __, __ min..max __, __ ..max __ ๋˜๋Š” __ exact __์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • __min__, __max__ ๋˜๋Š” __exact__๋Š” __unsigned integer__๋งŒ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • __expression__(์˜ˆ: 2|expression)๊ณผ ํ•จ๊ป˜ __range__๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด __rule__์ด ์„ฑ๊ณต์ ์œผ๋กœ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ __expression__์˜ ์ด๋Ÿ‰์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • __++expression__ ๋˜๋Š” __--expression__(์˜ˆ: 3|++expression)๊ณผ ํ•จ๊ป˜ __exact__ ๋ฒ”์œ„๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ __1__์ธ __++__ ๋˜๋Š” __--__์— ๋Œ€ํ•œ __integer__ ์–‘์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • __++expression__ ๋˜๋Š” __--expression__๊ณผ ํ•จ๊ป˜ __min__ ๋˜๋Š” __max__ ๋ฒ”์œ„๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ตฌ๋ฌธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๊ทœ์น™ ์‹๋ณ„์ž์™€ ํ˜ผ๋™๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ƒํƒœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

__range__, __++__, __--__ ๋˜๋Š” __ @__ ์กฐํ•ฉ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฐ๊ณผ์— ๋Œ€ํ•ด __action__ ๊ทœ์น™์— ๋œ ์˜์กดํ•˜๋Š” PEG ๋ฌธ๋ฒ• ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๊ณต๋ฐฑ(์˜ˆ: ๋“ค์—ฌ์“ฐ๊ธฐ)์˜ ๊ฐœ๋ฐœ ์‹œ๊ฐ„์ด ๋Š˜์–ด๋‚ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ฐ˜, ASCII ์•„ํŠธ ๋“ฑ) ์–ธ์–ด ์„ค๊ณ„์ž ๋ฐ/๋˜๋Š” ๊ตฌํ˜„์ž๋Š” ์˜ฌ๋ฐ”๋ฅธ ์–‘์˜ ๊ณต๋ฐฑ์ด ๊ตฌ๋ฌธ ๋ถ„์„๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ๊ฑฑ์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
์ด๊ฒƒ์€ ๋˜ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ์ž๊ฐ€ __action__์˜ ์–ธ์–ด๊ฐ€ ๋ฌด์—‡์ธ์ง€์— ๋Œ€ํ•ด _๋œ ๋‘๋ ค์›Œ_ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ํŒŒ์„œ ์ƒ์„ฑ๊ธฐ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(๊ธฐ๋ณธ์ ์œผ๋กœ JavaScript์ด์ง€๋งŒ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๋ฉด CoffeeScript, PHP ๋“ฑ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Œ).

๋”ฐ๋ผ์„œ PEG.js๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Python์„ ์ฆ‰์‹œ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋Š” ๊ฒƒ์€ ์˜ค๋Š˜๋‚ ์—๋„ ์—ฌ์ „ํžˆ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋งž์Šต๋‹ˆ๊นŒ?

๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ์ด๊ฒƒ์€ ๊ณง ์˜ฌ ๊ฒƒ์ž…๋‹ˆ๊นŒ? ์‚ฌ๋žŒ๋“ค์ด ๊ธฐ์—ฌํ•  ์ˆ˜ ์žˆ๋Š” ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์ผ๋ จ์˜ ์ž‘์—…์ด ์žˆ์Šต๋‹ˆ๊นŒ?

JS์—์„œ Python AST๋ฅผ ์–ป๊ณ  ์ˆ˜์ •ํ•œ ๋‹ค์Œ ๋™์ผํ•œ ํ˜•์‹์˜ ์†Œ์Šค ์ฝ”๋“œ๋กœ ๋‹ค์‹œ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์›ํ•˜๋Š” ํ”„๋กœ์ ํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋กœ๋“œ๋งต.

@mindjuice ์•„์ง, 1.0 ์ดํ›„๋กœ ์˜ˆ์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

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

https://github.com/krisnye/pegs

chevrotain ๊ณผ ๊ฐ™์€ ์ง€์› ๊ธฐ๋Šฅ์ด ์žˆ๋Š” ๋‹ค๋ฅธ ํŒŒ์„œ ์ƒ์„ฑ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŒŒ์ด์ฌ ๋“ค์—ฌ์“ฐ๊ธฐ ์˜ˆ

PEGjs๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ด์ฌ๊ณผ ๊ฐ™์€ ๋“ค์—ฌ์“ฐ๊ธฐ๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
์•„๋ž˜ ์˜ˆ์—์„œ๋Š” 4๊ฐœ์˜ ๊ณต๋ฐฑ ๊ธฐ๋ฐ˜ ๋“ค์—ฌ์“ฐ๊ธฐ๋งŒ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์ž„์˜ ๊ฐ„๊ฒฉ์˜ ํƒญ ๋ฐ ๊ธฐํƒ€ ๊ณต๋ฐฑ ๋ฌธ์ž๋ฅผ ํฌํ•จํ•˜๋„๋ก ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์‚ฌ์‹ค ๋‚ด๊ฐ€ ์ž‘์—…ํ•˜๊ณ  ์žˆ๋Š” ์–ธ์–ด๋Š” Python๋ณด๋‹ค ๋“ค์—ฌ์“ฐ๊ธฐ๊ฐ€ ์•ฝ๊ฐ„ ๋” ๋ณต์žกํ•˜๊ณ  ์ด ๋ฌธ๋ฒ•์ด ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

{
    let prevIndentCount = 0;
    function print(...s) { console.log(...s); }
}

Indent 'indent'
    = i:("    "+) { 
        let currentIndentCount = i.toString().replace(/,/g, "").length;
        if (currentIndentCount === prevIndentCount + 4) { 
            // DEBUG //
            print("=== Indent ===");
            print("    current:"+currentIndentCount); 
            print("    previous:"+prevIndentCount);
            print("    lineNumber:"+location().start.line); 
            // DEBUG //
            prevIndentCount += 4;
            return "[indent]";
        }
        error("error: expected a 4-space indentation here!")
    } // 4 spaces 

Samedent 'samedent'
    = s:("    "+ / "") &{
        let currentIndentCount = s.toString().replace(/,/g, "").length;
        if (currentIndentCount === prevIndentCount) {
            print("=== Samedent ===");
            return true;
        }
        return false;
    }

Dedent 'dedent'
    = d:("    "+ / "") {
        let currentIndentCount = d.toString().replace(/,/g, "").length;
        if (currentIndentCount < prevIndentCount) {
            // DEBUG //
            print("=== Dedent ===");
            print("    current:"+currentIndentCount); 
            print("    previous:"+prevIndentCount);
            print("    lineNumber:"+location().start.line); 
            // DEBUG //
            prevIndentCount -= 4;
            return "[dedent]";
        }
        error("error: expected a 4-space dedentation here!");
    }

์œ„์˜ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋“ค์—ฌ์“ฐ๊ธฐ ์ฐจ๋‹จ ๊ทœ์น™์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

FunctionDeclaration 
    = 'function' _ Identifier _ FunctionParameterSection _ ":" _ FunctionBody

FunctionBody
    = Newline Indent FunctionSourceCode (Newline Samedent FunctionSourceCode)* Dedent 
์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰

๊ด€๋ จ ๋ฌธ์ œ

brettz9 picture brettz9  ยท  8์ฝ”๋ฉ˜ํŠธ

futagoza picture futagoza  ยท  13์ฝ”๋ฉ˜ํŠธ

mikeaustin picture mikeaustin  ยท  7์ฝ”๋ฉ˜ํŠธ

StoneCypher picture StoneCypher  ยท  8์ฝ”๋ฉ˜ํŠธ

futagoza picture futagoza  ยท  6์ฝ”๋ฉ˜ํŠธ