Pegjs: ๊ณต๋ฐฑ ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๋ฅผ ์œ ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

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

๋ฌธ์ œ ์œ ํ˜•

  • ๋ฒ„๊ทธ ์‹ ๊ณ : _no_
  • ๊ธฐ๋Šฅ ์š”์ฒญ: _no_
  • ์งˆ๋ฌธ: _์˜ˆ_
  • ๋ฌธ์ œ ์•„๋‹˜: _no_

์ „์ œ ์กฐ๊ฑด

  • ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?: _์˜ˆ_
  • ์ €์žฅ์†Œ ๋ฌธ์ œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜์…จ์Šต๋‹ˆ๊นŒ?: _yes_
  • ํฌ๋Ÿผ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๊นŒ?: _์˜ˆ_
  • ์›น ๊ฒ€์ƒ‰(google, yahoo ๋“ฑ)์„ ์ˆ˜ํ–‰ํ•˜์…จ์Šต๋‹ˆ๊นŒ?: _yes_

์ €๋Š” PEG.js ํŒŒ์„œ๊ฐ€ ๋ฐฉ์ •์‹์˜ ์›๋ž˜ ๊ณต๋ฐฑ์„ ์œ ์ง€ํ•˜๋„๋ก ๊ณ ์‹ฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋™์ž‘: 2 * 5 + SUM(1, 2, 3)

[
   "2",
   "*",
   "5",
   "+",
   "SUM",
   "(",
   [
      "1",
      ",",
      "2",
      ",",
      "3"
   ],
   ")"
]

์›ํ•˜๋Š” ํ–‰๋™ : 2 * 5 + SUM(1, 2, 3)

[
   "2",
   " ",
   "*",
   " ",
   "5",
   " ",
   "+",
   " ",
   "SUM",
   "(",
   [
      "1",
      ",",
      " ",
      "2",
      ",",
      " ",
      "3"
   ],
   ")"
]

๋ณต์‚ฌํ•  ๋ฌธ๋ฒ•: https://pastebin.com/zpwqT6Uw
PEG.js ๋†€์ดํ„ฐ https://pegjs.org/online

๋‚ด๊ฐ€ ๋ฌด์—‡์„ ๋†“์น˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

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

@marek-baranowski ๋˜ ๋‹ค๋ฅธ ๋ถ€๋“œ๋Ÿฌ์šด ํ•‘ :smiley_cat:

๋˜ํ•œ, ๋ฌธ๋ฒ• ๋””๋ฒ„๊น…์„ ์šฉ์ดํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด PEG.js ํ”Œ๋Ÿฌ๊ทธ์ธ pegjs-syntactic-actions ๋ฅผ ์ž‘์„ฑํ–ˆ์œผ๋ฉฐ, ํŠนํžˆ @StoneCypher์—์„œ ์„ค๋ช…ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์—ฌ๊ธฐ์—์„œ ๊ท€ํ•˜์˜ ๋ฌธ์ œ์ผ ์ˆ˜ ์žˆ๋Š” ์ž‘์—…๊ณผ ๋…๋ฆฝ์ ์œผ๋กœ ์–ด๋–ค ๊ทœ์น™์— ์˜ํ•ด ์–ด๋–ค ๋ฌธ์ž๊ฐ€ ์บก์ฒ˜๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ์ถ”๋ก ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ๊ธฐ๋Œ€ํ•œ ๊ฒƒ๊ณผ ๋‹ค๋ฅผ ๋•Œ ์ „์ฒด ๊ฒฐ๊ณผ๋ฅผ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ข…์ข…/๋•Œ๋กœ๋Š” ์–ด๋ ต๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ทธ๊ฒƒ์€ ๋งŽ์€ ์ž‘์€ ํ–‰๋™์˜ ์กฐํ•ฉ์˜ ๊ฒฐ๊ณผ์ด๊ณ  ๋‚˜์˜๊ฒŒ/์ด์ƒํ•˜๊ฒŒ ํ–‰๋™ํ•˜๋Š” ํ–‰๋™์„ ์ฐพ๋Š” ๊ฒƒ์€ ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ฆฌ๋Š”. ์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ค ๊ทœ์น™์ด ์–ด๋–ค ์บ๋ฆญํ„ฐ๋ฅผ ์บก์ฒ˜ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์ž‘์—…ํ•  ์ž‘์—…์˜ ์ด๋ฆ„์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

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

@futagoza ๊ท€์ฐฎ๊ฒŒ ํ•ด์„œ ์ •๋ง ์ฃ„์†กํ•˜์ง€๋งŒ PEG.js๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ฒƒ์€ ์ฒ˜์Œ์ด๊ณ  ์ด ๋ฌธ์ œ๋Š” ์ €์—๊ฒŒ ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ํžŒํŠธ ์ข€ ๋ถ€ํƒ๋“œ๋ ค๋„ ๋ ๊นŒ์š”?

์นœ์• ํ•˜๋Š”,
๋งˆ๋ ‰

๋‚˜๋Š” ๋‹น์‹ ์˜ ๋ฌธ๋ฒ•(์–ด์ œ์™€ ์ง€๊ธˆ ๋ง‰)์„ ์‚ดํŽด๋ณด๋ ค๊ณ  ์‹œ๋„ํ–ˆ์ง€๋งŒ ๊ทธ๊ฒƒ์„ ์ดํ•ดํ•˜๊ธฐ๊ฐ€ ์ •๋ง ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์—(์ด๋ฆ„ ์ง€์ • ๊ทœ์น™์€ ์ œ์ณ๋‘๊ณ , ์†”์งํžˆ ํ˜•์‹์€ ๋„์ฒ˜์— ์žˆ์Šต๋‹ˆ๋‹ค), ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค.

  1. ๊ณต๊ฐ„์„ ์†Œ๋น„ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ทœ์น™(์˜ˆ: const ๋ฐ˜ํ™˜ [left_space, cnst, right_space] )
  2. ๊ฒฐ๊ณผ๋ฅผ ์ทจํ•˜๋Š” ๋ชจ๋“  ๊ทœ์น™/์ž‘์—…์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. [].concat.apply([], con)

๊ทธ๋ž˜๋„ ์†”์งํžˆ ๋งํ•ด์„œ ์ด๊ฒƒ์€ ๋‚˜์—๊ฒŒ ํ•ดํ‚ค ์†”๋ฃจ์…˜์ฒ˜๋Ÿผ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค. ์‚ฌ์–‘์ด๋‚˜ ๋‹ค๋ฅธ ๊ฒƒ์— ๋Œ€ํ•œ ๋งํฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์œ„์˜ ํ•ดํ‚ค ์†”๋ฃจ์…˜ ์—†์ด ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ๋‚ด๊ฐ€ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ๊ทœ์น™๊ณผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” ๊ทœ์น™์„ ์•„๋Š” ๊ฒƒ์ด ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ๊ธฐ๊บผ์ด ์‹œ๊ฐ„์„ ํˆฌ์žํ•˜๊ณ  ๋ฌธ๋ฒ•์„ ์ •๋ฆฌํ•˜๊ณ  ๋ช‡ ๊ฐ€์ง€ ๊ทœ์น™์˜ ์ด๋ฆ„์„ ๋ฐ”๊พธ๋ฉด(๊ทธ๋ž˜์„œ ์›ํ•˜๋Š” ๊ฒƒ์„ ๋” ์‰ฝ๊ฒŒ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค), ๊ธฐ๊บผ์ด ๋˜ ๋‹ค๋ฅธ ์‹œ๋„๋ฅผ ํ•ด๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค ๐Ÿ˜‰

@marek-baranowski - ์ง€๊ธˆ๊นŒ์ง€ ์ด๊ฒƒ์„ ๋ณด์ง€ ๋ชปํ•ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์—ฌ์ „ํžˆ ๋‹น์‹ ์—๊ฒŒ ์œ ์šฉํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๊ณต๋ฐฑ์„ ์œ ์ง€ํ•˜๋ ค๋ฉด ์ผ์น˜ ๊ฐ€๋Šฅํ•œ ์ฝ˜ํ…์ธ ๋กœ ์ทจ๊ธ‰ํ•˜์‹ญ์‹œ์˜ค.

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

๋˜ํ•œ ... ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ์ œ์™ธํ•˜๊ณ  ์™œ ๊ทธ๋ ‡๊ฒŒ ๊ธธ ์žƒ์€ ๋ฌธ์ž๋ฅผ ์›ํ•ฉ๋‹ˆ๊นŒ? ํŒŒ์„œ๋Š” ๋‹น์‹ ์„ ์œ„ํ•ด ๊ทธ๊ฒƒ๋“ค์„ ์š”์•ฝํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์–ด์จŒ๋“ 

์š”์ฒญํ•˜์‹  ๋‚ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Document = Expression*

Whitespace
  = tx:[ \r\n]+ { return tx.join(''); }

Number
  = str:[0-9]+ { return str.join(''); }

Oper
  = '+'
  / '-'
  / '/'
  / '*'
  / ','

Label
  = l:[a-zA-Z]+ { return l.join(''); }

Parens 
  = '(' Whitespace? ex:Expression* Whitespace? ')' { return ex; }

Expression 
  = Number 
  / Oper
  / Whitespace
  / Label
  / Parens
  / [^()]+

image

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

Document = Expression*

Whitespace
  = tx:[ \r\n]+ { return { 
    ast: 'whitespace', value: tx.join('') 
  }; }

Number
  = str:[0-9]+ { return {
    ast: 'number', value: parseInt(str,10)
  }; }

Oper
  = '+' { return { ast: 'oper', value: 'add' }}
  / '-' { return { ast: 'oper', value: 'subtract' }}
  / '/' { return { ast: 'oper', value: 'divide' }}
  / '*' { return { ast: 'oper', value: 'multiply' }}
  / ',' { return { ast: 'oper', value: 'sequence' }}

Label
  = l:[a-zA-Z]+ { return { 
    ast: 'label', value: l.join('') 
  }; }

Parens 
  = '(' Whitespace? ex:Expression* Whitespace? ')' { 
    return { ast: 'parens', value: ex 
  }; }

Expression 
  = Number 
  / Oper
  / Whitespace
  / Label
  / Parens
  / [^()]+

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

image

@marek-baranowski - ์ด ๋ฌธ์ œ ์ถ”์ ๊ธฐ์˜ ํฌ๊ธฐ๋ฅผ ๋‹ค์†Œ ์ค„์ด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์œ„์˜ ๋‚ด์šฉ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ด ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ๐Ÿ˜„

๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ด์œ ๋ฅผ ์•Œ๋ ค์ฃผ์„ธ์š”. ๋‹ค์‹œ ์‹œ๋„ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@marek-baranowski ๋˜ ๋‹ค๋ฅธ ๋ถ€๋“œ๋Ÿฌ์šด ํ•‘ :smiley_cat:

๋˜ํ•œ, ๋ฌธ๋ฒ• ๋””๋ฒ„๊น…์„ ์šฉ์ดํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด PEG.js ํ”Œ๋Ÿฌ๊ทธ์ธ pegjs-syntactic-actions ๋ฅผ ์ž‘์„ฑํ–ˆ์œผ๋ฉฐ, ํŠนํžˆ @StoneCypher์—์„œ ์„ค๋ช…ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์—ฌ๊ธฐ์—์„œ ๊ท€ํ•˜์˜ ๋ฌธ์ œ์ผ ์ˆ˜ ์žˆ๋Š” ์ž‘์—…๊ณผ ๋…๋ฆฝ์ ์œผ๋กœ ์–ด๋–ค ๊ทœ์น™์— ์˜ํ•ด ์–ด๋–ค ๋ฌธ์ž๊ฐ€ ์บก์ฒ˜๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ์ถ”๋ก ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ๊ธฐ๋Œ€ํ•œ ๊ฒƒ๊ณผ ๋‹ค๋ฅผ ๋•Œ ์ „์ฒด ๊ฒฐ๊ณผ๋ฅผ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ข…์ข…/๋•Œ๋กœ๋Š” ์–ด๋ ต๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ทธ๊ฒƒ์€ ๋งŽ์€ ์ž‘์€ ํ–‰๋™์˜ ์กฐํ•ฉ์˜ ๊ฒฐ๊ณผ์ด๊ณ  ๋‚˜์˜๊ฒŒ/์ด์ƒํ•˜๊ฒŒ ํ–‰๋™ํ•˜๋Š” ํ–‰๋™์„ ์ฐพ๋Š” ๊ฒƒ์€ ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ฆฌ๋Š”. ์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ค ๊ทœ์น™์ด ์–ด๋–ค ์บ๋ฆญํ„ฐ๋ฅผ ์บก์ฒ˜ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์ž‘์—…ํ•  ์ž‘์—…์˜ ์ด๋ฆ„์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์˜ค์˜ค ์ด๊ฑฐ ์ง„์งœ ์ง„์งœ ๊น”๋”ํ•˜๋‹ค

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