์ ๋ 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๋ ๊ตฌ๋ฌธ ๋ถ์ ๋ค์ฌ์ฐ๊ธฐ(๋ฐ ๊ธฐํ ์ํฉ์ ๋ง๋ ๋ฌธ๋ฒ)๋ฅผ ์์ ํ๊ฒ ๋ง๋ค๊ธฐ ์ํด ์กฐ๊ฑด๋ถ ์ํ๋ฅผ ํธ์ํ๊ณ ํํ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
์ด๊ฒ์ด ๋ด๊ฐ ์ง๊ธ ํ๋ ์ผ์ด๋ฉฐ ๋ค์๊ณผ ๊ฐ์ด ํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ ๋ ฅ ํ์ผ์ ์ฌ์ ์ฒ๋ฆฌํ๊ณ ๊ณ ์ ํ ๋ค์ฌ์ฐ๊ธฐ/๋ด์ด์ฐ๊ธฐ ํ ํฐ์ ์ฝ์ ํฉ๋๋ค. ์ ๋ ๊ฐ๊ฐ {{{{ ๋ฐ }}}}๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ๋ฌธ๋ฒ์ด ์ปจํ ์คํธ๊ฐ ์๊ณ ์ ์์ ์ผ๋ก ๊ตฌ๋ฌธ ๋ถ์๋ ์ ์์ต๋๋ค. ํ/์ด ๊ฐ์ ์๋ง์ผ๋ก ๋ง๋ค ์ ์์ง๋ง ํ์ฒ๋ฆฌ๊ธฐ์์ ์์ ํ ์ ์์ต๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๋์์ผ๋ก ํ ํ์๊ฐ ์๋ค๋ฉด 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;
}
๋ค์์ ํ ์ ์๋ค๋ ์์ด๋์ด์ ๋ํด ์ด๋ป๊ฒ ์๊ฐํ์ธ์?
๊ทธ๋ฆฌ๊ณ ๊ตฌ๋ฌธ์ ๋ํด ์ด๋ป๊ฒ ์๊ฐํ์ญ๋๊น?
ํธ์ง: ๋ค์์ ์ ์๋ ๊ตฌ๋ฌธ ๋ฌธ๋ฒ์ ๋๋ค(์ฌ๋ฏธ๋ก):
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.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
์, ์ฃผ์ ์ฌํญ์ ๋์น์ฑ์ง ๋ชปํ์ต๋๋ค.
์ปดํ์ผ๋ฌ/์์ฑ๊ธฐ ์ชฝ์ ์ง์ํ๋ ค๋ฉด ๋ค์์ ์ํํด์ผ ํ๋ค๊ณ ๊ฐ์ ํ๋ ๊ฒ์ด ๋ง์ต๋๊น?
๊ทธ๋ฅ ํฅ์ ์ํด 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
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
min..
__, __ min..max
__, __ ..max
__ ๋๋ __ exact
__์ผ ์ ์์ต๋๋ค.๊ท์น ์๋ณ์์ ํผ๋๋ ์ ์์ผ๋ฏ๋ก ์ํ ๋ณ์๋ฅผ ์ฌ์ฉํ์ง ์์ต๋๋ค.
__range__, __++__, __--__ ๋๋ __ @__ ์กฐํฉ์ ์ฌ์ฉํ์ฌ ๊ฒฐ๊ณผ์ ๋ํด __action__ ๊ท์น์ ๋ ์์กดํ๋ PEG ๋ฌธ๋ฒ ํ์ผ์ ๋ง๋ค๊ณ ์ถ์ต๋๋ค. ๊ทธ๋ฌ๋ฉด ๊ณต๋ฐฑ(์: ๋ค์ฌ์ฐ๊ธฐ)์ ๊ฐ๋ฐ ์๊ฐ์ด ๋์ด๋ฉ๋๋ค. ๊ธฐ๋ฐ, ASCII ์ํธ ๋ฑ) ์ธ์ด ์ค๊ณ์ ๋ฐ/๋๋ ๊ตฌํ์๋ ์ฌ๋ฐ๋ฅธ ์์ ๊ณต๋ฐฑ์ด ๊ตฌ๋ฌธ ๋ถ์๋์๋์ง ํ์ธํ๋ ๊ฒ์ ๋ํด ๊ฑฑ์ ํ ํ์๊ฐ ์์ต๋๋ค.
์ด๊ฒ์ ๋ํ ํ๋ฌ๊ทธ์ธ ๊ฐ๋ฐ์๊ฐ __action__์ ์ธ์ด๊ฐ ๋ฌด์์ธ์ง์ ๋ํด _๋ ๋๋ ค์_ ์ต์ ํํ ์ ์๋ ํ์ ์์ฑ๊ธฐ๋ฅผ ๋ง๋ค ์ ์๋๋ก ํ์ฉํด์ผ ํฉ๋๋ค(๊ธฐ๋ณธ์ ์ผ๋ก JavaScript์ด์ง๋ง ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๋ฉด CoffeeScript, PHP ๋ฑ์ผ๋ก ๋ณ๊ฒฝํ ์ ์์).
๋ฐ๋ผ์ PEG.js๋ฅผ ์ฌ์ฉํ์ฌ Python์ ์ฆ์ ๊ตฌ๋ฌธ ๋ถ์ํ๋ ๊ฒ์ ์ค๋๋ ์๋ ์ฌ์ ํ ๋ถ๊ฐ๋ฅํ ๊ฒ ๊ฐ์ต๋๋ค. ๋ง์ต๋๊น?
๊ทธ๋ ์ง ์๋ค๋ฉด ์ด๊ฒ์ ๊ณง ์ฌ ๊ฒ์ ๋๊น? ์ฌ๋๋ค์ด ๊ธฐ์ฌํ ์ ์๋ ์ด ์์ ์ ์ํํ๋ ๋ฐ ํ์ํ ์ผ๋ จ์ ์์ ์ด ์์ต๋๊น?
JS์์ Python AST๋ฅผ ์ป๊ณ ์์ ํ ๋ค์ ๋์ผํ ํ์์ ์์ค ์ฝ๋๋ก ๋ค์ ๋ณํํ ์ ์๊ธฐ๋ฅผ ์ํ๋ ํ๋ก์ ํธ๊ฐ ์์ต๋๋ค. ๋ก๋๋งต.
@mindjuice ์์ง, 1.0 ์ดํ๋ก ์์ ๋์ด ์์ต๋๋ค.
๊ธฐ๋ค๋ฆด ์ ์๋ค๋ฉด ๋ด ์กฐ์นด์ ๋๋ ๋์ผํ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ๊ณ ๋ค์ฌ์ฐ๊ธฐ๋ฅผ ์ฒ๋ฆฌํ๋ TypeScript๋ก ์์ฑ๋ ํ์๋ฅผ ๋ง๋ค์์ต๋๋ค. ์์ง ๋ฌธ์ํ๋์ง ์์์ง๋ง ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค. ์๋ก์ด ์ธ์ด ๋์์ธ์ ์ํ ํ์๋ก ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์์ง ์์ ์ด ์งํ ์ค์ ๋๋ค.
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
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋ค์ฌ์ฐ๊ธฐ ๊ธฐ๋ฐ ๋ฌธ๋ฒ์ ๊ตฌ๋ฌธ ๋ถ์ํ๊ธฐ ์ํด ์ฌ์ฉ์ ์ ์ ์ฒ๋ฆฌ๊ธฐ์ ์ถ๊ฐํ๋ ๋ถ์์ฉ์ ์์กดํ๋ ๊ฒ์ ๋งค์ฐ ์ํํฉ๋๋ค. ๊ทธ๋ฅ ํ์ง ๋ง์ธ์. Pegjs๋ ๊ตฌ๋ฌธ ๋ถ์ ๋ค์ฌ์ฐ๊ธฐ(๋ฐ ๊ธฐํ ์ํฉ์ ๋ง๋ ๋ฌธ๋ฒ)๋ฅผ ์์ ํ๊ฒ ๋ง๋ค๊ธฐ ์ํด ์กฐ๊ฑด๋ถ ์ํ๋ฅผ ํธ์ํ๊ณ ํํ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
์ด๊ฒ์ด ๋ด๊ฐ ์ง๊ธ ํ๋ ์ผ์ด๋ฉฐ ๋ค์๊ณผ ๊ฐ์ด ํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ ๋ ฅ ํ์ผ์ ์ฌ์ ์ฒ๋ฆฌํ๊ณ ๊ณ ์ ํ ๋ค์ฌ์ฐ๊ธฐ/๋ด์ด์ฐ๊ธฐ ํ ํฐ์ ์ฝ์ ํฉ๋๋ค. ์ ๋ ๊ฐ๊ฐ {{{{ ๋ฐ }}}}๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ๋ฌธ๋ฒ์ด ์ปจํ ์คํธ๊ฐ ์๊ณ ์ ์์ ์ผ๋ก ๊ตฌ๋ฌธ ๋ถ์๋ ์ ์์ต๋๋ค. ํ/์ด ๊ฐ์ ์๋ง์ผ๋ก ๋ง๋ค ์ ์์ง๋ง ํ์ฒ๋ฆฌ๊ธฐ์์ ์์ ํ ์ ์์ต๋๋ค.