ãã°ã©ã¹ã»ã¯ããã¯ãã©ãŒã2007-02-21
ã¯ããã«
1973幎ãæåã®å¹Žæ¬¡ã·ã³ããžãŠã ã
ããã°ã©ãã³ã°èšèªã®ååã®ã·ã³ããžãŠã ãã§ã
ãŠã©ã³ãã©ããã¯ã
ãããããŠã³æŒç®åã®åªå
é äœ ããšããèšäºã玹ä»ããŸããã ãã®èšäºã§ã¯ãPrattããååž°éäžã®æåã®åŽé¢ãš
ããã€ãæŒç®åã®åªå
é äœã®æ¹æ³ãçµã¿åãããè§£ææ¹æ³ã«ã€ããŠèª¬æããŸããã ãã©ããã®æ¹æ³ã¯ãååž°éäžã«éåžžã«äŒŒãŠããŸãããå¿
èŠãªã³ãŒããå°ãªããã¯ããã«é«éã«åäœããŸãã ãã©ããã¯ãåœŒã®æ¹æ³ã¯åŠç¿ãå®è£
ã䜿çšãç°¡åã§ãéåžžã«å¹æçã§éåžžã«æè»ã§ãããšè¿°ã¹ãŸããã ãã®ãã€ãããºã ã«ãããæ¡åŒµå¯èœãªèšèªã«äœ¿çšã§ããŸãã
ããããã¡ãœãããæ¬åœã«å®ç§ãªå Žåãã³ã³ãã€ã©éçºè
ã¯ãŸã ãããç¡èŠããã®ã§ããããïŒ ãã©ããã¯ã圌ã®èšäºã§ãBNFææ³ãšãã®å€æ°ã®ä¿®æ£ãããã³é¢é£ããå®çãšãªãŒãããã³ãããæ©ãããããå æããçŸåšã§ã¯ä»ã®æ¹åã®æ§æè§£æçè«ã®éçºã劚ããããšã瀺åããŸããã
å¥ã®èª¬æããããŸãïŒãã®æ¹æ³ã¯ãåçãªé¢æ°åããã°ã©ãã³ã°èšèªã«æã广çã§ãããéçãªæç¶ãåèšèªã§äœ¿çšããã®ã¯ã¯ããã«å°é£ã§ãã ãã©ããã¯åœŒã®èšäºãLispã§äŸãšããŠèª¬æããããŒã¯ã³ã®ã¹ããªãŒã ã䜿çšããŠæ§ææšããµãããŠæ§ç¯ããŸãã ããããæ§æè§£æã®ææ³ã¯ãSpartanã«ããæ§æã®æŸæ£ã説ãLispããã°ã©ããŒã®ã³ãã¥ããã£ã§ã¯ç¹ã«éèŠã§ã¯ãããŸããã Lispã®äœæä»¥æ¥ããã®èšèªã«ALGOLã¹ã¿ã€ã«ã®è±å¯ãªæ§æãäžãã詊ã¿ãå€ããããŸããïŒ
CGOL Pratt ã
Lisp-2 ã
MLISP ã
Dylan ã
Interlispã®Clisp ã
ãªãªãžãã«ã®McCarthy MåŒãªã©ã ãããããããã¯ãã¹ãŠå€±æããŸããã Lispã³ãã¥ããã£ã«ãšã£ãŠãããã°ã©ã ãšããŒã¿ã®äžè²«æ§ã¯ã衚çŸåè±ããªæ§æãããéèŠã§ããã äžæ¹ã倧倿°ã®ããã°ã©ããŒã¯æ§æã倧奜ããªã®ã§ãLispèªäœã¯äººæ°ããããŸããã ãã©ããã¡ãœããã¯åçèšèªãå¿
èŠãšããŸãããåçèšèªã®ã³ãã¥ããã£ã¯æŽå²çã«ããã©ããã¡ãœããã«ãã£ãŠéåžžã«äŸ¿å©ã«å®è£
ãããæ§æã䜿çšããŠããŸããã
Javascript
JavaScriptã®ç»å Žã«ããç¶æ³ã¯å€ãããŸããã JavaScriptã¯åçã§æ©èœçãªèšèªã§ãããæ§æçã«ã¯æããã«Cãã¡ããªãŒã«å±ããŸãã ããã¯åçèšèªã§ããããã®ã³ãã¥ããã£ã¯æ§æã倧奜ãã§ãã
JavaScriptããªããžã§ã¯ãæåã§ãã ãã©ããã®èšäºã¯ããªããžã§ã¯ãæåã®ã¢ãããŒããæ³å®ããŠããŸããããããã«ã€ããŠã®è¡šçŸåè±ããªè¡šèšæ³ãæ¬ ããŠããŸããã JavaScriptã¯ãPrattã¡ãœãããå®è£
ããããã®çæ³çãªèšèªã§ãã JavaScriptããŒãµãŒãè¿
éãã€å¹ççã«äœæããæ¹æ³ã玹ä»ããŸãã
JavaScriptãå®å
šã«æ±ãã«ã¯1ã€ã®èšäºã§ã¯äžååã§ãããããããç§ãã¡ã¯ããããããããŸããããã®èšèªã§ã¯æªéã圌ã®è¶³ãæãããã§ãã ããããããã«ã¯çŽ æŽãããåŽé¢ããããéåžžã«æ€èšã«å€ããŸãã Simplified JavaScriptãåŠçã§ããããŒãµãŒãäœæããŸãã ãããŠããã®ããŒãµãŒãSimplified JavaScriptã§äœæããŸãã ç°¡çŽ åãããJavaScriptã¯ã以äžãå«ããã¹ãŠã®èšèªã§æé«ã®ãã®ã§ãã
- æåã®ã¯ã©ã¹ã®ãªããžã§ã¯ããšããŠæ©èœããŸãã ç°¡ç¥åãããJavaScriptã§ã¯ã颿°ã¯åå¥ã¹ã³ãŒããæã€ã©ã ãåŒã§ãã
- ãããã¿ã€ãç¶æ¿ãæã€åçãªããžã§ã¯ãã ã¯ã©ã¹ã¯ãããŸããã éåžžã®å²ãåœãŠã䜿çšããŠããªããžã§ã¯ãã«æ°ããã¡ã³ããŒã远å ã§ããŸãã ãªããžã§ã¯ãã¯å¥ã®ãªããžã§ã¯ãã®ã¡ã³ããŒãç¶æ¿ã§ããŸãã
- ãªããžã§ã¯ããšé
åã®ãªãã©ã«ã æ°ãããªããžã§ã¯ããšé
åãäœæããã«ã¯ããã®è¡šèšæ³ãéåžžã«äŸ¿å©ã§ãã JavaScriptãªãã©ã«ã¯ã JSON圢åŒã®ã€ã³ã¹ãã¬ãŒã·ã§ã³ãšããŠæ©èœããŸã ã
JavaScriptãããã¿ã€ããå©çšããŠãæåãç¶æ¿ããããŒã¯ã³ãªããžã§ã¯ããäœæããŸãã å®è£
ã«ã¯ã
Object.createã¡ãœããïŒæ¢åã®ãªããžã§ã¯ãã®ã¡ã³ããŒãç¶æ¿ããæ°ãããªããžã§ã¯ããäœæããïŒãšãå
¥åè¡ã«ããŒã¯ã³ãªããžã§ã¯ãã®é
åãäœæããåå¥è§£æ
Object.createãå¿
èŠã§ãã ãã®é
åãç§»åããŠãè§£æããªãŒãæ§ç¯ããŸãã
ãã£ã©ã¯ã¿ãŒããŒãã«
æŒç®åãèå¥åãªã©ã®åããŒã¯ã³ã¯ããã£ã©ã¯ã¿ãŒããç¶æ¿ãããŸãã å¯èœãªãã¹ãŠã®æåïŒèšèªããŒã¯ã³ã®ã¿ã€ããæ±ºå®ããïŒã
symbol_tableãªããžã§ã¯ãã«
symbol_tableãŸãã
var symbol_table = {};
original_symbolãªããžã§ã¯ãã¯ãä»ã®ãã¹ãŠã®æåã®ãããã¿ã€ãã§ãã 圌ã®ã¡ãœããã¯éåžžããªãŒããŒããŒããããŠããŸãã
nudã¡ãœãããš
ledã¡ãœããã®æå³ãããã³çµååã«ã€ããŠã¯ãåŸã®ãåªå
é äœãã»ã¯ã·ã§ã³ã§èª¬æããŸãã
var original_symbol = { nud: function () { this.error("Undefined."); }, led: function (left) { this.error("Missing operator."); } };
æåãäœæãã颿°ãå®çŸ©ããŸãã ã·ã³ãã«èå¥åïŒ
id ïŒãšãã€ã³ãã£ã³ã°åŒ·åºŠïŒãªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒ
bp ãããã©ã«ãã¯ãŒãïŒãåãå
¥ãããã®
idã·ã³ãã«ãªããžã§ã¯ããè¿ããŸãã ã·ã³ãã«ã
symbol_tableã«æ¢ã«ååšããå Žåã颿°ã¯ãããè¿ããŸãã ãã以å€ã®å Žåã
original_symbolããç¶æ¿ãããæ°ãããã£ã©ã¯ã¿ãŒãäœæãããã£ã©ã¯ã¿ãŒããŒãã«ã«ä¿åããŠæ»ããŸãã ã·ã³ãã«ãªããžã§ã¯ãã«ã¯ãæåã¯
id ãvalueãå·Šãã€ã³ãã£ã³ã°åŒ·åºŠïŒ
lbp ïŒãããã³
original_symbolããã®ãã¹ãŠãå«ãŸããŠ
original_symbolãŸãã
var symbol = function (id, bp) { var s = symbol_table[id]; bp = bp || 0; if (s) { if (bp >= s.lbp) { s.lbp = bp; } } else { s = Object.create(original_symbol); s.id = s.value = id; s.lbp = bp; symbol_table[id] = s; } return s; };
äžè¬çãªåºåãæåãšæ«å°Ÿã®æåã宣èšããŸãã
symbol(":"); symbol(";"); symbol(","); symbol(")"); symbol("]"); symbol("}"); symbol("else");
èšå·
(end)ã¯ãããŒã¯ã³ã¹ããªãŒã ã®çµäºã瀺ããŸãã ã·ã³ãã«
(name)ã¯ã倿°åãªã©ã®æ°ããååã®ãããã¿ã€ãã§ãã ãŠãŒã¶ãŒããŒã¯ã³ãšã®äžèŽã®å¯èœæ§ãé¿ããããã«ãèå¥åã«ãã©ã±ãããå«ããŸããã
symbol("(end)"); symbol("(name)");
ããŒã¯ã³
ãœãŒã¹ããã¹ãã¯ã
typeãã£ãŒã«ãïŒ
"name" ã
"string" ã
"number"ãŸãã¯
"operator" ïŒããã³
valueãã£ãŒã«ãïŒstringãŸãã¯numberïŒãå«ãããªããã£ãããŒã¯ã³ã®
tokensé
åã«æ¢ã«å€æãããŠãããšä»®å®ããŸãã
token倿°ã¯åžžã«çŸåšã®ããŒã¯ã³ãåç
§ããŸãã
var token;
advance颿°ã¯ã次ã®ããªããã£ãããŒã¯ã³ããæ°ããããŒã¯ã³ãªããžã§ã¯ããäœæããããŒã¯ã³tokenãå²ãåœãŠ
token ã ãªãã·ã§ã³ã®
idãã©ã¡ãŒã¿ãæž¡ãããå Žåã颿°ã¯ããŒã¯ã³ã«å¯Ÿå¿ããèå¥åãããããšã確èªããŸãã æ°ããããŒã¯ã³ãªããžã§ã¯ãã®ãããã¿ã€ãã¯ãçŸåšã®ã¹ã³ãŒãå
ã®ã·ã³ãã«
(name)ãŸãã¯ã·ã³ãã«ããŒãã«ã®ã·ã³ãã«ã§ãã æ°ããããŒã¯ã³ã®
arityãã£ãŒã«ãã¯ã
"name" ã
"literal" ããŸãã¯
"operator"ããããã«ãªããŸãã ãã®åŸãããã°ã©ã ã§ã®ããŒã¯ã³ã®åœ¹å²ã«ã€ããŠããã«åŠç¿ãããšããã®å€ã¯
"binary" ã
"unary"ãŸãã¯
"statement"倿Žã§ããŸãã
var advance = function (id) { var a, o, t, v; if (id && token.id !== id) { token.error("Expected '" + id + "'."); } if (token_nr >= tokens.length) { token = symbol_table["(end)"]; return; } t = tokens[token_nr]; token_nr += 1; v = t.value; a = t.type; if (a === "name") { o = scope.find(v); } else if (a === "operator") { o = symbol_table[v]; if (!o) { t.error("Unknown operator."); } } else if (a === "string" || a === "number") { a = "literal"; o = symbol_table["(literal)"]; } else { t.error("Unexpected token."); } token = Object.create(o); token.value = v; token.arity = a; return token; };
ç¯å²
ã»ãšãã©ã®èšèªã«ã¯ãæ°ããæåïŒå€æ°åãªã©ïŒãå®çŸ©ããããã®è¡šèšããããŸãã åçŽãªèšèªã§ã¯ãæ°ããåèªã«åºäŒããšããããèªåçã«èå¥ããŠã·ã³ãã«ããŒãã«ã«å
¥ããŸãã ããè€éãªèšèªã«ã¯ãããã°ã©ãã倿°ãžã®ã¢ã¯ã»ã¹ãšãã®æå¹æéãå¶åŸ¡ã§ããç¯å²ããããŸãã
ã¹ã³ãŒãã¯ã倿°ãå®çŸ©ãããŠäœ¿çšå¯èœãªããã°ã©ã ã®äžéšã§ãã ã¹ã³ãŒãã¯ãã¹ãã§ããŸãã ç¹å®ã®ã¹ã³ãŒãã§å®çŸ©ããã倿°ã¯ãå€éšããã¯èŠããŸããã
çŸåšã®ã¹ã³ãŒããå¥ã®
scope倿°ã«ä¿åããŸãã
var scope;
original_scopeãªããžã§ã¯ãã¯ãã¹ã³ãŒãã§ãããã¹ãŠã®ãªããžã§ã¯ãã®ãããã¿ã€ãã§ãã æ°ãã倿°ãå®çŸ©ã§ãã
defineã¡ãœãããå«ãŸããŠã
define ã
defineã¡ãœããã¯ãååããŒã¯ã³ã倿°ããŒã¯ã³ã«å€æããŸãã 倿°ãã¹ã³ãŒãå
ã§æ¢ã«å®çŸ©ãããŠããå ŽåããŸãã¯ååãäºçŽèªã§ããå Žåããšã©ãŒãã¹ããŒãããŸãã
var itself = function () { return this; }; var original_scope = { define: function (n) { var t = this.def[n.value]; if (typeof t === "object") { n.error(t.reserved ? "Already reserved." : "Already defined."); } this.def[n.value] = n; n.reserved = false; n.nud = itself; n.led = null; n.std = null; n.lbp = 0; n.scope = scope; return n; },
findã¡ãœããã¯ãååã§å®çŸ©ãæ€çŽ¢ããããã«äœ¿çšãããŸãã çŸåšã®ã¹ã³ãŒãããæ€çŽ¢ãéå§ããå¿
èŠã«å¿ããŠãã§ãŒã³ãããã®ãŒããæåã®ããŒãã«ã§çµäºããŸãã å®çŸ©ãèŠã€ãããªãã£ãå Žåã
symbol_table["(name)"]è¿ããŸãã ã¡ãœããã¯ãæå®ãããååã®å€ã
undefinedãšçãã
undefined ïŒã€ãŸããæªå®£èšã®ååã«ã¢ã¯ã»ã¹ããããšãæå³ããŸãïŒããã³é¢æ°ã§ã¯ãªãããšïŒç¶æ¿ãããã¡ãœãããšã®è¡çªã瀺ãããšïŒããã§ãã¯ããŸãã
find: function (n) { var e = this, o; while (true) { o = e.def[n]; if (o && typeof o !== 'function') { return e.def[n]; } e = e.parent; if (!e) { o = symbol_table[n]; return o && typeof o !== 'function' ? o : symbol_table["(name)"]; } } },
popã¡ãœããã¯ã¹ã³ãŒããéãã芪ã«çœ®ãæããŸãã
pop: function () { scope = this.parent; },
reserveã¡ãœããã¯ãç¹å®ã®ååãçŸåšã®ã¹ã³ãŒãå
ã®äºçŽèªã§ããããšã瀺ãããã«äœ¿çšãããŸãã
reserve: function (n) { if (n.arity !== "name" || n.reserved) { return; } var t = this.def[n.value]; if (t) { if (t.reserved) { return; } if (t.arity === "name") { n.error("Already defined."); } } this.def[n.value] = n; n.reserved = true; } };
次ã«ãäºçŽèªãåŠçããããã®æŠç¥ãå¿
èŠã§ãã äžéšã®èšèªã§ã¯ãããã°ã©ã ã®æ§é ãèšè¿°ããåèªïŒ
if ïŒã¯äºçŽãããŠããã倿°åãšããŠäœ¿çšã§ããŸããã ããŒãµãŒã®æè»æ§ã«ãããããã«å€ããéæã§ããŸãã ããšãã°ãã©ã®é¢æ°ã§ããååŸããååã¯èšèªæŒç®åãŸãã¯å€æ°åãšããŠäœ¿çšã§ããŸãã äºçŽèªãšããŠäœ¿çšãããåŸã«ã®ã¿ãåèªãããŒã«ã«ã§äºçŽããŸãã æ°ããããŒã¯ãŒãã远å ããŠãæ¢åã®ããã°ã©ã ãäžæãããããšã¯ãªããããèšèªã®äœæè
ã®ç掻ãç°¡çŽ åãããååã®äœ¿çšã«é¢ããäžå¿
èŠãªå¶éã«éªéãããªããããããã°ã©ããŒã®ç掻ãåçŽåãããŸãã
颿°ãŸãã¯ãããã¯ã®æ°ããã¹ã³ãŒããäœæããå Žåã
new_scope颿°ãåŒã³åºããŸããããã«ããã
original_scopeãããã¿ã€ãã®æ°ããã€ã³ã¹ã¿ã³ã¹ãäœæãããŸãã
var new_scope = function () { var s = scope; scope = Object.create(original_scope); scope.def = {}; scope.parent = s; return scope; };
åªå
é äœ
ããŒã¯ã³ãªããžã§ã¯ãã«ã¯ãåªå
é äœã«é¢ããæ±ºå®ãä»ã®ããŒã¯ã³ã®éžæãããªãŒã®æ§ç¯ãå¯èœã«ããã¡ãœãããå«ãŸããŠããŸãïŒããã«è€éãªãããžã§ã¯ãã§ã¯ãã¿ã€ãã®ãã§ãã¯ãã³ãŒãã®æé©åãšçæãå¯èœïŒã åªå
é äœã®äž»ãªã¿ã¹ã¯ã¯æ¬¡ã®ãšããã§ãã2ã€ã®æŒç®åã®éã®æå®ããããªãã©ã³ãã«ã€ããŠããªãã©ã³ããå·ŠæŒç®åãåç
§ããã峿Œç®åãåç
§ããããæ±ºå®ããŸãã
d A e B fAãš
BãæŒç®åã§ããå Žåãã©ã®ãªãã©ã³ã
eããããã«å±ããŸããïŒ ã€ãŸãã
(d A e) B féžæããå¿
èŠããããŸã
ããã³
d A (e B f) ã
æçµçã«ãè§£æã®äž»ãªåé¡ã¯ããã®ãããŸããã解決ããããšã§ãã ãã®ã¡ãœããã®ããŒã¯ã³ãªããžã§ã¯ãã«ã¯ããã€ã³ãã£ã³ã°åŒ·åºŠïŒãŸãã¯åªå
床ã¬ãã«ïŒãšãåçŽãªã¡ãœãã
nud ïŒnull衚èšãnullãããïŒããã³
led ïŒå·Šè¡šèšãå·ŠãããïŒãæ ŒçŽãããŸãã
nudã¯ãã©ã®ããŒã¯ã³ãå·ŠåŽã«ãããã¯é¢ä¿ãããŸãããã
ledã¡ãœããã¯éèŠã§ãã
nudã¡ãœãã
nud ãå€ïŒå€æ°ãšãªãã©ã«ïŒããã³ãã¬ãã£ãã¯ã¹æŒç®åã«ãã£ãŠäœ¿çšãããŸãã
ledã¡ãœããã¯ãäžçœ®æŒç®åãšåŸçœ®æŒç®åã«ãã£ãŠäœ¿çšãããŸãã ããŒã¯ã³ã«ã¯ã
nudã¡ãœãããš
ledã¡ãœããã®äž¡æ¹ã
nudãŸãã ããšãã°ããã€ãã¹ïŒ
- ïŒã¯ãã¬ãã£ãã¯ã¹ïŒæ°åã®ç¬Šå·ã倿ŽïŒãŸãã¯ã€ã³ãã£ãã¯ã¹ïŒæžç®ïŒã®ããããã§ãããããäž¡æ¹ã®ã¡ãœãããå®çŸ©ãããŠããŸãã
ããŒãµãŒã¯ã次ã®ãã€ã³ãåã䜿çšããŸãã
| 0 | ã³ãã¥ãã±ãŒã·ã§ã³ã®ãªããªãã¬ãŒã¿ãŒ; ãªã© |
| 10 | 代å
¥æŒç®åïŒ =ãªã©ã |
| 20 | ?: |
| 30 | || && |
| 40 | æ¯èŒæŒç®åïŒ ===ãªã© |
| 50 | + - |
| 60 | * / |
| 70 | åé
æŒç®åïŒïŒ ãªã© |
| 80 | . [ ( |
衚çŸ
Prattã¡ãœããã®äž»èŠãªã³ã³ããŒãã³ãã¯
expression颿°ã§ãã å
¥åãšããŠæ£ããçµååãåãå
¥ããŸããããã¯ãåŒãã©ã®çšåºŠã¢ã¯ãã£ãã«æ£ããããŒã¯ã³ã«çµåãããã瀺ããŸãã
var expression = function (rbp) { var left; var t = token; advance(); left = t.nud(); while (rbp < token.lbp) { t = token; advance(); left = t.led(left); } return left; }
expression颿°ã¯ããªãã©ã«ã倿°ããã¬ãã£ãã¯ã¹æŒç®åãåŠçããçŸåšã®ããŒã¯ã³
tokenã®
nudã¡ãœãããåŒã³åºããŸãã æ¬¡ã«ãå³ã®ãã€ã³ãã£ã³ã°åŒ·åºŠã次ã®ããŒã¯ã³ã®å·Šã®ãã€ã³ãã£ã³ã°åŒ·åºŠããå°ãããªããŸã§ã
ledã¡ãœãããåŒã³åºãããŸãã ãã®ã¡ãœããã¯ãäžçœ®æŒç®åãšåŸçœ®æŒç®åãåŠçããŸãã
nudã¡ãœãããš
ledã¡ãœããèªäœã
expressionãåŒã³åºãããšãã§ãããããããã»ã¹ã¯ååž°çã«ãªããŸãã
äžçœ®æŒç®å
+æŒç®åã¯äžçœ®æŒç®åã§ãããããããŒã¯ã³ãªããžã§ã¯ããã
+èšå·ã®å·Šå³ã®ãªãã©ã³ãã§ãã2ã€ã®ãã©ã³ãïŒ
firstãš
second ïŒãæã€ããªãŒã«å€æãã
ledã¡ãœããããããŸãã
ledã¡ãœããã¯å·ŠåŽã®ãªãã©ã³ãããã©ã¡ãŒã¿ãŒãšããŠåãåããå³åŽã®ãªãã©ã³ãã¯
expressionãåŒã³åºãããšã§æ€åºãã
expression ã
symbol("+", 50).led = function (left) { this.first = left; this.second = expression(50); this.arity = "binary"; return this; };
*èšå·ã¯ã
idå€ãšãã€ã³ãã£ã³ã°åŒ·åºŠãé€ããŠ
+ãšåãã§ãã ãªãã©ã³ããšãã匷ãçµã³ä»ããããŠããããããã€ã³ãã£ã³ã°ã®åŒ·åºŠãé«ããªããŸãã
symbol("*", 60).led = function (left) { this.first = left; this.second = expression(60); this.arity = "binary"; return this; };
ãã¹ãŠã®äžçœ®æŒç®åãåãããã«èŠããããã§ã¯ãããŸããããå€ãã¯ããã§ãã ãããã£ãŠãäžçœ®æŒç®åã®äœæã«åœ¹ç«ã€
infix颿°ãå®çŸ©ããããšã«ãããäœæ¥ãç°¡çŽ åã§ããŸãã
infix颿°ã¯ã
id ããã€ã³ãã£ã³ã°ãã¯ãŒãããã³ãªãã·ã§ã³ã§
led颿°ãåãå
¥ããŸãã 颿°ãæå®ãããŠããªãå Žåã
infixã¯ããã©ã«ãã®
led颿°ãäœæããŸããããã¯ã»ãšãã©ã®å Žåã«æ©èœããŸãã
var infix = function (id, bp, led) { var s = symbol(id, bp); s.led = led || function (left) { this.first = left; this.second = expression(bp); this.arity = "binary"; return this; }; return s; }
ããã§ãäžçœ®æŒç®åããã宣èšçãªã¹ã¿ã€ã«ã§èšè¿°ã§ããŸãã
infix("+", 50); infix("-", 50); infix("*", 60); infix("/", 60);
===ã¯JavaScriptã®æ£ç¢ºãªæ¯èŒæŒç®åã§ãã
infix("===", 40); infix("!==", 40); infix("<", 40); infix("<=", 40); infix(">", 40); infix(">=", 40);
äžé
æŒç®åã¯ã
?åºåããã3ã€ã®åŒãåãå
¥ã
? ããã³
: ããã¯éåžžã®æ¿å
¥æŒç®åã§ã¯ãªããããããã§
led颿°ãèšå®ããå¿
èŠããããŸãã
infix("?", 20, function (left) { this.first = left; this.second = expression(0); advance(":"); this.third = expression(0); this.arity = "ternary"; return this; });
ãããæŒç®åïŒ
. ïŒã¯ããªããžã§ã¯ãã®ã¡ã³ããŒãåç
§ããããã«äœ¿çšãããŸãã ãã®å³åŽã«ååããªããã°ãªããŸãããããªãã©ã«ãšããŠäœ¿çšãããŸãã
infix(".", 80, function (left) { this.first = left; if (token.arity !== "name") { token.error("Expected a property name."); } token.arity = "literal"; this.second = token; this.arity = "binary"; advance(); return this; });
[æŒç®åã¯ããªããžã§ã¯ãã®ã¡ã³ããŒãŸãã¯é
åã®èŠçŽ ãåçã«åç
§ããããã«äœ¿çšãããŸãã å³åŽã®åŒã®åŸã«ã¯å³å€§æ¬åŒ§ãç¶ãã¹ãã§ãã
infix("[", 80, function (left) { this.first = left; this.second = expression(0); this.arity = "binary"; advance("]"); return this; });
ãããã®æ¿å
¥æŒç®åã¯ãã¹ãŠå·Šçµåã§ãã ãŸããå³çµåæŒç®åïŒè«ç||ã&&ãªã©ïŒãäœæããŠãé©åãªçµååãæžããããšãã§ããŸãã
var infixr = function (id, bp, led) { var s = symbol(id, bp); s.led = led || function (left) { this.first = left; this.second = expression(bp - 1); this.arity = "binary"; return this; }; return s; }
&&æŒç®åã¯ãfalseã®å Žåã¯æåã®ãªãã©ã³ããè¿ããããã§ãªãå Žåã¯2çªç®ã®ãªãã©ã³ããè¿ããŸãã æŒç®å
|| trueã®å Žåãæåã®ãªãã©ã³ããè¿ããŸãã falseå€ã¯
0ã§ãç©ºã®æååã¯
"" ã
falseãŸãã¯
nullã§ãã ä»ã®å€ïŒãªããžã§ã¯ããå«ãïŒã¯ãã¹ãŠtrueãšèŠãªãããŸãã
infixr("&&", 30); infixr("||", 30);
ãã¬ãã£ãã¯ã¹æŒç®å
飿³ã€ã³ãã©ã°ã©ãã£ãã¯æŒç®åã«äœ¿çšããã³ãŒãã¯ããã¬ãã£ãã¯ã¹æŒç®åã«é©åãããããšãã§ããŸãã ãã¬ãã£ãã¯ã¹æŒç®åã¯çµåçã§ãã ãã¬ãã£ãã¯ã¹ã¯å·ŠåŽã®äœã«ããã€ã³ãããªããããå·ŠåŽã®ãã€ã³ãåã¯ãããŸããã ãã¬ãã£ãã¯ã¹æŒç®åã¯äºçŽèªã§ããå ŽåããããŸãã
var prefix = function (id, nud) { var s = symbol(id); s.nud = nud || function () { scope.reserve(this); this.first = expression(70); this.arity = "unary"; return this; }; return s; } prefix("-"); prefix("!"); prefix("typeof");
ãã©ã±ããã®
nudã¡ãœãã
( advance(")")åŒã³åºããŸã
advance(")")ã¯ããã¢ãã©ã±ãããèŠã€ããŸãã ããŒã¯ã³èªäœã¯ã
nudãæ¬åŒ§ã®å
容ã®ã¿ãè¿ããããæ§æããªãŒã«åé¡ãããŸããã
prefix("(", function () { var e = expression(0); advance(")"); return e; });
å²ãåœãŠæŒç®å
infixr颿°ã䜿çšããŠã
infixrã
infixrã§ããŸãã ãã ããå¥ã®æäœãè¡ããããå¥ã®
assignment颿°ãäœæããããšããå§ãããŸããå·ŠåŽã®åŒã巊蟺å€ã§ããããšã確èªããŠãã ããã ã
var assignment = function (id) { return infixr(id, 10, function (left) { if (left.id !== "." && left.id !== "[" && left.arity !== "name") { left.error("Bad lvalue."); } this.first = left; this.second = expression(9); this.assignment = true; this.arity = "binary"; return this; }); }; assignment("="); assignment("+="); assignment("-=");
泚ïŒç¶æ¿ã®ãããªãã®ãå®è£
ããŸããã
assignment颿°ã¯
infixrãåŒã³åºã
infixrçµæã
infixr symbolãåŒã³åºã
infixrçµæã
infixr ã
宿°
constant颿°ã¯ãèšèªå®æ°ãäœæããŸãã
nudã¡ãœããã¯ãååããŒã¯ã³ããªãã©ã«ããŒã¯ã³ã«å€æããŸãã
var constant = function (s, v) { var x = symbol(s); x.nud = function () { scope.reserve(this); this.value = symbol_table[this.id].value; this.arity = "literal"; return this; }; x.value = v; return x; }; constant("true", true); constant("false", false); constant("null", null); constant("pi", 3.141592653589793);
ã·ã³ãã«
(literal)ã¯ããã¹ãŠã®æååãªãã©ã«ãšæ°å€ãªãã©ã«ã®ãããã¿ã€ãã§ãã
nudããŒã¯ã³ã®
nudã¡ãœããã¯ãããŒã¯ã³èªäœãè¿ããŸãã
symbol("(literal)").nud = itself;
ç³ãåº
ãªãªãžãã«ã§ã¯ãåŒã®ã¿ãååšãã颿°åèšèªçšã«Prattã¡ãœãããäœæãããŸããã ã»ãšãã©ã®äžè¬çãªèšèªã¯ãåŒãšããŠåã蟌ãã®ãããã»ã©é£ãããªãã¹ããŒãã¡ã³ãã䜿çšããŸãã ããŒã¯ã³ã«æ°ããã¡ãœããã远å ãããšãæãç°¡åã«åŠçã§ããŸãïŒ
std ïŒæã®è¡šç€ºãæã®äžèŽïŒã
stdã¡ãœããã¯
nudã«äŒŒãŠããŸãããæã®å
é ã§ã®ã¿åŒã³åºãããŸãã
statement颿°ã¯1ã€ã®æãè§£æããŸãã çŸåšã®ããŒã¯ã³ã«
stdã¡ãœãããå«ãŸããŠããå ŽåãããŒã¯ã³ã¯äºçŽããããã®ã¡ãœãããåŒã³åºãããŸãã ãã以å€ã®å Žåãæã¯ã»ãã³ãã³ã§çµããåŒã§ãããšèŠãªããŸãã ä¿¡é Œæ§ã®ããã«ãå²ãåœãŠã§ã颿°åŒã³åºãã§ããªãåŒããšã©ãŒãšèŠãªããŸãã
var statement = function () { var n = token, v; if (n.std) { advance(); scope.reserve(n); return n.std(); } v = expression(0); if (!v.assignment && v.id !== "(") { v.error("Bad expression statement."); } advance(";"); return v; };
statements颿°ã¯ããããã¯ã®çµäºã瀺ãããŒã¯ã³
(end)ãŸãã¯
}ãæ€åºãããŸã§
statementsè§£æããŸãã ãã®é¢æ°ã¯ãæãæã®é
åããŸãã¯æãèŠã€ãããªãå Žåã¯
nullè¿ããŸãã
var statements = function () { var a = [], s; while (true) { if (token.id === "}" || token.id === "(end)") { break; } s = statement(); if (s) { a.push(s); } } return a.length === 0 ? null : a.length === 1 ? a[0] : a; };
stmt颿°ã¯ãæåããŒãã«ã«æã®æåã远å ããããã«äœ¿çšãããŸãã
idãš
std颿°ããã©ã¡ãŒã¿ãŒãšããŠåãåããŸãã
var stmt = function (s, f) { var x = symbol(s); x.std = f; return x; };
ãããã¯ææ¡ã¯ãæ°ããã¹ã³ãŒããå®çŸ©ãããŠããäžæ¬åŒ§å
ã®æã®ãªã¹ãã§ãã éåžžã®JavaScriptã«ã¯ãããã¯ã®ã¹ã³ãŒãã¯ãããŸããããSimplified JavaScriptã«ã¯å«ãŸããŸãã
stmt("{", function () { new_scope(); var a = statements(); advance("}"); scope.pop(); return a; });
block颿°ã¯
blockè§£æããŸãã
var block = function () { var t = token; advance("{"); return t.std(); };
varå¥ã¯ãçŸåšã®ãããã¯ã®1ã€ä»¥äžã®å€æ°ãå®çŸ©ããŸãã 倿°åã®åŸã«çå·
=ãšå€æ°ã®åæå€ãç¶ããããšãã§ããŸãã
stmt("var", function () { var a = [], n, t; while (true) { n = token; if (n.arity !== "name") { n.error("Expected a new variable name."); } scope.define(n); advance(); if (token.id === "=") { t = token; advance("="); t.first = n; t.second = expression(0); t.arity = "binary"; a.push(t); } if (token.id !== ",") { break; } advance(","); } advance(";"); return a.length === 0 ? null : a.length === 1 ? a[0] : a; });
whileå¥ã¯ã«ãŒããå®çŸ©ããŸãã æ¬åŒ§å
ã®åŒãšãããã¯ãå«ãŸããŸãã
stmt("while", function () { advance("("); this.first = expression(0); advance(")"); this.second = block(); this.arity = "statement"; return this; });
ifç¯ã¯æ¡ä»¶ä»ãæ§æãäœæããŸãã
elseã·ã³ãã«ããããã¯ã®åŸã«ç¶ã
if ãæ¬¡ã®ãããã¯ãŸãã¯æ¬¡ã®
ifå¥ãåæããŸãã
stmt("if", function () { advance("("); this.first = expression(0); advance(")"); this.second = block(); if (token.id === "else") { scope.reserve(token); advance("else"); this.third = token.id === "if" ? statement() : block(); } else { this.third = null; } this.arity = "statement"; return this; });
breakå¥ã¯ãã«ãŒããäºåã«çµäºããããã«äœ¿çšãããŸãã
stmt("break", function () { advance(";"); if (token.id !== "}") { token.error("Unreachable statement."); } this.arity = "statement"; return this; });
returnç¯ã¯ã颿°ãçµäºããããã«äœ¿çšãããŸãã ãªãã·ã§ã³ã®åŒïŒé¢æ°ã®æ»ãå€ïŒãå«ããããšãã§ããŸãã
stmt("return", function () { if (token.id !== ";") { this.first = expression(0); } advance(";"); if (token.id !== "}") { token.error("Unreachable statement."); } this.arity = "statement"; return this; });
æ©èœ
颿°ã¯å®è¡å¯èœãªå€ã§ãã 颿°ã¯ããªãã·ã§ã³ã®ååïŒããèªäœãååž°çã«åŒã³åºãããšãã§ããããã«ïŒãæ¬åŒ§å
ã®ãã©ã¡ãŒã¿ãŒåã®ãªã¹ããããã³æ¬äœïŒäžæ¬åŒ§å
ã®æã®ãªã¹ãïŒãæã€ããšãã§ããŸãã 颿°ã«ã¯ç¬èªã®ã¹ã³ãŒãããããŸãã
prefix("function", function () { var a = []; new_scope(); if (token.arity === "name") { scope.define(token); this.name = token.value; advance(); } advance("("); if (token.id !== ")") { while (true) { if (token.arity !== "name") { token.error("Expected a parameter name."); } scope.define(token); a.push(token); advance(); if (token.id !== ",") { break; } advance(","); } } this.first = a; advance(")"); advance("{"); this.second = statements(); advance("}"); this.arity = "function"; scope.pop(); return this; });
颿°ã¯æŒç®å
( ãã䜿çšããŠå®è¡ãããŸããåŒã³åºããšããåŒæ°ã®æ°ãæå®ã§ããŸããå·ŠåŽã®ãªãã©ã³ãããã§ãã¯ããŠãå·ŠåŽã®å€ã颿°ã«ãªããªãç¶æ³ãã«ããããŸãã
infix("(", 80, function (left) { var a = []; if (left.id === "." || left.id === "[") { this.arity = "ternary"; this.first = left.first; this.second = left.second; this.third = a; } else { this.arity = "binary"; this.first = left; this.second = a; if ((left.arity !== "unary" || left.id !== "function") && left.arity !== "name" && left.id !== "(" && left.id !== "&&" && left.id !== "||" && left.id !== "?") { left.error("Expected a variable name."); } } if (token.id !== ")") { while (true) { a.push(expression(0)); if (token.id !== ",") { break; } advance(","); } } advance(")"); return this; });
thisæåã¯ç¹å¥ãªå€æ°ã§ãã ã¡ãœãããåŒã³åºããããšããªããžã§ã¯ãåç
§ããã®äžã«ä¿åãããŸãã
symbol("this").nud = function () { scope.reserve(this); this.arity = "this"; return this; };
ãªããžã§ã¯ããšé
åã®ãªãã©ã«
é
åãªãã©ã«ã¯ãã³ã³ãã§åºåãããè§æ¬åŒ§å
ã®åŒã®ã»ããã§ãã ååŒãè©äŸ¡ããããã¹ãŠã®çµæãæ°ããé
åã圢æããŸãã
prefix("[", function () { var a = []; if (token.id !== "]") { while (true) { a.push(expression(0)); if (token.id !== ",") { break; } advance(","); } } advance("]"); this.first = a; this.arity = "unary"; return this; });
ãªããžã§ã¯ãã®ãªãã©ã«ã¯ãã«ã³ãã§åºåãããäžæ¬åŒ§å
ã®ãã¢ã®ã»ããã§ãã ãã®ãã¢ã¯ãã³ãã³ïŒ
:åºåãããããŒãšåŒã§æ§æãããŸãã ããŒã¯ããªãã©ã«ãšããŠè§£éããããªãã©ã«ãŸãã¯ååã§ãã
prefix("{", function () { var a = []; if (token.id !== "}") { while (true) { var n = token; if (n.arity !== "name" && n.arity !== "literal") { token.error("Bad key."); } advance(); advance(":"); var v = expression(0); v.key = n.value; a.push(v); if (token.id !== ",") { break; } advance(","); } } advance("}"); this.first = a; this.arity = "unary"; return this; });
äœãèããäœããã¹ãã
äœæãããããªãŒã¯ãã³ãŒããžã§ãã¬ãŒã¿ãŒãŸãã¯ã€ã³ã¿ãŒããªã¿ãŒã«æž¡ãããšãã§ããŸãã ããªãŒãäœæããã«ã¯ãæå°éã®èšç®ãå¿
èŠã§ãã ãããŠãç§ãã¡ãèŠãããã«ããã®ãããªããŒãµãŒãæžãããã«ããã°ã©ããŒããããã»ã©å€ãã®åªåãå¿
èŠãšããŸããã
æäœã³ãŒããã©ã¡ãŒã¿ãŒã
infix颿°ã«è¿œå ããŠãã³ãŒããžã§ãã¬ãŒã¿ãŒãæ¯æŽã§ããŸãã
ãŸãã宿°ãæãããã¿ãã³ãŒããçæããããã®è¿œå ã®ã¡ãœãããæž¡ãããšãã§ããŸããç§ãã¡ã¯ãïŒäŸãã°ãä»ã®ææ¡ã远å ããããšãã§ãforãswitchãã€tryãã©ãã«ããšã©ãŒããã§ãã¯ããããã«å€ãã®ã³ãŒãããšã©ãŒå埩ãããã³æ°ããæŒç®åã®æãïŒãã¿ã¹ã¯ãšåã®æšè«ã远å ã§ããŸããèšèªãæ¡åŒµå¯èœã«ããããšãã§ããŸããããã°ã©ããŒã«ãæ°ãã倿°ã宣èšããã®ãšåããããç°¡åã«ãæ°ããã¹ããŒãã¡ã³ããšã¹ããŒãã¡ã³ãã宣èšãããããšãã§ããŸãããã®èšäºã§èª¬æãããŠããããŒãµãŒãèªåã§è©ŠããŠãã ããã JSLintãããžã§ã¯ãã§ãã®è§£æã¡ãœããã䜿çšããå¥ã®äŸãèŠã€ããããšãã§ããŸãã翻蚳è
ããïŒç§ã¯JSLintã®ãœãŒã¹ãéžæãããã®çŽ æŽãããèšäºã®ãã·ã¢èªã®ç¿»èš³ã害ã«ãªããªãããšã決ããŸãããJSLintããŒãµãŒã¯ãéåžžã«æç¢ºã§åŒ·åã§ãç°¡åã«æ¡åŒµã§ããŸãã翻蚳ãç·šéããŠãããKVieã«æè¬ããŸãããã®èšäºã¯ãBeautiful CodeïŒç¬¬9ç« ïŒã®äžéšãšããŠåºçãããŸãããé»å圢åŒã®æ¬å
šäœã®ãã·ã¢èªèš³ã¯ãåºç瀟ãããŒã¿ãŒãã®ãŠã§ããµã€ãã§è³Œå
¥ã§ããŸãã