ãã°ã©ã¹ã»ã¯ããã¯ãã©ãŒã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 f
Aãš
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ç« ïŒã®äžéšãšããŠåºçãããŸãããé»å圢åŒã®æ¬å
šäœã®ãã·ã¢èªèš³ã¯ãåºç瀟ãããŒã¿ãŒãã®ãŠã§ããµã€ãã§è³Œå
¥ã§ããŸãã