å€æ°ã䜿çšããŠã«ãŒã«ããã©ã¡ãŒã¿ãŒåã§ãããšäŸ¿å©ã§ãã
= '\"' parse_contents '\"' ->
/ '\'' parse_contents('\'') '\'' ->
/ '+' parse_contents('+') '+' -> /* sure why not :) */
parse_contents(terminator='\"')
= ('\\' terminator / !terminator .)+ -> return stuff
ããã«ããããªãã®äœæ¥éãç¯çŽãããããŸãã¯çŸåšäžå¯èœãªããšãå¯èœã«ãªãç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã¯ãããŸããïŒ
ã¬ãã«ãåŒæ°ãšããŠæž¡ãããã«ãŒã«ãåŒã³åºãããšã«ãããã€ã³ãã³ãã¬ãã«ã®è§£æãã¯ããã«ç°¡åã«ãªããŸãã
ãŸããçŽç²ãªDRYããžãã¯ã§ã¯ãããã®æåã§åºåããããã®ããšã¹ã±ãŒãã·ãŒã±ã³ã¹ãªã©ã§åºåãããªã©ã®å Žåãã«ãŒã«ïŒããã³ãã®ã¢ã¯ã·ã§ã³ïŒïŒã3åå®è¡ãããããã delimited('\'', '\\')
ã®ãããªãã®ãåŒã³åºãæ¹ãé©åã§ãã ã
ãã£ãšæ確ã«ãã¹ãã ã£ãã ãå ·äœçããšã¯ããèšèªXã®ææ³ã«åãçµãã§ããŠã1ã€ã«çµã¿åãããããšãã§ãã5ã€ã®ã«ãŒã«ããããŸããããã«ãããŸããã®ãããªãã®ãæ¢ããŠããŸãããã€ãŸããçŸå®ã®äžçãèŠããã£ãã®ã§ãããŠãŒã¹ã±ãŒã¹ãšå®éã®ã³ãŒãã ãã®ããšããããã®æ©èœãã©ã®ãããªå Žåã«ããããŠäœäººã®äººã ã«åœ¹ç«ã€ããããããå€æããããšãã§ããŸãã
ç§ã¯ãã®æ©èœèªäœã«å察ããŠããã®ã§ããããåãåããªãã§ãã ããã è€éããšå®è£ ã³ã¹ãã®ããã«ãç§ã¯äžè¬çã«ãèšèªãéçºè ã®ããäžéšã«ã®ã¿åœ¹ç«ã€æ©èœãå®è£ ããããããŸããã ãããŠãã®å Žåãã³ã¹ãã¯æ¯èŒçé«ããªããŸãã
javascriptã®ããŒãµãŒãäœæããã ãã§ã string = delimited_by('\'') / delimited_by('\"')
ãäœæããåŸã§regexp = delimited_by('/')
ãäœæããããšãã§ããŸãã
æè¿ãç§ã¯èªåã®èšèªã®ããŒãµãŒãæžããŠããŸãã ç§ã¯Pythonçšã«æžããPEGãã¬ãŒã ã¯ãŒã¯ã«ãã®ãããªãã®ããããŸãïŒ
LeftAssociative(op, subrule): l:subrule rest:(op subrule)* -> a_recursive_function_that_reverses_rest_and_makes_bintrees(l, op, subrule)
ãããŠãç§ã¯æ¬¡ã®ããã«æžãããšãã§ããŸãïŒ
...
exp_mult = LeftAssociative(/[\*\/%]/, exp_paren)
exp_add = LeftAssociative(/[\+-]/, exp_mult)
ç§ã¯C ++ãšã»ãŒåãã¬ãã«ã®åªå é äœãæã£ãŠããã®ã§ïŒãã®ãã¹ãŠã®æŒç®åã«å ããŠããã«ããã€ãïŒãã§ãã©ãã»ã©åœ¹ç«ã€ãæ³åããŠã¿ãŸãããã 解æåŒã¯ãŸã å®æããŠããŸãããããã§ã«12å䜿çšããŠããŸãã
ããã¯ããã€ã³ããŒããæ©èœãšçµã¿åããããšçŽ æŽãããã§ããã
require(CommaSeparatedList.pegjs)
require(StringLiteral.pegjs)
require(IntegerLiteral.pegjs)
...
Function
= name:FuncName "(" args:CommaSeparatedList(Literal) ")"
Hash
= "{" props:CommaSeparatedList(Prop) "}"
Prop
= Key ":" Literal
Literal =
StringLiteral / IntegerLiteral
ïŒããã¯OPã®èŠæ±ãããå°ãè€éã§ãããããèªäœã®ã¹ã¬ãããæ£åœåããã«ã¯è¿ãããããã«èŠããŸãããïŒ
ç§ã¯PEG.jsã®å©ããåããŠR5RSã¹ããŒã ããŒãµãŒãæ§ç¯ããŠããŸãã ã³ã³ããã¹ãã¢ãŠã§ã¢ãªæ§æ解æãå¿ èŠãšããæºåŒçšç¬Šãé€ããŠããã¹ãŠããã©è²ã§ãã ãã³ãã¬ãŒããããªã³ã¶ãã©ã€ã§ã«ãŒã«ãçæããããã«ã«ãŒã«ããã©ã¡ãŒã¿ãŒåã§ãããšäŸ¿å©ã§ãé¢åãªåŸåŠçã倧éã«åé¿ã§ããŸãã ããšãã°ãç°¡ç¥åãããæºåŒçšææ³ã¯æ¬¡ã®ããã«ãªããŸãã
quasiquotation = qq[1]
qq[n] = "`" qq_template[n]
qq_template[0] = expression
qq_template[n] = simple_datum / list_qq_template[n] / unquotation[n]
list_qq_template[n] = "(" qq_template[n]* ")" / qq[n+1]
unquotation[n] = "," qq_template[n-1]
ããŒã«ã«è¿œå ããããšã«èå³ãããã°ããã®æ©èœã®éçºã«è²¢ç®ããããšã«èå³ããããŸãã
ãããè¡ãäž»ãªçç±ã¯ãã³ã³ããã¹ãã«ææãªææ³ããµããŒãããããšã§ããããã¯ãç§ãééã£ãŠããªããã°ãæã人æ°ã®ããèšèªã§ãïŒCãšPythonã«ã¯ã³ã³ããã¹ãåºæã®ãã®ãããããšã¯ç¢ºãã§ãïŒã Trevor Jimã«ãããšãHaskellãæèèªç±ã§ã¯ãªããã»ãšãã©ã®èšèªã¯æèèªç±ã§ã¯ãªããšäž»åŒµããŠããŸãã
http://trevorjim.com/haskell-is-not-context-free/
http://trevorjim.com/how-to-prove-that-a-programming-language-is-context-free/
ïŒPEGã®ããã«ïŒããã¯ãã©ãã¯ã§ããããŒãµãŒã§å€éšç¶æ ã䜿çšããããšã¯å±éºã§ããããã®ããŒãµãŒã§èŠããããããªåé¡ãåŒãèµ·ããå¯èœæ§ããããŸãã
{ var countCs = 0;
}
start = ((x/y) ws*)* { return countCs }
x = "ab" c "d"
y = "a" bc "e"
c = "c" { countCs++; }
bc = "bc" { countCs++; }
ws = " " / "\n"
äžèšã¯ã1ã®æ£è§£ã§ã¯ãªã2ãè¿ããŸãããã®ãããªåé¡ã¯ãæšè«ããã®ãé£ããå Žåããããæœè¡æ§ã®èŠã€ãã«ãããã°ãäœæããå¯èœæ§ããããèŠã€ãã£ãå Žåãåé¿ããã®ãéåžžã«å°é£ã«ãªãå¯èœæ§ããããŸãã ã PEGã«ãã£ãŠè¿ãããããŒã¿ã®åŸåŠçãè¡ããã«ãããè¡ãæ¹æ³ããç§ã«ã¯ããããŸããã ã©ããããããããªãã®ããŒãµãŒèªäœãã«ãŠã³ããå¿ èŠãšãããªããããã¯åã«éãæªãã§ãã
çŸåšãïŒå±éºãªããšã«ïŒå€éšç¶æ ã䜿çšããããšããã³ã³ããã¹ãã«ææãªææ³ã解æããå¯äžã®æ¹æ³ã§ãã ãã©ã¡ãŒã¿åãããã«ãŒã«ã䜿çšãããšãããŒãµãŒã¯ç¡å¹ãªç¶æ ã®ãªã¹ã¯ãåãããšãªãããã解æã§ããŸãã
start = countCs:((x<0>/y<0>) ws*)* { return countCs.reduce(function(a,b){return a+b[0];}, 0); }
x<count> = "ab" theCount:c<count> "d" { return theCount; }
y<count> = "a" theCount:bc<count> "e" { return theCount; }
c<count> = "c" { return count++; }
bc<count> = "bc" { return count++; }
ws = " " / "\n"
ãããããããªãã¯å®éã®ç¶æ³ãå°ããŸããããããŠPythonã®ç©ºçœã€ã³ãã³ãæ§æã¯æããã«ããã§ã®äŸã§ãã ãªãïŒPEGã§äœæããŠããããã°ã©ãã³ã°èšèªïŒã§åæ§ã®ç©ºçœã€ã³ãã³ãæ§æãå®è¡ããããšæããŸãã ãããããã¹ãŠãå°çã«å¹ãé£ã°ããããªç¡å¹ãªç¶æ ããã£ããäœæããŠããŸãå¯èœæ§ãããå Žåã¯ããã®ãããªãã®ãå®è£ ããããããŸããã Cã®x * yã®ããã«ãã³ã³ããã¹ããå¿ èŠãšãã解ææ§é ã«ååãä»ããããšãã§ããŸãïŒx x yãŸãã¯yã¯xåã®å€ãžã®ãã€ã³ã¿ãŒãšããŠå®çŸ©ãããŠããŸããïŒïŒã
ã³ã³ããã¹ãã«ææãªææ³ã解æå¯èœã«ããã«ã¯ããã©ã¡ãŒã¿ãŒåãããã«ãŒã«ã«ãã§ã«äžèŽããéšååŒããè¿ãããæ å ±ãå¿ ãæž¡ãå¿ èŠãããããšã«æ³šæããŠãã ãããããããªããšãããŒãµãŒã¯å®éã«ã³ã³ããã¹ãã䜿çšã§ããŸããã ããã¯ããã©ã¡ãŒã¿ãŒåããã解æã䜿çšå¯èœã§ããã以åã«äžèŽããåŒã®ã©ãã«ã«ïŒå€æ°ãšããŠïŒã¢ã¯ã»ã¹ã§ããå Žåã«ã®ã¿æ©èœãããLimaã«ã€ããŠæ€èšããŠããæååã¿ã€ãã®å®éã®äŸã§ãã
literalStringWithExplicitLength = "string[" n:number ":" characters<n> "]"
number = n:[0-9]* {return parseInt(n.join(''));}
characters<n> = c:. { // base case
if(n>0) return null; // don't match base case unless n is 0
else return c;
}
/ c:. cs:characters<n-1> {
ret c+cs
}
ããã«ãããstring [10ïŒabcdefghij]ã®ãããªæååã解æã§ããŸãã çŸç¶ã§ã¯ãçŽç²ãªPEG.jsã§ã¯ãããè¡ãããšã¯ã§ããŸããã ããªãã¯æ¬¡ã®ãããªã²ã©ãããšãããŸããïŒ
{ var literalStringLengthLeft=undefined;
}
literalStringWithExplicitLength = "string[" n:specialNumber ":" characters "]"
specialNumber = n:number {
literalStringLengthLeft = n;
return n;
}
number = n:[0-9]* {return parseInt(n.join(''));}
characters = c:character cs:characters? {
return c + cs
}
character = c:. {
if(literalStringLengthLeft > 0) {
literalStringLengthLeft--;
return c;
} else {
literalStringLengthLeft = undefined;
return null; // doesn't match
}
}
å€ãã®ãããã³ã«ã«ã¯ããã®çš®ã®è§£æã®å¿ èŠæ§ããããŸããããšãã°ãIPv4ãã±ããã«ã¯ããã®å šé·ãèšè¿°ãããã£ãŒã«ãããããŸãã ãã±ããã®æ®ãã®éšåãé©åã«è§£æããã«ã¯ããã®ã³ã³ããã¹ããå¿ èŠã§ãã IPv6ãUDPãããã³ããããä»ã®ãã±ããããŒã¹ã®ãããã³ã«ã«ã€ããŠãåãããšãèšããŸãã TCPã䜿çšããã»ãšãã©ã®ãããã³ã«ã§ããåãæŠå¿µçãªæåã¹ããªãŒã ã䜿çšããŠè€æ°ã®å®å šã«å¥åã®ãªããžã§ã¯ããéä¿¡ã§ããå¿ èŠãããããããã®ãããªãã®ãå¿ èŠã«ãªããŸãã
ãšã«ããããããåªããæ©èœã§ããã ãã§ãªãã匷åãªæ©èœã§ããã ãã§ãªããå€ãã®ããŒãµãŒã«æ¬ ããŠããæ¬åœã«äžå¯æ¬ ãªæ©èœïŒçŸæç¹ã§ã¯ãPEG.jsãå«ãïŒã§ãããšæãçç±ãããã€ãæããŠããã ããã°å¹žãã§ãã ïŒã
Pegasus ïŒæ§æã®ã»ãšãã©ãpeg.jsãšå
±æãããããžã§ã¯ãïŒã¯ãç¶æ
ã®ãã£ã¯ã·ã§ããªãå€æŽããæ©èœãäžãããã#STATE{}
åŒã䜿çšããããšã§ãããã解決ããŸãã ãã®ç¶æ
ã®ãã£ã¯ã·ã§ããªã¯ãã«ãŒã«ãããã¯ãã©ãã¯ããããšãã«ããã¯ãã©ãã¯ãããŸãã ããã«ãããéèŠãªç©ºçœã®è§£æããµããŒãã§ããŸãïŒè©³çŽ°ã«ã€ããŠã¯ãéèŠãªç©ºçœã«é¢ããwikiãšã³ããªãåç
§ããŠãã ããïŒã
ãŸãã解æã«ãŒãœã«ãšãšãã«ç¶æ ãããã¯ãã©ãã¯ããããšã«ãããã¹ããŒããã«ã«ãŒã«ã®ã¡ã¢åãå®è¡ã§ããŸãã
Peg.jsã§ãåãããšãç°¡åã«ã§ãããšæããŸãã
ã«ãŒã«ãããã¯ãã©ãã¯ããå Žåããã¬ãµã¹ã¯ããã¯ãã©ãã¯ç¶æ ãã©ã®ããã«ç®¡çããŸããïŒ å€æŽãããããã°ã©ã ç¶æ å šäœã®ã¹ãããã·ã§ãããä¿æããå ã«æ»ãããšãã§ãããšæ³åã§ããŸãããããã¯ã³ã¹ããããããŸãã å€æŽãããå€æ°ã®ã¿ã®ã¹ãããã·ã§ãããä¿æããããšãæ³åã§ããŸããããŠãŒã¶ãŒããããæå®ããå¿ èŠããããããŒãµãŒã®äœæãè€éã«ãªãããããŒãµãŒãã³ãŒãã®äžéšã§å€æŽããããã¹ãŠã®ç¶æ ãäœããã®æ¹æ³ã§ææ¡ããå¿ èŠããããŸãã ãããã®ã©ããçæ³çã«èãããªãã®ã§ãPegasusã¯ã©ã®ããã«ãããè¡ããŸããïŒ
çè«çã«ã¯ãAãã¢ã¯ã·ã§ã³ãã¯ããŒãžã£ã«ãã¥ãŒã€ã³ã°ãããããŒãµãŒãå®å šã«å®äºããåŸã«ã®ã¿å®è¡ãããå Žåãããã³B.ããŒãµãŒãå®äºããåŸã«å®è¡ããããããã«ãŒã«ã®äžèŽããã£ã³ã»ã«ã§ããªãå ŽåãããŒãµãŒã¯ç¡å¹ã«å®è¡ãããã¢ã¯ã·ã§ã³ãåé¿ã§ããŸãã ããããããã®ã¹ããŒã ã¯ããã¬ãµã¹ã§è¡ãããç¶æ ã®ããã¯ãã©ãã¯ãããæé©ã§ããããïŒ
ãŸããç¡å¹ãªç¶æ ã®åé¡ãä¿®æ£ããããšã¯ç¢ºãã«éåžžã«è¯ãããšã§ãããstring [10ïŒabcdefghij]ã®ãããªæååãªãã©ã«ã«é¢é£ããŠç§ãæèµ·ããè¡šçŸå¯èœæ§ã®åé¡ã¯è§£æ±ºããŸãããããããã©ã®ããã«æ©èœãããã«ééããªãèå³ããããŸã
ããã°ã©ã å
šäœã®ç¶æ
ãããã®ãŒãããšã¯ãããŸããã ç¶æ
ã®äžå€ã®èŸæžãç¶æããŸãã çŸåšã®ç¶æ
ãã£ã¯ã·ã§ããªãã«ãŒãœã«ãšäžç·ã«ä¿åããã«ãŒãœã«ãããã¯ãã©ãã¯ããããã³ã«ãç¶æ
ãã£ã¯ã·ã§ããªãããã¯ãã©ãã¯ãããŸãã ãã£ã¯ã·ã§ããªã¯#STATE{}
ã¢ã¯ã·ã§ã³ä»¥å€ã®å Žæã§ã¯äžå€ã§ãããåç¶æ
ãå€åããçŽåã«ã³ããŒãããŸãã
ã«ãŒãœã«ãé²ãããã³ã«è¿œå ã®å€æ°ãèšå®ãããšãããã©ãŒãã³ã¹ããããã«äœäžããŸãããã¹ããŒããã«ã«ãŒã«ãã¡ã¢åããæ©èœããããã¯ããã«äžåããŸãã ãŸããç¶æ ãã£ã¯ã·ã§ããªã¯äžå€ã§ãããããå€æŽããããŸã§å ±æã§ãããããããã«ãã£ãŠå€§éã®ã¡ã¢ãªãå²ãåœãŠãããããšã¯ãããŸããã ããšãã°ãããŒãµãŒã«ç¶æ ããªãå Žåãå²ãåœãŠã¯1ã€ã ãã«ãªããŸãã1ã€ã®ïŒç©ºã®ïŒç¶æ ãã£ã¯ã·ã§ããªã§ãã
JavaScriptã«ã¯ïŒç§ã®ç¥ãéãïŒãªããžã§ã¯ããäžå€ã«ããæ©èœã¯ãããŸããããããã¯ã»ãšãã©å®å
šæ©èœã§ããã Peg.jsã¯ãå#STATE{}
ã³ãŒããããã¯ãåŠçããåã«ç¶æ
ãã£ã¯ã·ã§ããªãã³ããŒããã«ãŒãœã«ãããã¯ãã©ãã¯ããããã³ã«ãããããã¯ãã©ãã¯ããå¿
èŠããããŸãã
ããããŸãããåºæ¬çã«ããŠãŒã¶ãŒã¯å€æŽããç¶æ ãæå®ããå¿ èŠããããŸãã ããã¯ãããã ããããããã§ãããã©ã¡ãŒã¿ãŒåãšåãã¡ãªãããå®éã«ã«ããŒãããŠãããšã¯æããŸããã ããèªäœãä»ã®ããšã«åœ¹ç«ã€ãšæãããŸãã
å€æ°env
ã䜿çšããŠã¢ã¯ã»ã¹ã§ããç°å¢ãæäŸãããã©ãŒã¯ãäœæããŸããïŒ https ïŒ//github.com/tebbi/pegjs
ããã¯ãäžèšã§ææ¡ãã#STATE{}
ãªããžã§ã¯ããšåãã§ãã
ããã¯ãïŒããã±ãŒãžïŒã°ããŒãã«å€æ°ã䜿çšããç°¡åãªããã¯ã§ããã解æé¢æ°ãæ®ããããã³ã«åŸ©å
ãããŸãã env
ã®ã³ããŒã¯ãObject.createïŒïŒã䜿çšããŠå®è¡ãããŸãã
ããã䜿çšããŠãPythonã§ç©ºçœãå®çŸ©ããããããã¯ã解æããææ³ã®äŸã次ã«ç€ºããŸãã
{
env.indLevel = -1
}
block =
empty
ind:ws* &{
if (ind.length <= env.indLevel) return false;
env.indLevel = ind.length;
return true;
}
first:statement? rest:indStatement*
{
if (first) rest.unshift(first);
return rest;
}
indStatement =
"\n" empty ind:ws* &{ return env.indLevel === ind.length; }
stm:statement
{return stm; }
statement =
id:identifier ws* ":" ws* "\n"
bl:block { return [id, bl]; }
/ identifier
identifier = s:[a-z]* { return s.join(""); }
empty = (ws* "\n")*
ws = [ \t\r]
çµæã®ããŒãµãŒã®å ¥åäŸã次ã«ç€ºããŸãã
b:
c
d:
e
f
g
PEG.jsã¯ãã«ãŒã«ã«é¢ãããããªãçš®é¡ã®ãã©ã¡ãŒã¿ãŒããµããŒãããŠããªããšããå°è±¡ããããŸããããã¯é©ãã¹ãããšã§ãã ãã®æ©èœã¯ç§ã«ãšã£ãŠéåžžã«éèŠã§ãã
ç§ãå¿
èŠãšããŠããã®ã¯ãOPã®èŠæ±ãããåçŽã§ããOPã¯ãã©ã¡ãŒã¿ãŒã«å¿ããŠææ³èªäœãå€æŽãããã®ã§ãããå°ãªããšããã«ãŒã«ã«æŽæ°ãæž¡ãå¿
èŠããããŸãã åºæ¬çã«ã次ã®ãããªLLLPGã«ãŒã«ãå€æããããšæããŸãïŒ PrefixExpr
ã¯ã -x
ã®ãããªãã¬ãã£ãã¯ã¹åŒããŸãã¯èå¥åãªã©ã®åªå
é äœã®é«ãåŒã§ã...ïŒïŒ
@[LL(1)]
rule Expr(context::Precedence)::LNode @{
{prec::Precedence;}
e:PrefixExpr(context)
greedy
( // Infix operator
&{context.CanParse(prec=InfixPrecedenceOf(LT($LI)))}
t:(NormalOp|BQString|Dot|Assignment)
rhs:Expr(prec)
{ ... }
| // Method_calls(with arguments), indexers[with indexes], generic!arguments
&{context.CanParse(P.Primary)}
e=FinishPrimaryExpr(e)
| // Suffix operator
...
)*
{return e;}
};
// Helper rule that parses one of the syntactically special primary expressions
@[private] rule FinishPrimaryExpr(e::LNode)::LNode @{
( // call(function)
"(" list:ExprList(ref endMarker) ")"
{ ... }
| // ! operator (generic #of)
"!" ...
| // Indexer / square brackets
{var args = (new VList!LNode { e });}
"[" args=ExprList(args) "]"
{ ... }
)
{return e;}
};
ç§ã®èšèªã«ã¯25ã®åªå
é äœã¬ãã«ãããããããã®ã«ãŒã«ã䜿çšããŠãã»ãšãã©ãã¹ãŠãæããããã§1ã€ã®ã«ãŒã«ã§åŠçããŸããïŒ Precedence
ã¯ãåªå
é äœãè¡šã2ã€ã®æŽæ°ã®ã©ãããŒãšèããããšãã§ããŸãããªãã¬ãŒã¿ãŒïŒã ããã«ãç§ã®èšèªã«ã¯ç¡éã®æ°ã®æŒç®åïŒåºæ¬çã«ã¯å¥èªç¹ã®ä»»æã®ã·ãŒã±ã³ã¹ïŒããããæŒç®åã®åªå
é äœã¯è§£æåŸã«æ±ºå®ãããŸãã 25çš®é¡ã®æŒç®åããšã«åå¥ã®ã«ãŒã«ã䜿çšããŠãéåžžã®æ¹æ³ã§èšèªã解æããããšã¯_æè¡çã«_å¯èœã§ãããããã¯æãããæ¹æ³ã§ãã
ãŸããããã§ã¯ãå
éšã«ãŒã«FinishPrimaryExpr
ããå²ãã§ããã«ãŒã«ããæž¡ããããã©ã¡ãŒã¿ãŒãçµã¿èŸŒãã æ§æããªãŒãæ§ç¯ããŠããããšãããããŸãã
ããã§...ãã©ã¡ãŒã¿ãPEG.jsã«ãŒã«ã«æž¡ãæ¹æ³ã¯ãããŸããïŒ
+1ïŒ ç§ã®å Žåãæ§æã®ããŒãµãŒãçæãããã ãã§ããããã§ãããã€ãã®åºåãæåã¯ã°ããŒãã«ã«æ§æå¯èœã§ãã ãã®å Žåãè¿°èªãšçµã¿åãããä»»æã®åŒã«äžèŽããããšã§åºåãæåãªãã©ã«ã眮ãæããããšã§ãããå®çŸã§ããŸããããã¹ãŠãå€æ°ã«çœ®ãæããããšãã§ããã°ãã¯ããã«ãšã¬ã¬ã³ãã«ãªããŸãïŒããã«å¹ççã«ãªããŸãïŒã
+1ããããè¿ãå°æ¥ã«å®è£ ãããã®ãèŠããã£ã³ã¹ã¯ãããŸããïŒ
å¥ã®ãŠãŒã¹ã±ãŒã¹ã ããã¯ã javascript.pegjs
ã®äŸããã®ãã®ã§ãã
(...)
RelationalExpression
= head:ShiftExpression
tail:(__ RelationalOperator __ ShiftExpression)*
{ return buildBinaryExpression(head, tail); }
RelationalOperator
= "<="
/ ">="
/ $("<" !"<")
/ $(">" !">")
/ $InstanceofToken
/ $InToken
RelationalExpressionNoIn
= head:ShiftExpression
tail:(__ RelationalOperatorNoIn __ ShiftExpression)*
{ return buildBinaryExpression(head, tail); }
RelationalOperatorNoIn
= "<="
/ ">="
/ $("<" !"<")
/ $(">" !">")
/ $InstanceofToken
(...)
(...)
/ ForToken __
"(" __
init:(ExpressionNoIn __)? ";" __
test:(Expression __)? ";" __
update:(Expression __)?
")" __
body:Statement
(...)
(...)
ããããã¹ãŠã®...NoIn
ã«ãŒã«ïŒããã³ãããããããããããŸãïŒã¯ãåã«for in
ã¹ããŒãã¡ã³ãã®ããã«å¿
èŠã§ãã ããã«å¯Ÿããã¯ããã«åªããã¢ãããŒãã¯ã次ã®ãããªãã®ã§ã¯ãªãã§ããããã
(...)
RelationalExpression<allowIn>
= head:ShiftExpression
tail:(__ RelationalOperator<allowIn> __ ShiftExpression)*
{ return buildBinaryExpression(head, tail); }
RelationalOperator<allowIn>
= "<="
/ ">="
/ $("<" !"<")
/ $(">" !">")
/ $InstanceofToken
/ &{ return allowIn; } InToken
{return "in";}
(...)
(...)
/ ForToken __
"(" __
init:(Expression<false> __)? ";" __
test:(Expression<true> __)? ";" __
update:(Expression<true> __)?
")" __
body:Statement
(...)
(...)
ããã¯ãããšãã°ãJavaScriptã®ææ³ãæå®ããæ¹æ³ãšéåžžã«ãã䌌ãŠããŸããhttps ïŒ//tc39.github.io/ecma262/#prod -IterationStatementïŒ ~In
ã«æ³šæããŠãã ããïŒ
ç§ãçŸåšéçºããŠããèšèªã«ã¯ããã®æ£ç¢ºãªåé¡ããããŸããç¹å®ã®æç¹ã§ã®ã¿äžéšã®ã«ãŒã«ãç¡å¹/æå¹ã«ãããã®ã§ãã JavaScriptææ³ã®å Žåã®ããã«ã圱é¿ãåãããã¹ãŠã®ã«ãŒã«ãè€è£œããããšã¯éåžžã«æ§ããããšæããŸãã
ã«ãŒã«ãè€è£œããã«ãããéæããããã®ä»£æ¿æ¹æ³ã¯ãããŸããïŒ
+1ããããè¿ãå°æ¥ã«å®è£ ãããã®ãèŠããã£ã³ã¹ã¯ãããŸããïŒ
ãã®åé¡ã«ã¯ãã€ã«ã¹ããŒã³ãå²ãåœãŠãããŠããŸãïŒ1.0.0以éïŒã PEG.jsã®çŸåšã®ããŒãžã§ã³ã¯0.10.0ã§ãã æããã«ã1.0.0以éã®åé¡ã¯ã1.0.0ããªãªãŒã¹ããåŸã«åŠçãããŸããããã¯ãããŒããããã«åŸã£ãŠã0.11.0ããªãªãŒã¹ããåŸã®ããæç¹ã§çºçããŸãã
ããã¯ããªãã®è³ªåã«çããã¯ãã§ãã ããã»ã¹å šäœãå éããæåã®æ¹æ³ã¯ã 0.11.0ããã³1.0.0ã察象ãšããåé¡ãæ¯æŽããããšã§ãã
ã«ãŒã«ãè€è£œããã«ãããéæããããã®ä»£æ¿æ¹æ³ã¯ãããŸããïŒ
èããããæ¹æ³ã¯ãç¶æ ãæåã§è¿œè·¡ããŠãããã»ãã³ãã£ãã¯è¿°èªã䜿çšããããšã§ãã ãã ãããã®ã¢ãããŒãã«ã¯ããã¯ãã©ããã³ã°ã®åé¡ãããããããå§ãããŸããïŒã€ãŸããã«ãŒã«ã®è€è£œãšæåã®ç¶æ 远跡ã®ã©ã¡ãããéžæããå Žåã¯ãè€è£œãéžæããŸãïŒã
ããŒãµãŒã«æž¡ãããšãã§ããåŒæ°ã«ã¯ã次ã®2ã€ã®ã¿ã€ãããããŸãã
leftAssociative(element, separator)
ã escapedString(quote)
ã withPosition(parser)
ã¯ãã®è¯ãäŸã§ããåŒæ°ãããŒãµãŒã§ãããå€ã§ããããäœããã®æ¹æ³ã§ããŒã¯ããæ¹æ³ãããã¯ãã§ãã æ£ããã¢ãããŒããèŠã€ããããšãããšããã³ã³ããã¹ãã«ã°ããŒãã«å€æ°ã䜿çšããããšã«ãªããŸããããããã¯æããã«è¡ãæ¢ãŸãã§ãã 誰ããããã«ã€ããŠäœãèããæã£ãŠããŸããïŒ
ãã¯ãã¯ã©ãã§ããïŒ
äžããããïŒ
Add <Expression, Add>
= left:Expression _ '+' _ right:Add
{ return { type: 'add', left, right } }
/ Expression
ãã€ïŒ
= Add <MyExpression, MyAdd>
MyExpression
= [0-9]+
ããã§ïŒ
= left:MyExpression _ '+' _ right:MyAdd
{ return { type: 'add', left, right } }
/ MyExpression
MyExpression
= [0-9]+
ããã«ãããããã ã¢ããããã«ãŒã«ãæ§ç¯ã§ããŸãïŒsmirkïŒ
åæããŸããéçºè ããã®æ©èœãè¿œå ããããšããå§ãããŸã:)
ç§ãæžããŠããæŽæ°ãããJavaScriptææ³ã«ã¯ãã®æ©èœãæ¬åœã«å¿ èŠãªã®ã§ãããã¯ç§ã®ãŠã£ãã·ã¥ãªã¹ãã®äžäœã«ãããŸãã ãããè©ŠããŠã¿ãŠããããã©ã®ããã«æ©èœããããèŠãŠãããŸãã
@samvvéåžžã«ç°ãªãã«ãŒãããããã«ééããŸãããããŸã ã¹ã¬ããå
šäœãèªãã§ããŸããã
ãã ããããã§åç
§ããïŒ572ã§ã¯ããã©ã¡ãŒã¿ãŒåãããã«ãŒã«ãã·ãã¥ã¬ãŒãã§ããææ³ã瀺ããŠããŸãã
ã€ãŸããæ¬è³ªçã«ã¯ãé¢æ°ãäžéã®è§£æçµæãšããŠè¿ããŸãã
ãã®ãããªãã¯ãã¯æ±ºããŠç§ã®çºæã§ã¯ãªããããããããªãã®ç®çã«ã¯ããªãäžæ Œå¥œã ãšæããŸãã ããããããã¯ããªãã«ãšã£ãŠã®åé¿çãããããŸããã ç§ã¯ãv1.0以éããŸã§ãæå³ããŸã... :)
@meislãã£ãããããã³ããããããšãïŒ æéãããã°è©ŠããŠã¿ãŸãã
@samvvããããã...ç§ã¯ããªãéèŠãªäœããèŠèœãšããŠããã®ã§ã¯ãªãããšæããŸãïŒ
ç§ãææ¡ããã®ã¯åè
ã ãã«åœ¹ç«ã¡ãŸãããåŸè
ã¯OPã®å®éã®åé¡ã§ã...
ãã®ããã«æ®å¿µã
ãã ããåŸè
ã®å Žåã§ããããã«äžæ Œå¥œã§ã¯ãããŸãããåé¿çããããŸãã
ãããŠããäŸå決å®ãã®éšåã¯ãé¢æ°ãè¿ãããšãšã¯äœã®é¢ä¿ããããŸãã...
https://pegjs.org/onlineã§è©ŠããŠã¿ãããã®äŸãè¿œå ããŸã
åºæ¬çãªèãæ¹ã¯ãã°ããŒãã«ç¶æ
ã䜿çšããŠçŸåšã®ãã¿ãŒãããŒã¿ããèšæ¶ããããšã§ãã 確ãã«ãããã¯ããªãã®ããã¯ã§ãããç¹°ãè¿ãã§ãã
ãã ããããã«å¥ã®åºåãæåãè¿œå ãããšã |
ã¯ã str
ã«ãã1ã€è¿œå ããããšãæå³ããŸãã
/ (t:'|' {term = t}) c:conts t:.&{ return isT(t) } { return c }
ããã¯ã1ã€ã®æå|
ã ããä»ã®æåãšç°ãªããŸãã
{
var term;
function isT(ch) { return ch === term }
function isE(ch) { return ch === '\\' }
}
start = str*
str
= (t:'\"' {term = t}) c:conts t:.&{ return isT(t) } { return c }
/ (t:'\'' {term = t}) c:conts t:.&{ return isT(t) } { return c }
conts
= c:(
'\\' t:.&{ return isT(t) || isE(t) } { return t }
/ t:.!{ return isT(t) } { return t }
)*
{ return c.join('') }
...å ¥åã«ã€ããŠ
"abc"
-> ["abc"]
"a\"bc"
-> ["a\"bc"]
"a\\bc"
-> ["a\bc"]
"a\\b\"c"'a\\b\''
-> ["a\b\"c", "a\b'c"]
psïŒããã¯å®éã«ã¯æã§æžããããã®ã§ã¯ãããŸããã ãããããããããããªãã®ããã«çæããããšæ³åããŠãã ãã...ç§ã¯ååãšããŠãããã©ã®ããã«è¡ããããšæããŸãã
@ceymard -10幎åŸã ãšæããŸããããããïŒ36ãšã©ãéãã®ãæ°ã«ãªããŸã
ãããŒãèŠããã®ã«å°ãæéãããããŸããã 10幎 ïŒ
ãã®PRã§ã¯ãã«ãŒã«ã¯åŒæ°ãåãããã©ã¡ãŒã¿ãŒåã§ããŸãã ããã¯ãé¡äŒŒããŠãããç°ãªãèŠåãç¹°ãè¿ããªãããã«ããããã«ãææ³èªäœã«ãã£ãŠäœ¿çšãããããšãæå³ããŠããŸãã
ïŒ36ã§ã¯ãèŠåã¯ææ³èªäœã®å€ã§æå®ãããŠããŸãã ãããã£ãŠãææ³èªäœããã©ã¡ãŒã¿åãããŸãã
ç¯å²ã¯éããšæããŸãããææ³èªäœãã«ãŒã«ã§ãããåãåé¡ã§ãããšèšãããããããŸããã ïŒ36ã¯ããããAPIã®ããããªå€æŽãæå³ããŸããããã®PRã¯ããã§ã¯ãªãã®ã§ãããã§ã¯ãªããšæããŸãã
ãããã£ãŠãC ++ ishã®çšèªãéåžžã«èª€ã£ãæ¹æ³ã§æªçšããã«ã¯ãåè ã¯ãã³ãã¬ãŒãéçã§ãããåŸè ã¯ã³ã³ã¹ãã©ã¯ã¿ãŒåŒã³åºãã§ããïŒ
ã¯ãããã®ã¢ãããžãŒã¯ããçšåºŠæ©èœãããšæããŸãã
説æãæéãããã ãããããšãããããŸã
ãããã10幎åŸã«å¥ã®è³ªåããããŸãã è¯ã2020幎代ã
ããã¯ãããŒãµãŒå®çŸ©ã®åé·æ§ãåãé€ãã®ã«éåžžã«åœ¹ç«ã¡ãŸãã ç§ã¯æå³çã«éåžžã«ãªã©ãã¯ã¹ããã«ã¹ã¿ã ææ³ãæã£ãŠãããããã€ãã®ã«ãŒã«ã¯ãããã«ç°ãªãã³ã³ããã¹ãã§é©çšããå¿ èŠããããŸãã
æãåèã«ãªãã³ã¡ã³ã
説æãæéãããã ãããããšãããããŸã
ãããã10幎åŸã«å¥ã®è³ªåããããŸãã è¯ã2020幎代ã