Pegjs: ๋ฐ˜๋ณต ํšŸ์ˆ˜๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ธฐ๋Šฅ(regexp์—์„œ์™€ ๊ฐ™์ด)

์— ๋งŒ๋“  2011๋…„ 08์›” 11์ผ  ยท  22์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: pegjs/pegjs

PEG.js ๋ฌธ๋ฒ•์ด POSIX ๊ธฐ๋ณธ ์ •๊ทœ ํ‘œํ˜„์‹์˜ ๋ฒ”์œ„ ํ‘œํ˜„์‹๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•œ๋‹ค๋ฉด ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ:

  • "a"\{1,7\}

a , aa , ..., aaaaaaa ์ผ์น˜

  • "a"\{0,1\}

๋นˆ ๋ฌธ์ž์—ด ๋ฐ a ์™€ ์ผ์น˜

  • "a"\{,6\}

์ตœ๋Œ€ 6๊ฐœ์˜ a ๊ฐ€ ์žˆ๋Š” ๋ฌธ์ž์—ด๊ณผ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.

  • "a"\{6,\}

6๊ฐœ ์ด์ƒ์˜ a ๋ฌธ์ž์—ด๊ณผ ์ผ์น˜

  • "a"\{3\}

aaa ๋งŒ ์ผ์น˜ํ•˜๋ฉฐ $#$ "a"\{3,3\} ์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

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

๋‚˜๋Š” ๋ฐ˜๋ณต ํšŸ์ˆ˜๋„ ์ข‹์•„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์•ฝ๊ฐ„ ๋‹ค๋ฅธ ๊ตฌ๋ฌธ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. Pegasus ๋Š” C#์˜ ๊ฒฝ์šฐ์—๋งŒ pegjs์™€ ๊ฑฐ์˜ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค: https://github.com/otac0n/Pegasus/wiki/Syntax-Guide#expressions

๊ทธ๋ฆฌ๊ณ  d<3> e<2,> f<1,5> ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

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

์ด ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ฃผ๋œ ์ด์œ ๋Š” PEG.js ๋ฌธ๋ฒ•์— {m,n} ๊ตฌ๋ฌธ์„ ์œ„ํ•œ ๊ณต๊ฐ„์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ค‘๊ด„ํ˜ธ๋Š” ์ด๋ฏธ ์ž‘์—…์— ์‚ฌ์šฉ๋˜์—ˆ์œผ๋ฉฐ ์ œ์•ˆํ•œ ๋Œ€๋กœ ๋ฐฑ์Šฌ๋ž˜์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค(๊ทธ๋“ค์€ ์ถ”์•…ํ•˜๊ณ  ํ˜ธํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค ํ˜„์žฌ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” Perl ์ •๊ทœ ํ‘œํ˜„์‹๊ณผ ๋‹ค๋ฅธ PEG.js ๊ตฌ๋ฌธ์˜ ์†Œ์Šค) ๋˜๋Š” ๊ธฐํƒ€ ๊ตฌ๋ถ„ ๊ธฐํ˜ธ(ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ์ˆ˜ ์žˆ์Œ)๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋‚ด ๊ฒฝํ—˜์ƒ ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ์ œํ•œ๋œ ๋ฐ˜๋ณต์€ ์ฃผ๋กœ ๋ฌธ๋ฒ•์˜ "์–ดํœ˜" ๋ถ€๋ถ„( color = "#" hexdigit hexdigit hexdigit hexdigit hexdigit hexdigit ์™€ ๊ฐ™์€ ๊ทœ์น™)์—์„œ ๋ฐœ์ƒํ•˜๋ฉฐ ์ž์ฃผ ๋ฐœ์ƒํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๊ฑฐ๊ธฐ์— ํ‘œํ˜„์‹์˜ ์‹œํ€€์Šค์™€ ๊ธฐ์กด ๋ฐ˜๋ณต ์—ฐ์‚ฐ์ž( * , + , ? )๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ดœ์ฐฎ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์‹œ ์ƒ๊ฐํ•ด ๋ณด์•˜๊ณ  ์ด ๋ฌธ์ œ๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ž„์˜์˜ ๋ฐ˜๋ณต ํšŸ์ˆ˜๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ธฐ๋Šฅ์€ ์‚ฌ์šฉ์ž๊ฐ€ ๋งŽ์ด ์›ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

{ ๋ฐ } ๊ฐ€ ์ด๋ฏธ ์ž‘์—…์— ์‚ฌ์šฉ๋˜์—ˆ์œผ๋ฉฐ ์žฌ์‚ฌ์šฉํ•˜๋ฉด ๋ชจํ˜ธ์„ฑ์ด ์ƒ๊ธฐ๊ธฐ ๋•Œ๋ฌธ์— ์ •๊ทœ ํ‘œํ˜„์‹๊ณผ ๊ฐ™์€ {m,n} ๊ตฌ๋ฌธ์„ ํ”ผํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ํ˜„์žฌ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

"foo" @ 1..10   // repeat 1 to 10 times
"foo" @ 1..     // repeat at least once
"foo" @ ..10    // repeat at most 10 times

๊ฐ€์žฅ ํฐ ์งˆ๋ฌธ์€ ๊ตฌ๋ถ„ ๋ฌธ์ž๊ฐ€ ๋ฌด์—‡์ด๊ณ  ๋ฒ”์œ„๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

๋ถ„๋ฆฌ ๋ฌธ์ž์— ๊ด€ํ•ด์„œ๋Š” @ ๊ฐ€ ์ข‹์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. % ๋ฐ # ์„ ๊ณ ๋ คํ•˜๊ณ  ์žˆ์—ˆ์ง€๋งŒ ์ฒซ ๋ฒˆ์งธ ๊ฒƒ์€ ์ด๋ฏธ ๋ฌธ์ž์—ด ๋ณด๊ฐ„(์˜ˆ: Python)๊ณผ ์—ฐ๊ด€๋˜์–ด ์žˆ๊ณ  ๋‘ ๋ฒˆ์งธ ๊ฒƒ์€ ์ฃผ์„(๋‹ค์–‘ํ•œ ์–ธ์–ด)๊ณผ ์—ฐ๊ด€๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋˜ํ•œ ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๋ฅผ ์™„์ „ํžˆ ๊ฑด๋„ˆ ๋›ฐ๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

"foo" 1..10   // repeat 1 to 10 times
"foo" 1..     // repeat at least once
"foo" ..10    // repeat at most 10 times

๋ฒ”์œ„ ๋งˆํฌ์—…์€ Ruby์—์„œ ์˜๊ฐ์„ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. ์ €๋„ - ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ, ๋„ˆ๋ฌด ๋นผ๊ธฐ ๊ธฐํ˜ธ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์— ํŒŒ์ด์ฌ ๊ฐ™์€ : ๋„ ์ข‹์•„ ๋ณด์ž…๋‹ˆ๋‹ค.

๋ฐ˜๊ฐœ๋ฐฉ ๋ฒ”์œ„์— ๋Œ€ํ•ด์„œ๋Š” ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด + ๋ฐ - ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งˆํฌ์—…ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

"foo" @ 1+    // repeat at least once
"foo" @ 10-   // repeat at most 10 times

์•„์ด๋””์–ด๋‚˜ ์˜๊ฒฌ์ด ์žˆ์œผ์‹ญ๋‹ˆ๊นŒ?

์ด ๊ธฐ๋Šฅ์„ ์ง€์›ํ•  ๊ณ„ํš์ด๋ผ๋‹ˆ ์ •๋ง ๋Œ€๋‹จํ•ฉ๋‹ˆ๋‹ค!

๋‚˜๋Š” ๋‹น์‹ ์˜ (๊ธฐ๋ณธ) ์ œ์•ˆ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค:
"foo" @ 1..10 // 1~10ํšŒ ๋ฐ˜๋ณต
"foo" @ 1.. // ์ ์–ด๋„ ํ•œ ๋ฒˆ ๋ฐ˜๋ณต
"foo" @ ..10 // ์ตœ๋Œ€ 10๋ฒˆ ๋ฐ˜๋ณต

๋ฐ˜๊ฐœ๋ฐฉ ๋ฒ”์œ„์— ๋Œ€ํ•œ +/- ๊ตฌ๋ฌธ์ด ๋งˆ์Œ์— ๋“ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด์ค‘ ์  ๊ตฌ๋ฌธ์€ ํ›จ์”ฌ ๋” ์ง๊ด€์ ์ด๊ณ  ์ฝ๊ธฐ ์‰ฌ์šด IMO์ž…๋‹ˆ๋‹ค.

IMO "#"๋Š” ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ˆซ์ž/์„ธ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๋Š” ๋ฐ˜๋ฉด "@"๋Š” ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ฐธ์กฐ๋ฅผ ์˜๋ฏธํ•˜๋ฏ€๋กœ "#"์€ ์กฐ๊ธˆ ๋” ์ง๊ด€์ ์ด๊ณ  ์ฝ๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. (๊ทธ๋ฆฌ๊ณ  ์•„๋งˆ๋„ ๋ฏธ๋ž˜์— "@"๋ฅผ ๋ฌด์–ธ๊ฐ€์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”?). ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ์ •๋ง ์‚ฌ์†Œํ•œ ๋ฌธ์ œ์ด๋ฉฐ "@" ๊ตฌ๋ฌธ์— ๋งŒ์กฑํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฑด๋ฐฐ!

๊ฐ„๋‹จํ•œ ์˜๊ฒฌ: @ ๋ฐ % ๊ฐ€ # ๋ณด๋‹ค ๋” ๋‚˜์€ ์„ ํƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. PEG.js ๋ฌธ๋ฒ•์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ตฌ๋ฌธ ํ˜•๊ด‘ํŽœ, ํŠนํžˆ ์ถ”์ธก์„ ์‹œ๋„ํ•˜๋Š” ๊ตฌ๋ฌธ ํ˜•๊ด‘ํŽœ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ตฌ๋ฌธ(์˜ˆ: ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์˜ ์ฝ”๋“œ ํ˜•๊ด‘ํŽœ)์€ # ๋ฅผ ์ฃผ์„์˜ ์‹œ์ž‘์œผ๋กœ ํ•ด์„ํ•˜์—ฌ ํ•ด๋‹น ์ง€์ ๋ถ€ํ„ฐ "์ฃผ์„ ์ƒ‰์ƒ"์˜ EOL๊นŒ์ง€ ํ‘œ์‹œ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฌผ๋ก  ๋…ผ๋ฆฌ์™€ ์ถ”๋ก ์— ๊ธฐ๋ฐ˜ํ•œ ์„ ํ˜ธ๊ฐ€ ์•„๋‹ˆ๋ผ ์‹ค์šฉ์ฃผ์˜์— ๊ธฐ๋ฐ˜ํ•ฉ๋‹ˆ๋‹ค.

{num, num} ์— ๋Œ€ํ•œ ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ? { , num} ๋ฐ { num, } ๋Š” ์œ ํšจํ•œ js ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋ฉฐ {num, num} ๋ฐ { num } ๋Š” ๋ฌด์˜๋ฏธํ•˜๋ฏ€๋กœ ๋ฐ˜๋ณต์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์ž‘์—…์ด ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ๋œ ๊ฒฝ์šฐ์—๋„ ์˜๋ฏธ๊ฐ€ ์—†์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ œ์•ˆ๋œ ๊ฒƒ ์ค‘์—์„œ ์ด๋Ÿฌํ•œ ๋ณ€ํ˜•์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค(๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ๋‹น์‹ ์ด ์ €์ž์ด๊ธฐ ๋•Œ๋ฌธ์— ์„ ํƒํ•˜๋Š” ๊ฒƒ์€ ๋‹น์‹ ์—๊ฒŒ ๋‹ฌ๋ ค ์žˆ์Šต๋‹ˆ๋‹ค :))

// why we need separator, anyway? for me it looks very cool and simple to understand
"foo" 1..10   // repeat 1 to 10 times
"foo" 1..     // repeat at least once
"foo" ..10    // repeat at most 10 times

๋˜๋Š”

"foo"@1..10   // repeat 1 to 10 times
"foo"@1..     // repeat at least once
"foo"@..10    // repeat at most 10 times

๊ทธ๋Ÿฌ๋‚˜ ๋‘ ๋ฒˆ์งธ๋Š” ๋œ ๋ฐ”๋žŒ์งํ•˜๋‹ค

x..y / ..y / x.. ์•„์ด๋””์–ด๋Š” .. ๋•๋ถ„์— ์ผ๊ด€๋œ ์—ฐ์‚ฐ์ž๋กœ ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์— ๋งค์šฐ ๋ฉ‹์ ธ ๋ณด์ž…๋‹ˆ๋‹ค.

+/- ๋Š” ํ˜ผ๋™์„ ์ผ์œผํ‚ค๊ณ  .. ์œ„์˜ ์ถ”๊ฐ€ ์—ฐ์‚ฐ์ž๊ฐ€ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ดœ์ฐฎ์ง€ ์•Š์Šต๋‹ˆ๋‹ค( + ๋Š” ์ด๋ฏธ ์‚ฌ์šฉ๋จ).

๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๋‹ค์‹œ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ž‘๋™ํ• ๊นŒ์š”?

'foo'<1,5>
'foo'< ,3>
'foo'<2, >

< ๋ฐ > ๋Š” ํ˜„์žฌ ๋ฌธ๋ฒ•์—์„œ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—

:+1: ์ œ๊ฐ€ ๋ณด๊ธฐ์—๋Š” ์ข‹์•„ ๋ณด์ž…๋‹ˆ๋‹ค.

๋ฌผ๋ก  <,3> ๋Š” <0,3> ์™€ ๋™์ผํ•˜๋ฏ€๋กœ ์ตœ์†Œ ์ˆซ์ž๋งŒ ์š”๊ตฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ECMA๊ฐ€ JavaScript ์ •๊ทœ์‹์— ๋Œ€ํ•ด ์ˆ˜ํ–‰ํ•œ ์ž‘์—…๊ณผ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.

<,> ์ข‹์•„์š”. ๊ทธ๋Ÿฌ๋‚˜ <3> ์„ <3,3> ์™€ ๋™์ผํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.

๋™์˜ํ•ฉ๋‹ˆ๋‹ค. <> ๊ตฌ๋ฌธ์€ ๊ฐ€๋Šฅํ•œ ํ•œ RegExp์—์„œ {} ์˜ ๋™์ž‘์— ์ง์ ‘ ๋งคํ•‘๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ํ‹€๋ฆฌ์ง€ ์•Š์•˜๋‹ค๋ฉด ๋ฒ”์œ„์— ๋ณ€์ˆ˜ ์ด๋ฆ„์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š” ํ•œ ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๋ฅผ ์ถ”๊ฐ€ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

foo 1,2 fighter
bar ,3 tender
baz 4, lurhmann
qux 5 quux

๋ชจ๋‘ ๋ช…ํ™•ํ•ฉ๋‹ˆ๋‹ค.

@pygy , ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๋Š” ์ž ์žฌ์ ์œผ๋กœ ์–ธ์–ด ๊ตฌ๋ฌธ์˜ ์ง„ํ™”๋ฅผ ์–ต์ œํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋‚˜์ค‘์— ๋‹ค๋ฅธ ์šฉ๋„๋กœ ์‰ผํ‘œ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ์ด์ œ ๋ชจ๋“  ๊ณณ์—์„œ ๊ตฌ๋ฌธ ์ถฉ๋Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. <> ๋Œ€๊ด„ํ˜ธ ๋‚ด๋กœ ์ œํ•œํ•˜๋ฉด ์‰ผํ‘œ์™€ ์ˆซ์ž์˜ ํ‘œ๋ฉด์ ์ด ํฌ๊ฒŒ ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.

๋˜ํ•œ ์‚ฌ๋žŒ๋“ค์€ ์–ด์จŒ๋“  RegExps์—์„œ {1,6} ์Šคํƒ€์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ์ต์ˆ™ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ตฌ๋ฌธ์— ๋Œ€ํ•ด ๊ฐ•ํ•˜๊ฒŒ ๋Š๋ผ์ง€ ์•Š์ง€๋งŒ ์ด ๊ธฐ๋Šฅ์„ ์›ํ•˜๊ณ  ํ‘œํ˜„์‹์„ ๋ฒ”์œ„ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚ด ์‚ฌ์šฉ ์‚ฌ๋ก€: {42}\r\n... ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” IMAP ์„œ๋ฒ„ ์‘๋‹ต์—์„œ ๋ฆฌํ„ฐ๋Ÿด์„ ๊ตฌ๋ฌธ ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ 42 ๋Š” ๋ฌธ์ž์—ด์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ค„ ๋ฐ”๊ฟˆ ๋’ค์˜ ๋ฌธ์ž ์ˆ˜์ž…๋‹ˆ๋‹ค(์—ฌ๊ธฐ์—์„œ๋Š” ์ค„์ž„ํ‘œ๋กœ ํ‘œ์‹œ๋จ). IMAP ๋ฆฌํ„ฐ๋Ÿด์—๋Š” ๋ ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๊ฐ€ ์—†์œผ๋ฏ€๋กœ ๋ฌธ์ž ๊ณ„์‚ฐ์€ ์ด ์‘๋‹ต์„ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

์ œํ•œ ์‚ฌํ•ญ์˜ ๋ณ€์ˆ˜๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ๊ธธ์ด๊ฐ€ ํฌํ•จ๋œ ํ—ค๋”๊ฐ€ ์žˆ๋Š” ๋ฉ”์‹œ์ง€์— ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฌธ๋ฒ•

  = len:number message:.<len,len> .* {return message;}
number
  = n:[0-9] {return parseInt(n);}

๊ตฌ๋ฌธ ๋ถ„์„ํ•ด์•ผ

4[__] -> ['[', '_', '_', ']']
4[___] -> ['[', '_', '_', '_']
4[_] -> Error: expected 4 chars, got 3

์ด๊ฒƒ์€ ๋งŽ์€ ํ”„๋กœํ† ์ฝœ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ•ด๋‹น ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
expression |min,max| , ํ…œํ”Œ๋ฆฟ ๊ทœ์น™์— ๊บพ์‡  ๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹น์‹ ์€ ์•„์ง๋„ ์ด๊ฒƒ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?
ABNF ๋ฒ”์œ„์™€ ์œ ์‚ฌํ•œ ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

exp *     // 0 or more times
exp 1*    // at least once
exp *10   // up to 10 times
exp 1*10  // 1 to 10 times

์—ฌ๋ณด์„ธ์š”. ๊ตฌ๋ฌธ ๋ถ„์„ํ•  ๋ณต์žกํ•œ ํŒŒ์ผ ํ˜•์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜์€ ๋ฐ”์ด๋„ˆ๋ฆฌ, ๋ฐ˜์€ ASCII์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ๋ฌธ์ œ์˜ ๋‹จ์ˆœํ™”๋œ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค.

KK4TesRandom ๋˜๋Š” KK10TestATestBRandom

๋…ผ๋ฆฌ:

<StringIndicator><StringLength><String><otherStuff>

KK ๋Š” ๋ฌธ์ž์—ด์„ ํ‘œ์‹œํ•˜๋Š” ํ‘œ์‹œ๊ธฐ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ์ˆซ์ž(์—ฌ๊ธฐ์„œ๋Š” 4 ๋ฐ 10 )๋Š” ๋ฌธ์ž์—ด์˜ ๊ธธ์ด์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋ฌธ์ž์—ด ์ž์ฒด(์—ฌ๊ธฐ์„œ๋Š” Test ๋ฐ TestATestB ). ๋ฌธ์ž์—ด์€ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ํŒจํ„ด์œผ๋กœ ๋๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ธธ์ด ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ ํ˜•์‹์˜ ์ผ๋ฐ˜์ ์ธ ํŒจํ„ด์ด๋ผ๊ณ  ๋งํ•˜๊ณ  ์‹ถ์ง€๋งŒ ํ˜„์žฌ ๋ฌธ๋ฒ•์œผ๋กœ ๊ตฌ๋ฌธ ๋ถ„์„์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๊นŒ?

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๋‚ด ๋ธŒ๋žœ์น˜ range-dynamic-boundary ์—์„œ ๊ทธ๋Ÿฐ ๊ฒƒ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค:

start = len:nx data:.|len| { return data; };
nx = n:$[0-9]+ { return parseInt(n, 10); };

@๋ฏผ๊ฑด ์™€ ! ๊ทธ๊ฒƒ์€ ๋งค๋ ฅ์ฒ˜๋Ÿผ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค! ๊ตฌํ˜„๊ณผ ์งง์€ ์˜ˆ์ œ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋ช‡ ๊ฐ€์ง€ ํ…Œ์ŠคํŠธ๋ฅผํ–ˆ๊ณ  ๊ทธ๊ฒƒ์€ ํ›Œ๋ฅญํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ’€ ์š”์ฒญ์ด ๋งˆ์Šคํ„ฐ์—๊ฒŒ ์ˆ˜๋ฝ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋ฐ˜๋ณต ํšŸ์ˆ˜๋„ ์ข‹์•„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์•ฝ๊ฐ„ ๋‹ค๋ฅธ ๊ตฌ๋ฌธ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. Pegasus ๋Š” C#์˜ ๊ฒฝ์šฐ์—๋งŒ pegjs์™€ ๊ฑฐ์˜ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค: https://github.com/otac0n/Pegasus/wiki/Syntax-Guide#expressions

๊ทธ๋ฆฌ๊ณ  d<3> e<2,> f<1,5> ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด ์‚ฌ๋žŒ๋“ค์€ ๋ฌด์—‡์„ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๊นŒ? ์ง€๊ธˆ ๋ง‰ PEGjs์— ์ž…๋ฌธํ•˜๊ณ  ์žˆ์–ด์„œ ๋ง์น˜๋กœ ๋‚˜์‚ฌ๋ฅผ ๋Œ๋ฆฌ๋ ค๊ณ  ํ•˜๊ณ  ์žˆ๋Š”๋ฐ 1~6์ž๋ฆฌ ์ˆซ์ž๋งŒ ๋งž์ถ”๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. :)

๋‚˜๋Š” ๋‚ด ์ž์‹ ์˜ ๊ตฌํ˜„์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค(๊ตฌ๋ฌธ์€ #267 ์ฐธ์กฐ, ์ตœ์ข… ์†”๋ฃจ์…˜์€ ์ˆซ์ž, ๋ณ€์ˆ˜ ๋ฐ ์ฝ”๋“œ ๋ธ”๋ก์„ ๊ฒฝ๊ณ„๋กœ ์ง€์›ํ•จ). ๊ณง Peggy ๋ฅผ ์œ„ํ•œ PR์„ ์ค€๋น„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค(์œ ์ง€๋˜๋Š” PEG.js ํฌํฌ์˜ ๋ธŒ๋žœ๋“œ ๋ณ€๊ฒฝ)

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