ç§ã¯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ã¯ãã€ã³ãã³ãïŒããã³ãã®ä»ã®ç¶æ³äŸåææ³ïŒã®è§£æãå®å šã«ããããã«ãæ¡ä»¶ä»ãç¶æ ãããã·ã¥ããã³ãããããæ©èœãè¿œå ããå¿ èŠããããŸãã
ããã¯ç§ãä»è¡ã£ãŠããããšã§ããããããè¡ãããšããå§ãããŸããå ¥åãã¡ã€ã«ãååŠçããç¬èªã®ã€ã³ãã³ã/ã¢ãŠããã³ãããŒã¯ã³ãæ¿å ¥ããŸãã ç§ã¯ãããã{{{{ãš}}}}ã䜿çšããŸãã ããããã°ãææ³ã¯æèèªç±ã§ãããéåžžã©ããã«è§£æã§ããŸãã è¡/åã®å€ãæ··ä¹±ããå¯èœæ§ããããŸããããã¹ãããã»ããµã§ä¿®æ£ã§ããŸãã
javascriptãã¿ãŒã²ããã«ããå¿ èŠããªãå Žåã¯ãCïŒçšã®ç§ã®pegjsã¯ããŒã³ã§ããPegasusãããã·ã¥/ãããç¶æ ããµããŒãããŠããŸãã ãããããªããæãããšãæ£ç¢ºã«è¡ãæ¹æ³ã«é¢ããwikiã®èšäºã§ãïŒ https ïŒ
pegjsãç§ã®æ§æãç¶æ ããŒã¹ã®æ§æ解æã®éå§ç¹ãšããŠäœ¿çšããããšãææ¡ããããšæããŸãã
ç¶æ ãå®å šã«æŒããŠãããããæ©èœã¯çŽ æŽãããã§ãã JavascriptããŒã¹ã®å Žåã¯ããã䜿çšããŸãã 解æã®ããã ãã«CLRãçµ±åãã䟡å€ã¯ãããŸããã
ãããç§ãèãããã®ã§ãã ãã®å Žåãç§ã¯ããããèªåã®æ¹åãpegjsã«ããã¯ããŒãããããšãè©Šã¿ãã¹ãã ãšæããŸãã
ãã ãã@ dmajdaãšäŒè©±ããã«ãããè¡ãå¿ èŠã¯ãããŸããã
@ otac0nããã§ããã ç§ã¯CïŒãæžããŸããã JavaScriptã¯ç§ã«ãšã£ãŠã¯ããã«åªããŠããŸãã
ã€ã³ãã³ãããŒã¹ã®èšèªã¯éèŠã§ãã 1.0.0以éã®è§£æãåçŽåããããšãæ€èšããããšæããŸãã
ãã®åé¡ã¯ããã¬ãµã¹ãšåãããã«ãïŒ285ã§ææ¡ãããŠããããã«ãäžè¬çã«ç¶æ ãèš±å¯ããããšã§æããã解決ããããšæããŸãã ããã«ã¢ã€ãã¢ããããŸãïŒä»¥äžã¯ãã¬ãµã¹ã®éèŠãªç©ºçœã®ææ³ãpegjsã«ç¿»èš³ããç§ã®æ§æã®ã¢ã€ãã¢ãè¿œå ãããã®ã§ãïŒïŒ
{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ã§ã€ã³ãã³ãã解æããããã®å ã®ã€ã³ãã³ãã¯ãªããªã£ããšæããŸãã
ã€ã³ãã³ãã解æããããã®åé¿çãããããšãæå³ããŸãããã³ã¡ã³ãã«ãããšããããã®åé¿çã¯ç¹å®ã®å Žåã«å€±æããããšããããŸãã
ç¶æ³ãæ確ã«ããŸããããPEG.jsã§ã€ã³ãã³ãããŒã¹ã®èšèªã解æããããšã¯å¯èœã§ãã äžèšã®ããŸããŸãªè§£æ±ºçããããŸãããããããæãããããšããŠãå¥ã®è§£æ±ºçãäœæããŸããïŒããã¯ã2ã€ã®ã¹ããŒãã¡ã³ããå«ãåçŽãªèšèªã®ææ³ã§ããããã®ãã¡ã®1ã€ã«ã¯ã€ã³ãã³ãããããµãã¹ããŒãã¡ã³ããå«ããããšãã§ããŸããããšãã°if
Pythonã§ã¯
ãã¹ãŠã®ãœãªã¥ãŒã·ã§ã³ã«å ±éããããšã®1ã€ã¯ãã€ã³ãã³ãç¶æ ãæåã§è¿œè·¡ããå¿ èŠãããããšã§ãïŒPEG.jsã§ã¯è¿œè·¡ã§ããªãããïŒã ããã¯ã2ã€ã®å¶éãããããšãæå³ããŸãã
å¶é1ã¯ããã©ãŒãã³ã¹ã®åé¡ãåŒãèµ·ããå ŽåããããŸãããå¶é2ãåé¡ã«ãªãèšèªã¯å€ããªããšæããŸãã
ãã®ç¶æ ã¯1.0.0ãŸã§ã¯åé¡ãããŸãããããã®åŸãã€ããã®ãããã¯ã«æ»ãäºå®ã§ãã æ¹åã®æåã®ã¬ãã«ã¯ãããæ瀺çãªç¶æ 远跡ã䜿çšããŠïŒäžèšã§ææ¡ããããã«ïŒããŸãã¯ããã¯ãã©ããã³ã°ããã¯ãæäŸããããšã«ãã£ãŠïŒç¶æ ãæ£ããå±éã§ããããã«ïŒå¶é2ãåãé€ãããšã§ãã 2çªç®ã®ã¬ãã«ã¯ã宣èšçãªæ¹æ³ãæäŸããããšã«ãããã€ã³ãã³ãç¶æ ãæåã§è¿œè·¡ããå¿ èŠæ§ãåãé€ãããšã§ãã ããã¯å¶é1ã«åœ¹ç«ã€å¯èœæ§ããããŸãã
Hãããã§èª¬æããããã«ãé©åãªããã¯ãã©ããã³ã°ããµããŒãããPEG.jsçšã®ïŒå°ããªããããŒãªïŒããããäœæããŸããïŒ https ïŒ
ãã³ããããããªããð
èšèšããŠããèšèªã®CSONããŒãµãŒãšYAMLããŒãµãŒã®äœæãæ€èšããŠãããšãããPEG.jsã䜿çšããŠã€ã³ãã³ãããŒã¹ã®ããŒãµãŒãäœæããæ¹æ³ãæ€èšããŠãããšãã«ã次ã®ãããªç°¡åãªæ¹æ³ãæãã€ããŸããã
1ïŒããã·ã¥/ãããç¶æ
ã«äŸåããŸãã
2ïŒã¢ã¯ã·ã§ã³å
ã®ã³ãŒããä»ããŠã€ã³ãã³ãã¬ãã«ãã¢ãµãŒããã
äžèšã®2ã€ã®ãœãªã¥ãŒã·ã§ã³ã®ããããããçæãããããŒãµãŒã«å®éã«ããã©ãŒãã³ã¹ã®åé¡ãè¿œå ããããšã«æ°ã¥ããŸããã ããã«ç§ã®æèŠã§ã¯ïŒ
1ïŒç¶æ
ã«äŸåãããšãéãPEG.jsæ§æãè¿œå ãããã ãã§ãªããã¢ã¯ã·ã§ã³ããŒã¹ã®ç¶æ
åŠçããµããŒãããå¿
èŠããããããçæã§ããããŒãµãŒã®ã¿ã€ãã«ã圱é¿ãäžããå¯èœæ§ããããŸãã
2ïŒã¢ã¯ã·ã§ã³ã«ã³ãŒããè¿œå ãããšãèšèªã«äŸåããã«ãŒã«ãäœæãããããšããããŸããäžéšã®éçºè
ã«ãšã£ãŠã¯ããã©ã°ã€ã³ã䜿çšããŠCãPHPãªã©ã®ä»ã®èšèªã®ããŒãµãŒãçæããã«ã¯ãã«ãŒã«ã«å¯Ÿããã¢ã¯ã·ã§ã³ãåŠçãããã©ã°ã€ã³ãå¢ããå¿
èŠããããŸãã 1ã€ãŸãã¯2ã€ã®å€æŽããµããŒãããããã ãã®ãã倧ããªãã«ãã·ã¹ãã ãæå³ããŸãã
ãã°ããããŠãç§ã¯PEG.jsããŒãµãŒã®ç¬èªã®ããªã¢ã³ãã®äœæãéå§ãã次ã®ããã«èããŸãããã€ã³ã¯ãªã¡ã³ãïŒ "++"ïŒããã³ãã¯ãªã¡ã³ãïŒ "-"ïŒãã¬ãã£ãã¯ã¹æŒç®åïŒ__ ++ expression__ããã³__-- expression__ïŒã䜿çšããªãã®ã¯ãªãã§ããã ïŒäžèŽåŒïŒ__expression * __ãŸãã¯__expression + __ïŒã®çµæãåŠçããŸãã
以äžã¯ã @ dmajdaã®åçŽãªæå³ããŒã¹ã®èšèªã«
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 more__äžèŽã§ãããšæ³å®ãããã以å€ã®å Žåã¯_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__ã¯ãchoiceãsequenceããŸãã¯rule_refã®ã¿ã€ãã§ããå¿
èŠããããŸãã
2ïŒ__ expression * __ãŸãã¯__expression + __ã®çæãããããŒãµãŒã«ãã£ãã·ã¥ããŒã¹ã®ãã§ãã¯ãè¿œå ããŸããããã¯ãäžèŽãè¿ãåã«ãæäœéå¿
èŠãªäžèŽãæºããããŠããããšãè¡šæããŸãã
3ïŒãªãã·ã§ã³ã§ãçæãããããŒãµãŒãå®è£
ãããã«ããŒã¡ãœãããè¿œå ããŸããããã¯ãç¹å®ã®ã«ãŒã«ã«å¿
èŠãªäžèŽæ°ãè¿ããŸãã nMatches( name: String ): Number
@futagoza ãããã¯ãããã§è³¢ãã§ãã ããã¯ããã§ããã ç§ã¯ç¶æ ãåŠçããããŒãµãŒã«åãçµãã§ããŸãããæ¬åœã«å¿ èŠãªç¶æ ã¯ã€ã³ãã³ãã¬ãã«ã ãã§ãã ç§ã¯ãã®ã¢ã€ãã¢ã䜿çšããŠãããªãã«ãããä¿¡çšãããããããŸããã ã€ã³ãã³ãã¬ãã«ã远跡ããã«ã¯ãããã·ã¥/ãããç¶æ ãå¹æçã«å¿ èŠã§ãããããäžéšã®æé©åã劚ããããå¯èœæ§ããããŸãããããã®ã»ãã³ãã£ã¯ã¹ã¯éåžžã«åªããŠããŸãã
ææ³ã«æŒç®åãè¿œå ããå Žåã¯ã@ãã¬ãã£ãã¯ã¹æŒç®åãè¿œå ããããšããå§ãããŸãã ç®çã¯ãã·ãŒã±ã³ã¹ããåäžã®ã«ãŒã«çµæãåçŽã«æœåºããããšã§ãã ããã䜿çšãããšããµã³ãã«ã®ææ³ãããã«ãããã«ãªããŸãã äºçŽ°ãª{returnx}ã¢ã¯ã·ã§ã³ã¯ãããããŸããã
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ã«ã¯ã
https://github.com/krisnye/pegjs
ããã¯éåžžã«åçŽãªè¿œå ã§ãã
@krisnye +1ã¯ãææ³ããŒã¹ã®å®è£ ã§ãçŽ æŽãããã·ã³ãã«ã§ãã ãããããã°ããããPEG.jsã®ããªã¢ã³ãã«è¿œå ããŸãð
@kristianmandrupããªããç§ã®ææ¡ã®ããã«ã³ãããããã®ãèŠãŠãã ãã
@futagozaããŠãã ããã
ã€ã³ãã³ãããžãã¯ã«ã€ããŠååãšè©±ãåã£ãŠããã®ã§ã次ã®æ§æèŠçŽ ãææ¡ããŸã
//ååä»ãç¶æ
å€æ°ãã€ã³ã¯ãªã¡ã³ãããŸã
èå¥å++
//ååä»ãç¶æ
å€æ°ããã¯ãªã¡ã³ãããŸã
èå¥å -
//äžå®éãŸãã¯ç¶æ
å€æ°ãç¹°ãè¿ããŸãïŒå€æ°ããŸã ã€ã³ã¯ãªã¡ã³ããããŠããªãå Žåã¯ããã©ã«ãã§ãŒãïŒ
ã«ãŒã«{æŽæ°| èå¥å}
//å®æ°ãŸãã¯ç¶æ
å€æ°ã䜿çšããŠæå°/æ倧ãç¹°ãè¿ããŸã
ã«ãŒã«{æŽæ°| èå¥åãæŽæ°| èå¥å}
ç§ãã¡ãåãçµãã§ããããŒãµãŒã¯ä»»æã®ç¶æ ãåŠçã§ããŸãããæ£çŽãªãšãããã€ã³ãã³ãã®è§£æã«å¿ èŠãªã®ã¯äžèšã®ãã¹ãŠã§ãã
ã©ããããããšãïŒ ããããšãŠãç°¡åãªããããªããèšåããããšããããŸãããããšããã«ãå°çšã®ããã©ãŒã¯ãäœã£ãŠã¿ãŸããã;ïŒ
也æ¯ïŒ
@krisnye
rule{ STATE_REPEAT / RANGE }
ã¯rule{ ACTION }
ãšæ··åãããå¯èœæ§ãããããããã®ã¢ãããŒãã¯@dmajdaã«ãã£ãŠæåŠãã@kristianmandrup _ïŒOFF TOPICïŒ_ç§ã¯æ©èœã®èšèšãæã«ã¯å®è£ ã®äœæã¯åŸæã§ããããããã®ãã¹ããšãã³ãããŒã¯ã¯ã²ã©ãã®ã§ãéåžžã¯PCã®ãã©ã€ããŒãéãªããžããªãã£ã¬ã¯ããªã«ïŒãã¹ãããã³ãããŒã¯ãªãã§ïŒåäœããããªã¢ã³ããäœæããŸãããããŠããããå¿ããŠãã ããð€£ã PEG.jsã®çŸåšã®ããªã¢ã³ãïŒePEG.jsðãšããååãPEG.jsã®æ¡åŒµãªã©ã€ãïŒã«ã€ããŠã¯ãããã§èª¬æãããã®ãšä»ã®æ©èœïŒç¯å²ãã€ã³ããŒãããã³ãã¬ãŒããªã©ïŒãè¿œå ããŠããã®ã§ãè¿œå ããŸããã¹ããšãã³ãããŒã¯ã§ãããçŸåšãæéãããã£ãŠããC ++ãããžã§ã¯ãã«ãåãçµãã§ãããããETAã¯ãããŸããã
@futagozaããããšãããããŸã:)æ©èœæ¡åŒµãèŠãŠãã€ã³ãã³ãã®ãµããŒãã«ã€ããŠã¯è§ŠããŠããŸããã ããã¯å«ãŸããŠããŸãããææžåãããŠããªãããä»åŸç»å ŽããŸããïŒ
ãã®ãªã¹ãã®ä»ã®èª°ãããç§ãåæ§ã«èª¿ã¹ãå¯èœæ§ã®ããä»ã®ããŒãµãŒãã«ããŒ/ãžã§ãã¬ãŒã¿ãŒãœãªã¥ãŒã·ã§ã³ãææããŠãããŸããã æçš¿ããŠãã ããïŒ ä¹Ÿæ¯ïŒ
@kristianmandrupç§ãç¥ãéãå«ãŸããŠããŸãããã @ dmajdaã¯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ã§PythonASTãååŸãããããå€æŽããŠãããåããã©ãŒãããã®ãœãŒã¹ã³ãŒãã«å€æã§ããããã«ããããããžã§ã¯ããããã®ã§ãæ確ãªããšãããã°ãããå®çŸããããšã«èå³ããããŸããããŒããããã
@mindjuiceãŸã ã1.0以éã«äºå®ãããŠããŸãã
åŸ ãŠãªãå Žåã¯ãç¥ãšç§ã¯ãåãæ§æã䜿çšããŠã€ã³ãã³ããåŠçããTypeScriptã§èšè¿°ãããããŒãµãŒãäœæããŸããã ãŸã ææžåãããŠããŸããããéåžžã«ç°¡åã§ãã æ°ããèšèªèšèšã®ããŒãµãŒãšããŠäœ¿çšããŠããããããŸã äœæ¥ãé²è¡äžã§ãã
chevrotainãªã©ã®ãµããŒããåããå¥ã®ããŒãµãžã§ãã¬ãŒã¿ãè©Šãããšãã§ããŸã
PEGjsã䜿çšããŠPythonã®ãããªã€ã³ãã³ãã解æããããšã¯éåžžã«å¯èœã§ãããšæããŸãã
以äžã®äŸã§ã¯ã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ã¯ãã€ã³ãã³ãïŒããã³ãã®ä»ã®ç¶æ³äŸåææ³ïŒã®è§£æãå®å šã«ããããã«ãæ¡ä»¶ä»ãç¶æ ãããã·ã¥ããã³ãããããæ©èœãè¿œå ããå¿ èŠããããŸãã
ããã¯ç§ãä»è¡ã£ãŠããããšã§ããããããè¡ãããšããå§ãããŸããå ¥åãã¡ã€ã«ãååŠçããç¬èªã®ã€ã³ãã³ã/ã¢ãŠããã³ãããŒã¯ã³ãæ¿å ¥ããŸãã ç§ã¯ãããã{{{{ãš}}}}ã䜿çšããŸãã ããããã°ãææ³ã¯æèèªç±ã§ãããéåžžã©ããã«è§£æã§ããŸãã è¡/åã®å€ãæ··ä¹±ããå¯èœæ§ããããŸããããã¹ãããã»ããµã§ä¿®æ£ã§ããŸãã