![](https://habrastorage.org/webt/cz/z2/rd/czz2rdgu2rihmxmrnqielvrkmai.png)
ä»å¹Žã®åãã«ãMongoDBã®GUIã§ããMongoDB Compassã«åãçµãã§ããããŒã ã«åå ããŸããã Intercomãä»ããCompassãŠãŒã¶ãŒã¯ãMongoDBãã©ã€ããŒã§ãµããŒããããŠããããŠãŒã¶ãŒã«ãšã£ãŠäŸ¿å©ãªããã°ã©ãã³ã°èšèªã䜿çšããŠããŒã¿ããŒã¹ã¯ãšãªãäœæã§ããããŒã«ãèŠæ±ããŠããŸãã ã€ãŸããMongo Shellèšèªãä»ã®èšèªã«ããŸãã¯ãã®éã«å€æïŒã³ã³ãã€ã«ïŒããæ©èœãå¿ èŠã§ããã
ãã®èšäºã¯ãJavaScriptã§ã³ã³ãã€ã©ãŒãäœæããéã«åœ¹ç«ã€å®çšçãªã¬ã€ãã§ãããã³ã³ãã€ã©ãŒãäœæããããã®åºæ¬çãªæŠå¿µãšååãå«ãçè«çãªãªãœãŒã¹ã§ããããŸãã æåŸã«ãå·çã«äœ¿çšããããã¹ãŠã®è³æã®å®å šãªãªã¹ãã ãã§ãªããåé¡ã®ããæ·±ãç 究ãç®çãšããè¿œå ã®æç®ãžã®ãªã³ã¯ããããŸãã èšäºã®æ å ±ã¯ããµããžã§ã¯ãé åã®èª¿æ»ããå§ãŸãããã®åŸãäŸãšããŠéçºãããŠããã¢ããªã±ãŒã·ã§ã³ã®æ©èœãåŸã ã«è€éã«ããŠãããŸãã èªã¿ãªãããããã¹ãããããå¥ã®ã¹ããããžã®ç§»è¡ãææ¡ããŠããªãããã«æããå Žåã¯ããã®ããã°ã©ã ã®å®å šçãåç §ã§ããŸããããã«ãããã®ã£ããã解æ¶ã§ããŸãã
å 容
- çšèª
- ãªãµãŒã
- ã³ã³ãã€ã©äœæ
- ANTLRãã€ã³ã¹ããŒã«ãã
- ANTLRã䜿çšããŠNode.jsã§ãããžã§ã¯ããäœæãã
- ãœãŒã¹ã³ãŒãåæãšæ§æããªãŒæ§ç¯
- ã³ãŒãçæ
- ãšã©ãŒåŠç
- ãããã«
çšèª
ã³ã³ãã€ã©ãŒã¯ãé«æ°Žæºããã°ã©ãã³ã°èšèªã®ãœãŒã¹ããã°ã©ã ãå¥ã®èšèªã®åçã®ããã°ã©ã ã«å€æããŸããããã¯ãã³ã³ãã€ã©ãŒã®åå ãªãã«å®è¡ã§ããŸãã
ã¬ã¯ãµãŒ-åå¥è§£æãå®è¡ããã³ã³ãã€ã©ãŒèŠçŽ ã
åå¥è§£æ ïŒããŒã¯ã³åïŒ-èªèãããã°ã«ãŒãïŒããŒã¯ã³ãããŒã¯ã³ïŒãžã®å ¥åæååã®è§£æ解æã®ããã»ã¹ã
ããŒãµãŒ-çµæã解æããã³ã³ãã€ã©ãŒèŠçŽ ã解æããªãŒã§ãã
解æ-èªç¶èšèªãŸãã¯åœ¢åŒèšèªã®ããŒã¯ã³ã®ç·åœ¢ã·ãŒã±ã³ã¹ã圢åŒææ³ãšæ¯èŒããããã»ã¹ã
èªåœçŽ ãŸãã¯ããŒã¯ã³-ã³ã³ãã€ã©ã«ãšã£ãŠæå³ã®ããããã°ã©ãã³ã°èšèªã®æå¹ãªæåã®ã·ãŒã±ã³ã¹ã
蚪åè -åå«ã®åŠçãç¶è¡ããããªãŒãæäœãããã¿ãŒã³ãæåã§ã¡ãœãããåŒã³åºããŠåå«ããã€ãã¹ããå¿ èŠããããŸãã
ãªã¹ããŒãŸãã¯ãŠã©ãŒã«ãŒ-ãã¹ãŠã®åå«ã蚪åããã¡ãœãããèªåçã«åŒã³åºããããšãã®ããªãŒã®æäœãã¿ãŒã³ã ãªã¹ããŒã«ã¯ãããŒã蚪åã®éå§æã«åŒã³åºãããã¡ãœããïŒenterNodeïŒãšãããŒã蚪ååŸã«åŒã³åºãããã¡ãœããïŒexitNodeïŒããããŸãã
解æããªãŒ-ããŒãµãŒã®çµæãè¡šãæ§é ã å ¥åèšèªã®æ§é ã®æ§æãåæ ããæäœã®å®å šãªçžäºæ¥ç¶ãæ確ã«å«ãã§ããŸãã
æœè±¡æ§æããªãŒ ïŒAST-æœè±¡æ§æããªãŒïŒã¯ãããã°ã©ã ã®ã»ãã³ãã£ã¯ã¹ã«åœ±é¿ãäžããªãæ§æèŠåã®ããŒããšãšããžããªããšããç¹ã§ã解æããªãŒãšã¯ç°ãªããŸãã
Universal Abstract Syntax Tree ïŒUASTïŒã¯ãèšèªã«äŸåããªã泚éã䜿çšããASTã®æ£èŠåããã圢åŒã§ãã
æ·±ãåªå æ¢çŽ¢ããªãŒãã©ããŒãµã«ïŒDFSïŒ-ã°ã©ããã©ããŒãµã«ã¡ãœããã®1ã€ã æ·±ãæ€çŽ¢æŠç¥ã¯ããã®ååã瀺ãããã«ãå¯èœãªéãã°ã©ãã«ãæ·±ãå ¥ã蟌ããããšã§ãã
ææ³ ïŒææ³ïŒ-åå¥è§£æåšããã³æ§æ解æåšãæ§ç¯ããããã®äžé£ã®æ瀺ã
ã«ãŒãããŒã ïŒã«ãŒãïŒ-ã¯ããŒã«ãéå§ããããªãŒã®æäžäœããŒãã ããã¯ç¥å ãæããªãå¯äžã®ããªãŒããŒãã§ãããããèªäœãä»ã®ãã¹ãŠã®ããªãŒããŒãã®ç¥å ã§ãã
ãªãŒãããªãŒãããŸãã¯ã¿ãŒããã«ããŒã ïŒãªãŒãïŒ-åå«ãæããªãããŒãã
芪 -åãæã€ããŒãã åããªãŒããŒãã«ã¯ã0å以äžã®åå«ããŒãããããŸãã
ãªãã©ã«-åºå®å€ãŸãã¯ããŒã¿åã®è¡šçŸã
ã³ãŒããžã§ãã¬ãŒã¿ãŒã¯ãå ¥åãšããŠãœãŒã¹ããã°ã©ã ã®äžéè¡šçŸãåãåããã¿ãŒã²ããèšèªã«å€æããŸãã
ãªãµãŒã
ããããã°ã©ãã³ã°èšèªãå¥ã®ããã°ã©ãã³ã°èšèªã«å€æããåé¡ã解決ããæ¹æ³ã¯3ã€ãããŸãïŒãœãŒã¹ãããœãŒã¹ãžã®å€æïŒã
- ç¹å®ã®ããã°ã©ãã³ã°èšèªã«æ¢åã®ããŒãµãŒã䜿çšããŸãã
- ç¬èªã®ããŒãµãŒãäœæããŸãã
- ããŒã«ãŸãã¯ã©ã€ãã©ãªã䜿çšããŠããŒãµãŒãçæããŸãã
æåã®ãªãã·ã§ã³ã¯è¯ãã§ãããæãæåã§ãµããŒããããŠããèšèªã®ã¿ãã«ããŒããŠããŸãã JavaScriptã«ã¯ã Esprima ã Falafel ã UglifyJS ã Jisonãªã©ã®ããŒãµãŒããããŸãã èªåã§äœããæžãåã«ãæ¢åã®ããŒã«ã調ã¹ã䟡å€ããããŸãããããããå¿ èŠãªæ©èœãå®å šã«ã«ããŒããŠããã§ãããã
éãæªããèšèªã®ããŒãµãŒãèŠã€ãããªãå ŽåããŸãã¯èŠã€ãã£ãããŒãµãŒããã¹ãŠã®ããŒãºãæºãããŠããªãå Žåã¯ã2çªç®ã®ãªãã·ã§ã³ã«é Œã£ãŠèªåã§äœæã§ããŸãã
æåããã³ã³ãã€ã©ãæžãæ¹æ³ãç解ããããã®è¯ãåºçºç¹ã¯ã Super Tiny Compilerã§ãã ãã¡ã€ã«ããã³ã¡ã³ããåé€ãããšãææ°ã®ã³ã³ãã€ã©ãŒã®ãã¹ãŠã®åºæ¬ååãå«ãã³ãŒãã¯200è¡ã®ã¿ã«ãªããŸãã
èšäºã 25è¡ã®JavaScriptã§ã®åçŽãªã³ã³ãã€ã©ãŒã®å®è£ ãã®èè ã¯ãJavaScriptã³ã³ãã€ã©ãŒãäœæããçµéšãå ±æããŠããŸãã ãŸããåå¥è§£æã解æãã³ãŒãçæãªã©ã®æŠå¿µãã«ããŒããŠããŸãã
JavaScriptã§åçŽãªã€ã³ã¿ãŒããªã¿ãŒãäœæããæ¹æ³ã¯ãäŸãšããŠåçŽãªé»åã䜿çšããŠã€ã³ã¿ãŒããªã¿ãŒãäœæããããã»ã¹ã調ã¹ãå¥ã®ãªãœãŒã¹ã§ãã
ã³ã³ãã€ã©ãŒããŒãããäœæããã®ã¯æéã®ãããããã»ã¹ã§ãããã³ã³ãã€ã«ãããèšèªã®æ§æäžã®æ©èœã培åºçã«äºå調æ»ããå¿ èŠããããŸãã ãã®å ŽåãããŒã¯ãŒãã ãã§ãªããããŒã¯ãŒãã®çžå¯Ÿçãªäœçœ®ãèªèããå¿ èŠããããŸãã ãœãŒã¹ã³ãŒããåæããããã®ã«ãŒã«ã¯æ確ã§ãããåãåææ¡ä»¶äžã§åºåã§åãçµæãäžããå¿ èŠããããŸãã
ããŒãµãŒãçæããããã®ããŒã«ãšã©ã€ãã©ãªãããã«åœ¹ç«ã¡ãŸãã çã®ãœãŒã¹ã³ãŒããååŸããããŒã¯ã³ã«åå²ãïŒåå¥è§£æïŒãããŒã¯ã³ã®ç·åœ¢ã·ãŒã±ã³ã¹ãæ£åŒãªææ³ã«ããããïŒè§£æïŒãæ°ããã³ãŒããæ§ç¯ã§ããããªãŒæ§é ã®æ§é ã«ããããé 眮ããŸãã ãããã®äžéšã«ã€ããŠã¯ãèšäºã JavaScriptã§ã®è§£æïŒããŒã«ãšã©ã€ãã©ãªãã§èª¬æããŠããŸã ã
![](https://habrastorage.org/webt/ib/el/vw/ibelvw6fn2ex2egpa9lfjh0osfq.png)
äžèŠãåé¡ã®è§£æ±ºçã¯ãã±ããã®äžã«ããããã«æãããããããŸãããããœãŒã¹ã³ãŒããèªèããããã«ããŒãµãŒã«æããããã«ã¯ãæ瀺ïŒææ³ïŒãæžãããã«ããå€ãã®å·¥æ°ãè²»ããå¿ èŠããããŸãã ãŸããã³ã³ãã€ã©ãè€æ°ã®ããã°ã©ãã³ã°èšèªããµããŒãããå¿ èŠãããå Žåããã®ã¿ã¹ã¯ã¯èããè€éã§ãã
ãã®èª²é¡ã«çŽé¢ããæåã®éçºè ã§ã¯ãªãããšã¯æããã§ãã IDEã®äœæ¥ã¯ã³ãŒãåæã«é¢é£ããŠãããBabelã¯ææ°ã®JavaScriptããã¹ãŠã®ãã©ãŠã¶ãŒã§ãµããŒããããæšæºã«å€æããŸãã ããã¯ãåå©çšã§ããææ³ããªããã°ãªããªãããšãæå³ããããã«ãã£ãŠäœæ¥ã容æã«ããã ãã§ãªããå€ãã®æœåšçã«é倧ãªãšã©ãŒãäžæ£ç¢ºããåé¿ã§ããŸãã
ãããã£ãŠãç§ãã¡ã®éžæã¯ãã»ãšãã©ãã¹ãŠã®ããã°ã©ãã³ã°èšèªã®ææ³ãå«ãŸããŠãããããèŠä»¶ã«æé©ãªANTLRã«åºã¥ããŠããŸãã
å¥ã®æ¹æ³ã¯Babelfishã§ã ãããã¯ããµããŒããããŠããèšèªã®ãã¡ã€ã«ã解æãããã®ãã¡ã€ã«ããASTãæœåºããUASTã«å€æããŸããããŒãã¯ãœãŒã¹èšèªã®æ§æã«ãã€ã³ããããŠããŸããã å ¥åã§ã¯JavaScriptãŸãã¯CïŒã䜿çšã§ããŸãããUASTã¬ãã«ã§ã¯éãã¯èŠãããŸããã ã³ã³ãã€ã©ã®çšèªã§ã¯ãå€æããã»ã¹ã¯ASTããŠãããŒãµã«åã«ãã£ã¹ãããããã»ã¹ãæ åœããŸãã
![](https://habrastorage.org/webt/o5/df/qb/o5dfqbbs8nx1szgbkablez67-fg.png)
ã³ã³ãã€ã©ã®åå¿è ã¯ãç¹å®ã®ã³ãŒããã©ã°ã¡ã³ããšéžæããèšèªã«å¯Ÿå¿ããããŒãµãŒã«å¯ŸããŠæ§æããªãŒãã©ã®ãããªãã®ãã確èªã§ããã€ã³ã¿ãŒãã§ã€ã¹ã§ããAstexplorerã«ãèå³ããããããããŸããã ãããã°ããASTã®æ§é ã®äžè¬çãªã¢ã€ãã¢ã®åœ¢æã«åœ¹ç«ã¡ãŸãã
ã³ã³ãã€ã©äœæ
ANTLR ïŒèšèªèªèã®ããã®å¥ã®ããŒã«-èšèªãèªèããããã®å¥ã®ããŒã«ïŒã¯ãJavaã§æžãããããŒãµãŒãžã§ãã¬ãŒã¿ãŒã§ãã 圌ã¯å ¥åãšããŠããã¹ããåãåãããããææ³ã«åºã¥ããŠåæãããããçµç¹åãããæ§é ã«å€æããããã䜿çšããŠæœè±¡çãªæ§æããªãŒãäœæããããšãã§ããŸãã ANTLR 3ããã®ã¿ã¹ã¯ãåŒãåããŸãã-ASTã«ãã£ãŠçæãããŸãã ãã ããANTLR 4ã¯StringTemplatesã䜿çšããããã«ãã®æ©èœãé€å€ãã解æããªãŒãªã©ã®æŠå¿µã§ã®ã¿åäœããŸãã
詳现ã«ã€ããŠã¯ã ããã¥ã¡ã³ããåç §ãããã The ANTLR Mega Tutorialã®åªããèšäºãåç §ããŠãã ãããããŒãµãŒãšã¯äœãããªããããå¿ èŠãªã®ããANTLRã®èšå®æ¹æ³ã䟿å©ãªANTLRé¢æ°ãªã©ãå€æ°ã®äŸã玹ä»ããŠããŸãã
ææ³ã®äœæã«ã€ããŠè©³ããã¯ããã¡ããã芧ãã ããã
ããããã°ã©ãã³ã°èšèªãå¥ã®ããã°ã©ãã³ã°èšèªã«å€æããããã«ãANTLR 4ãšãã®ææ³ã®1ã€ãã€ãŸãECMAScript.g4ã䜿çšããããšã«ããŸããã JavaScriptãéžæããã®ã¯ããã®æ§æãMongo Shellèšèªã«å¯Ÿå¿ããCompassã¢ããªã±ãŒã·ã§ã³ã®éçºèšèªã§ãããããã§ãã èå³æ·±ãäºå®ïŒLexerãšParser CïŒã䜿çšããŠè§£æããªãŒãæ§ç¯ã§ããŸãããECMAScriptææ³ã®ããŒããä»ããŠããããã€ãã¹ã§ããŸãã
ãã®è³ªåã«ã¯ããã詳现ãªèª¿æ»ãå¿ èŠã§ãã èªä¿¡ãæã£ãŠããã¹ãŠã®ã³ãŒãæ§é ãããã©ã«ãã§æ£ããèªèããããšã¯éããŸããã æ°ããã¡ãœãããšãã§ãã¯ã䜿çšããŠãã€ãã¹æ©èœãæ¡åŒµããå¿ èŠããããŸãã ãã ããåãã¢ããªã±ãŒã·ã§ã³å ã§è€æ°ã®ããŒãµãŒããµããŒãããå ŽåãANTLRãåªããããŒã«ã§ããããšã¯æ¢ã«æããã§ãã
ANTLRã¯ãããªãŒãæäœããããã®ãµããŒããã¡ã€ã«ã®ãªã¹ããäœæããŸãã ãããã®ãã¡ã€ã«ã®å 容ã¯ãææ³ã§æå®ãããã«ãŒã«ã«çŽæ¥äŸåããŠããŸãã ãããã£ãŠãææ³ãå€æŽãããå Žåããããã®ãã¡ã€ã«ãåçæããå¿ èŠããããŸãã ããã¯ãã³ãŒãã®èšè¿°ã«çŽæ¥äœ¿çšããªãã§ãã ãããããããªããšã次ã®å埩ã§å€æŽã倱ãããŸãã ã¯ã©ã¹ãäœæããANTLRã«ãã£ãŠçæãããã¯ã©ã¹ããç¶æ¿ããå¿ èŠããããŸãã
ANTLRã®çµæãšããŠçæãããã³ãŒãã¯ã解æããªãŒã®äœæã«åœ¹ç«ã¡ãŸããããã¯ãæ°ããã³ãŒããçæããããã®åºæ¬çãªæ段ã§ãã äžçªäžã®è¡ã¯ãåããŒããå·Šããå³ã«åŒã³åºãïŒããããœãŒã¹ããã¹ãã®é åºã§ããå ŽåïŒãããããè¡šãæžåŒèšå®ãããããã¹ããè¿ãããšã§ãã
ããŒãããªãã©ã«ã®å Žåãå®éã®å€ãè¿ãå¿ èŠããããŸãã çµæãæ£ç¢ºã«ãããå Žåãããã¯æã£ãããé£ããã§ãã ãã®å Žåã粟床ãæãªãããšãªãæµ®åå°æ°ç¹æ°ãåºåããæ©èœãšãããŸããŸãªæ°å€ã·ã¹ãã ã®æ°å€ãæäŸããå¿ èŠããããŸãã æååãªãã©ã«ã®å ŽåããµããŒãããåŒçšç¬Šã®ã¿ã€ããæ€èšãã䟡å€ããããŸãããŸãããšã¹ã±ãŒãããå¿ èŠãããæåã®ãšã¹ã±ãŒãã·ãŒã±ã³ã¹ãå¿ããªãã§ãã ããã ã³ãŒãã³ã¡ã³ãããµããŒãããŠããŸããïŒ ãŠãŒã¶ãŒå ¥å圢åŒïŒã¹ããŒã¹ã空çœè¡ïŒãç¶æããŸããããããšãããã¹ããããæšæºçã§èªã¿ããããã©ãŒã ã«ããŸããã äžæ¹ã§ã¯ã2çªç®ã®ãªãã·ã§ã³ã¯ããå°éçã«èŠããŸãããä»æ¹ã§ã¯ãã³ã³ãã€ã©ãŒã®ãŠãŒã¶ãŒã¯ãçµæãšããŠèªåã®å ¥åãšåã圢åŒãååŸãããã®ã§ãçµæãšããŠæºè¶³ããªããããããŸããã ãããã®åé¡ã«å¯Ÿããæ®éçãªè§£æ±ºçã¯ãããŸãããã³ã³ãã€ã©ãŒã®ç¯å²ããã詳现ã«èª¿æ»ããå¿ èŠããããŸãã
ANTLRã䜿çšããŠã³ã³ãã€ã©ãŒãäœæããåºæ¬ã«éäžããããã«ãããåçŽãªäŸãæ€èšããŸãã
ANTLRãã€ã³ã¹ããŒã«ãã
$ brew cask install java $ cd /usr/local/lib $ curl -O http://www.antlr.org/download/antlr-4.7.1-complete.jar $ export CLASSPATH=".:/usr/local/lib/antlr-4.7.1-complete.jar:$CLASSPATH" $ alias antlr4='java -Xmx500M -cp "/usr/local/lib/antlr-4.7.1-complete.jar:$CLASSPATH" org.antlr.v4.Tool' $ alias grun='java org.antlr.v4.gui.TestRig'
ãã¹ãŠã®ã€ã³ã¹ããŒã«ãæåããããšã確èªããã«ã¯ãã¿ãŒããã«ã«å ¥åããŸãã
$ java org.antlr.v4.Tool
ANTLRããŒãžã§ã³ã«é¢ããæ å ±ãšã³ãã³ãã®ãã«ãã衚瀺ãããŸãã
![](https://habrastorage.org/webt/p7/la/n3/p7lan3cfuduw4kz2chewi3zdshq.png)
ANTLRã䜿çšããŠNode.jsã§ãããžã§ã¯ããäœæãã
$ mkdir js-runtime $ cd js-runtime $ npm init
JavaScriptã©ã³ã¿ã€ã ãã€ã³ã¹ããŒã«ããŸããããã«ã¯ãANTL 4ã® npmããã±ãŒãžantlr4- JavaScriptã¿ãŒã²ãããå¿ èŠã§ãã
$ npm i antlr4 --save
ECMAScript.g4ææ³ãããŠã³ããŒãããŸããããã¯åŸã§ANTLRã«ãã£ãŒãããŸãã
$ mkdir grammars $ curl --http1.1 https://github.com/antlr/grammars-v4/blob/master/ecmascript/ECMAScript.g4 --output grammars/ECMAScript.g4
ã¡ãªã¿ã«ã ANTLR Webãµã€ãã®[éçºããŒã«]ã»ã¯ã·ã§ã³ã«ã¯ãIntellijãNetBeansãEclipseãVisual Studio CodeãjEditãªã©ã®IDEã®ãã©ã°ã€ã³ãžã®ãªã³ã¯ããããŸãã ã«ã©ãŒããŒããã»ãã³ãã£ãã¯ãšã©ãŒãã§ãã¯ããã€ã¢ã°ã©ã ã䜿çšããèŠèŠåã«ãããææ³ã®èšè¿°ãšãã¹ãã容æã«ãªããŸãã
æåŸã«ãANTLRãå®è¡ããŸãã
$ java -Xmx500M -cp '/usr/local/lib/antlr-4.7.1-complete.jar:$CLASSPATH' org.antlr.v4.Tool -Dlanguage=JavaScript -lib grammars -o lib -visitor -Xexact-output-dir grammars/ECMAScript.g4
ãã®ã¹ã¯ãªãããpackage.jsonã«è¿œå ããŠãåžžã«ã¢ã¯ã»ã¹ã§ããããã«ããŸãã ææ³ãã¡ã€ã«ãå€æŽããå Žåã¯ãANTLRãåèµ·åããŠå€æŽãé©çšããå¿ èŠããããŸãã
![](https://habrastorage.org/webt/an/k3/kr/ank3kraw0ibich8qkb7nnuynori.png)
libãã©ã«ããŒã«ç§»åããANTLRããã¡ã€ã«ã®ãªã¹ããäœæããããšã確èªããŸãã ãããã®ãã¡ã®3ã€ãããã«è©³ããèŠãŠãããŸãããã
- ECMAScriptLexer.jsã¯ãææ³ã§æå®ãããèŠåã«åŸã£ãŠããœãŒã¹ã³ãŒãã®æåã¹ããªãŒã ãããŒã¯ã³ã¹ããªãŒã ã«åå²ããŸãã
- ECMAScriptParser.jsã¯ãããŒã¯ã³ã¹ããªãŒã ããã解æããªãŒãšåŒã°ããæœè±¡çãªæ¥ç¶ãããããªãŒã®ãããªæ§é ãæ§ç¯ããŸãã
- ECMAScriptVisitor.jsã¯ãæ§ç¯ãããããªãŒãèµ°æ»ããŸãã çè«çã«ã¯ãåå«ã®æ·±ããååž°çã«èµ°æ»ããŠããã®ããªãŒãç¬ç«ããŠåŠçã§ããŸãã ãã ããå€æ°ã®ããŒãã¿ã€ããšãããã®åŠçã®è€éãªããžãã¯ã䜿çšããå Žåã¯ã蚪åè ãè¡ãããã«ãç¬èªã®ã¡ãœããã䜿çšããŠåããŒãã¿ã€ãã«ã¢ã¯ã»ã¹ããããšããå§ãããŸãã
ããã©ã«ãã§ã¯ãANTLRã¯* Visitor.jsãäœæããªãããšã«æ³šæããŠãã ããã ANTLRã§ããªãŒããã©ããŒã¹ããæšæºçãªæ¹æ³ã¯ãªã¹ããŒã§ãã ãªã¹ããŒã®ä»£ããã«èšªåè ãçæããŠäœ¿çšããå Žåã¯ãã¹ã¯ãªããã§è¡ã£ãããã«ã '
-visitor
'ãã©ã°ã䜿çšããŠæ瀺çã«æå®ããå¿ èŠããããŸãã
$ java -Xmx500M -cp '/usr/local/lib/antlr-4.7.1-complete.jar:$CLASSPATH' org.antlr.v4.Tool -Dlanguage=JavaScript -lib grammars -o lib -visitor -Xexact-output-dir grammars/ECMAScript.g4
ãã ããäž¡æ¹ã®æ¹æ³ã®äœæ¥ã®æ¬è³ªãšçµæã¯éåžžã«äŒŒãŠããŸãããVisitorã䜿çšãããšã³ãŒãããããããã«èŠããå€æããã»ã¹ããã詳现ã«å¶åŸ¡ã§ããŸãã ããªãŒã®ããŒãã«ã¢ã¯ã»ã¹ããé åºãšãããŒãã«ã¢ã¯ã»ã¹ãããã©ãããèšå®ã§ããŸãã ã¯ããŒã«äžã«æ¢åã®ãµã€ããå€æŽããããšãã§ãã蚪åãããµã€ãã«é¢ããæ å ±ãä¿åããå¿ èŠã¯ãããŸããã èšäºAntlr4-蚪åè ãšãªã¹ããŒã®ãã¿ãŒã³ã¯ããã®ãããã¯ããã詳现ã«ãäŸãšãšãã«èª¬æããŸããã
ãœãŒã¹ã³ãŒãåæãšæ§æããªãŒæ§ç¯
æåŸã«ããã°ã©ãã³ã°ãå§ããŸãããã ANTLRãšJavaScriptã®çµã¿åããã§æ€çŽ¢ãããšãæåéãã©ãã«ã§ã䌌ããããªã³ãŒãã®äŸãèŠã€ãããŸãã
const antlr4 = require('antlr4'); const ECMAScriptLexer = require('./lib/ECMAScriptLexer.js'); const ECMAScriptParser = require('./lib/ECMAScriptParser.js'); const input = '{x: 1}'; const chars = new antlr4.InputStream(input); const lexer = new ECMAScriptLexer.ECMAScriptLexer(chars); lexer.strictMode = false; // JavaScript strictMode const tokens = new antlr4.CommonTokenStream(lexer); const parser = new ECMAScriptParser.ECMAScriptParser(tokens); const tree = parser.program(); console.log(tree.toStringTree(parser.ruleNames));
ä»ãã£ãããšïŒANTLRãçæããã¬ã¯ãµãŒãšããŒãµãŒã䜿çšããŠããœãŒã¹æååãLISP圢åŒïŒANTLR 4ã®æšæºããªãŒåºå圢åŒïŒã§ããªãŒãã¥ãŒã«è¡šç€ºããŸããã ææ³ã«ãããšãECMAScriptããªãŒã®ã«ãŒãã¯ã
program
ã«ãŒã«ã§ããããããã®äŸã§ã¯ãã©ããŒãµã«ã®éå§ç¹ãšããŠéžæããŸããã ãã ããããã¯ãã®ããŒããåžžã«æåã§ããããšãæå³ãããã®ã§ã¯ãããŸããã å ã®æåå `
{x: 1}
`ã®å Žåã `
expressionSequence
ã¯ããŒã«ãéå§ããããšã¯å®å šã«å ¬å¹³ã§ãã
const tree = parser.expressionSequence();
![](https://habrastorage.org/webt/fd/d3/to/fdd3to-l4uqw0a2q7khipevigl0.png)
`
.toStringTree()
`ãã©ãŒããããåé€ãããšãããªãŒãªããžã§ã¯ãã®å éšæ§é ãèŠãããšãã§ããŸãã
åŸæ¥ãããããã°ã©ãã³ã°èšèªãå¥ã®ããã°ã©ãã³ã°èšèªã«å€æããããã»ã¹å šäœã¯ã3ã€ã®æ®µéã«åããããšãã§ããŸãã
- ãœãŒã¹ã³ãŒãåæã
- æ§æããªãŒã®æ§ç¯ã
- æ°ããã³ãŒããçæããŸãã
ã芧ã®ãšãããANTLRã®ãããã§äœæ¥ãå€§å¹ ã«ç°¡çŽ åãããæ°è¡ã®ã³ãŒãã§ããã€ãã®æé ãã«ããŒãããŸããã ãã¡ããããããã«æ»ããææ³ãæŽæ°ããããªãŒãå€æããŸãããããã§ãè¯ãåºç€ã¯ãã§ã«æ§ç¯ãããŠããŸãã ãªããžããªããããŠã³ããŒããããææ³ãå£ããããšã©ãŒãçºçããå¯èœæ§ããããŸãã ããããããããã圌ãã¯èªåã§ææ³ãäžããæžãå§ããå Žåã«ã®ã¿ãããªããç¯ããã§ãããééãããã§ã«ä¿®æ£ããŠããã§ãããã ãã€ã³ãã¯ããã§ããä»ã®éçºè ãæžããã³ãŒããç²ç®çã«ä¿¡é Œããã¹ãã§ã¯ãããŸããããæ¢åã®ã«ãŒã«ãæ¹åããããã«åãã«ãŒã«ãæžãæéãç¯çŽã§ããŸãã ããããã次äžä»£ã®è¥ãANTLRã¯ãããçæ³çãªããŒãžã§ã³ã®ææ³ããã§ã«ããŠã³ããŒãããŠããã®ã§ãããã
ã³ãŒãçæ
ãããžã§ã¯ãã«æ°ãããã£ã¬ã¯ã㪠`
codegeneration
äœæãããã®äžã«æ°ããPythonGenerator.jsãã¡ã€ã«ãäœæããŸãã
$ mkdir codegeneration $ cd codegeneration $ touch PythonGenerator.js
ãæ³åã®ãšãããäŸãšããŠãJavaScriptããPythonã«äœããå€æããŠããŸãã
çæãããECMAScriptVisitor.jsãã¡ã€ã«ã«ã¯ãèšå€§ãªã¡ãœããã®ãªã¹ããå«ãŸããŠããŸããåã¡ãœããã¯ã察å¿ããããŒãã«ã¢ã¯ã»ã¹ãããšãããªãŒãŠã©ãŒã¯äžã«èªåçã«åŒã³åºãããŸãã ãããŠãã®ç¬éãçŸåšã®ããŒããå€æŽã§ããŸãã ãããè¡ãã«ã¯ãECMAScriptVisitorããç¶æ¿ããå¿ èŠãªã¡ãœããããªãŒããŒã©ã€ãããã¯ã©ã¹ãäœæããŸãã
const ECMAScriptVisitor = require('../lib/ECMAScriptVisitor').ECMAScriptVisitor; /** * Visitor , ANTLR * JavaScript Python * * @returns {object} */ class Visitor extends ECMAScriptVisitor { /** * * * @param {object} ctx * @returns {string} */ start(ctx) { return this.visitExpressionSequence(ctx); } } module.exports = Visitor;
ææ³ã®æ§æèŠåã«æºæ ããã¡ãœããã«å ããŠãANTLRã¯4ã€ã®ç¹å¥ãªãããªãã¯ã¡ãœããããµããŒãããŸã ã
- visitïŒïŒã¯ãããªãŒã®ãã©ããŒã¹ãæ åœããŸãã
- visitChildrenïŒïŒã¯ããŒãã®æšªæãæ åœããŸãã
- visitTerminalïŒïŒã¯ãããŒã¯ã³ã®ãã€ãã¹ãæ åœããŸãã
- visitErrorNodeïŒïŒã¯ãç¡å¹ãªããŒã¯ã³ããã€ãã¹ããŸãã
visitChildren()
ã¡ãœãã `
visitChildren()
`ã `
visitChildren()
`ã `
visitTerminal()
`ãå®è£ ããŸãã
/* * * * @param {object} ctx * @returns {string} */ visitChildren(ctx) { let code = ''; for (let i = 0; i < ctx.getChildCount(); i++) { code += this.visit(ctx.getChild(i)); } return code.trim(); } /** * ( ) * * @param {object} ctx * @returns {string} */ visitTerminal(ctx) { return ctx.getText(); } /** * , * * @param {object} ctx * @returns {string} */ visitPropertyExpressionAssignment(ctx) { const key = this.visit(ctx.propertyName()); const value = this.visit(ctx.singleExpression()); return `'${key}': ${value}`; }
é¢æ° `
visitPropertyExpressionAssignment
ã¯ãå€`
visitPropertyExpressionAssignment
`
visitPropertyExpressionAssignment
ã«å²ãåœãŠãããŒãã«
visitPropertyExpressionAssignment
ãŸãã Pythonã§ã¯ããªãã·ã§ã³ã®JavaScriptãšã¯ç°ãªãããªããžã§ã¯ãã®æååãã©ã¡ãŒã¿ãŒã¯åŒçšç¬Šã§å²ãå¿ èŠããããŸãã ãã®å Žåãããã¯JavaScriptã³ãŒãã®ãã©ã°ã¡ã³ããPythonã³ãŒãã«å€æããããã«å¿ èŠãªå¯äžã®å€æŽã§ãã
![](https://habrastorage.org/webt/zp/0c/uq/zp0cuqgitso9ebb5gj2hij_6vlo.png)
index.jsã§PythonGeneratorãžã®åŒã³åºããè¿œå ããŸãã
console.log('JavaScript input:'); console.log(input); console.log('Python output:'); const output = new PythonGenerator().start(tree); console.log(output);
ããã°ã©ã ãå®è¡ããçµæãã³ã³ãã€ã©ãã¿ã¹ã¯ãæ£åžžã«å®äºããJavaScriptãªããžã§ã¯ããPythonãªããžã§ã¯ãã«å€æããããšãããããŸãã
![](https://habrastorage.org/webt/dc/ln/5y/dcln5y4kccccgaimr6gm-pwkdw0.png)
ç§ãã¡ã¯èŠªããåå«ãžãšæšã暪æãå§ããåŸã ã«ãã®èãžãšéããŠãããŸãã 次ã«ãéã®é åºã§1ã¬ãã«äžã®æžåŒèšå®ãããå€ã眮æããŸãããããã£ãŠãããªãŒããŒãã®ãã§ãŒã³å šäœããæ°ããããã°ã©ãã³ã°èšèªã®æ§æã«å¯Ÿå¿ããããã¹ãè¡šçŸã«çœ®ãæããŸãã
![](https://habrastorage.org/webt/yn/6p/t4/yn6pt4qtqbzy9bcmmw3jlwbshdc.png)
`
visitPropertyExpressionAssignment
é¢æ°ã«ãããã°ãè¿œå ããŸãã
// console.log(ctx.getText()); // - console.log(ctx.getChildCount()); // console.log(ctx.propertyName().getText()) x console.log(ctx.getChild(0).getText()); // : console.log(ctx.getChild(1).getText()); // console.log(ctx.singleExpression().getText()) 1 console.log(ctx.getChild(2).getText());
åå«ã«ã¯ãååãšã·ãªã¢ã«çªå·ã®äž¡æ¹ã§ã¢ã¯ã»ã¹ã§ããŸãã åå«ã¯ããŒãã§ãããããããªããžã§ã¯ãè¡šçŸã§ã¯ãªãããã¹ãå€ãååŸããããã«ã `
.getText()
`ã¡ãœããã䜿çšããŸããã
ECMAScript.g4ãè£è¶³ããã³ã³ãã€ã©ã« `
Number
ããŒã¯ãŒããèªèããããã«æããŸãã
![](https://habrastorage.org/webt/qj/u6/sd/qju6sdfomdvi6ngzv83-f3c6nnw.png)
![](https://habrastorage.org/webt/oj/dp/i4/ojdpi4iiaz8aws6yi6zpzwux6lq.png)
ããžã¿ãŒãåçæããŠãææ³ã«å ããããå€æŽãåŒãåºããŸãã
$ npm run compile
PythonGenerator.jsãã¡ã€ã«ã«æ»ããæ°ããã¡ãœããã®ãªã¹ããè¿œå ããŸãã
/** * `new` * * @param {object} ctx * @returns {string} */ visitNewExpression(ctx) { return this.visit(ctx.singleExpression()); } /** * `Number` * * @param {object} ctx * @returns {string} */ visitNumberExpression(ctx) { const argumentList = ctx.arguments().argumentList(); // JavaScript Number , // if (argumentList === null || argumentList.getChildCount() !== 1) { return 'Error: Number '; } const arg = argumentList.singleExpression()[0]; const number = this.removeQuotes(this.visit(arg)); return `int(${number})`; } /** * * * @param {String} str * @returns {String} */ removeQuotes(str) { let newStr = str; if ( (str.charAt(0) === '"' && str.charAt(str.length - 1) === '"') || (str.charAt(0) === '\'' && str.charAt(str.length - 1) === '\'') ) { newStr = str.substr(1, str.length - 2); } return newStr; }
Pythonã¯ã³ã³ã¹ãã©ã¯ã¿ãåŒã³åºããšãã« `
visitNewExpression
ããŒã¯ãŒãã䜿çšããªãããããããåé€ãããã
visitNewExpression
ããŒãã§æåã®åãåé€ããŠããªãŒã®èµ°æ»ãç¶è¡ããŸãã 次ã«ãããŒã¯ãŒã `
Number
ã`
int
ã«çœ®ãæããŸããããã¯Pythonã®åçã®æ©èœã§ãã `
Number
ã¯åŒïŒåŒïŒã§ããããã
.arguments()
`ã¡ãœãããä»ããŠåŒæ°ã«ã¢ã¯ã»ã¹ã§ããŸãã
![](https://habrastorage.org/webt/id/a0/q_/ida0q_bjpjz-0wgmzmur2-ze-fq.png)
åæ§ã«ãECMAScriptVisitor.jsã«ãªã¹ããããŠãããã¹ãŠã®ã¡ãœãããå®è¡ãããã¹ãŠã®JavaScriptãªãã©ã«ãã·ã³ãã«ãã«ãŒã«ãªã©ãPythonïŒãŸãã¯ä»ã®ããã°ã©ãã³ã°èšèªïŒã®åçç©ã«å€æã§ããŸãã
ãšã©ãŒåŠç
ANTLRã¯ããã©ã«ãã§ãææ³ã§æå®ãããæ§æã«æºæ ããŠãããã©ããã®å ¥åãæ€èšŒããŸãã äžäžèŽãçºçããå Žåãã³ã³ãœãŒã«ã«ã¯çºçããåé¡ã«é¢ããæ å ±ãæäŸãããŸãããANTLRã¯èªèã§ããæååãè¿ããŸãã ãœãŒã¹æåå `{xïŒ2}`ããã³ãã³ãåé€ãããšãANTLRã¯èªèãããªãããŒãã `undefined`ã«çœ®ãæããŸãã
![](https://habrastorage.org/webt/bw/st/pj/bwstpjor3cjlqxshx9umd8gakjo.png)
ãã®åäœã«åœ±é¿ãäžããããšãã§ããç Žç·ã®ä»£ããã«è©³çŽ°ãªãšã©ãŒæ å ±ãåºåããŸãã ãŸããã¢ããªã±ãŒã·ã§ã³ã®ã«ãŒãã«æ°ããã¢ãžã¥ãŒã«ãäœæããŸãããã®ã¢ãžã¥ãŒã«ã¯ãã«ã¹ã¿ã ãšã©ãŒã¿ã€ããçæããŸãã
$ mkdir error $ cd error $ touch helper.js $ touch config.json
ããã¯ã³ã³ãã€ã©ã«é¢ãããããã¯ã®ç¯å²ãè¶ ããŠããããããã®ã¢ãžã¥ãŒã«ã®å®è£ ã®æ©èœã«ã€ããŠã¯èª¬æããŸããã 以äžã®å®æããŒãžã§ã³ãã³ããŒããããã¢ããªã±ãŒã·ã§ã³ã®ã€ã³ãã©ã¹ãã©ã¯ãã£ã«ããé©ããç¬èªã®ããŒãžã§ã³ãäœæã§ããŸãã
ã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšãããã¹ãŠã®ã¿ã€ãã®ãšã©ãŒã¯ãconfig.jsonã«ç€ºãããŠããŸãã
{ "syntax": {"generic": {"message": "Something went wrong"}}, "semantic": { "argumentCountMismatch": { "message": "Argument count mismatch" } } }
次ã«ãerror.jsã¯æ§æãããªã¹ãã埪ç°ãããã®äžã®åã¬ã³ãŒãã«å¯ŸããŠãErrorããç¶æ¿ãããåå¥ã®ã¯ã©ã¹ãäœæããŸãã
const config = require('./config.json'); const errors = {}; Object.keys(config).forEach((group) => { Object.keys(config[group]).forEach((definition) => { // const name = [ group[0].toUpperCase(), group.slice(1), definition[0].toUpperCase(), definition.slice(1), 'Error' ].join(''); const code = `E_${group.toUpperCase()}_${definition.toUpperCase()}`; const message = config[group][definition].message; errors[name] = class extends Error { constructor(payload) { super(payload); this.code = code; this.message = message; if (typeof payload !== 'undefined') { this.message = payload.message || message; this.payload = payload; } Error.captureStackTrace(this, errors[name]); } }; }); }); module.exports = errors;
visitNumberExpression
ã¡ãœãããæŽæ°ãããšã `
Error
ããŒã¯ãããããã¹ãã¡ãã»ãŒãžã®ä»£ããã«ã`
SemanticArgumentCountMismatchError
`errorãã¹ããŒãããŸããããã«ããããã£ãããããããªããã¢ããªã±ãŒã·ã§ã³ã®æåãšåé¡ã®ããçµæãåºå¥ãããããªããŸãã
const path = require('path'); const { SemanticArgumentCountMismatchError } = require(path.resolve('error', 'helper')); /** * `Number` * * @param {object} ctx * @returns {string} */ visitNumberExpression(ctx) { const argumentList = ctx.arguments().argumentList(); if (argumentList === null || argumentList.getChildCount() !== 1) { throw new SemanticArgumentCountMismatchError(); } const arg = argumentList.singleExpression()[0]; const number = this.removeQuotes(this.visit(arg)); return `int(${number})`; }
ããã§ãANTLRã®äœæ¥ã«çŽæ¥é¢é£ãããšã©ãŒãã€ãŸãã³ãŒãã®è§£æäžã«çºçãããšã©ãŒã«å¯ŸåŠããŸãããã ã³ãŒãçæãã£ã¬ã¯ããªã§ãæ°ãããã¡ã€ã«ErrorListener.jsãäœæãããã®äžã« `antlr4.error.ErrorListener`ããç¶æ¿ããã¯ã©ã¹ãäœæããŸãã
const antlr4 = require('antlr4'); const path = require('path'); const {SyntaxGenericError} = require(path.resolve('error', 'helper')); /** * * * @returns {object} */ class ErrorListener extends antlr4.error.ErrorListener { /** * * * @param {object} recognizer , * @param {object} symbol , * @param {int} line * @param {int} column * @param {string} message * @param {string} payload */ syntaxError(recognizer, symbol, line, column, message, payload) { throw new SyntaxGenericError({line, column, message}); } } module.exports = ErrorListener;
æšæºãšã©ãŒåºåã¡ãœããããªãŒããŒã©ã€ãããã«ã¯ãANTLRããŒãµãŒã§äœ¿çšå¯èœãª2ã€ã®ã¡ãœããã䜿çšããŸãã
- parser.removeErrorListenersïŒïŒã¯ãæšæºã®ConsoleErrorListenerãåé€ããŸãã
- parser.addErrorListenerïŒïŒã¯ãã«ã¹ã¿ã ErrorListenerãè¿œå ããŸãã
ããã¯ãããŒãµãŒãäœæããåŸãåŒã³åºãåã«è¡ãå¿ èŠããããŸãã æŽæ°ãããindex.jsã®å®å šãªã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
const antlr4 = require('antlr4'); const ECMAScriptLexer = require('./lib/ECMAScriptLexer.js'); const ECMAScriptParser = require('./lib/ECMAScriptParser.js'); const PythonGenerator = require('./codegeneration/PythonGenerator.js'); const ErrorListener = require('./codegeneration/ErrorListener.js'); const input = '{x 2}'; const chars = new antlr4.InputStream(input); const lexer = new ECMAScriptLexer.ECMAScriptLexer(chars); lexer.strictMode = false; // JavaScript strictMode const tokens = new antlr4.CommonTokenStream(lexer); const parser = new ECMAScriptParser.ECMAScriptParser(tokens); const listener = new ErrorListener(); parser.removeErrorListeners(); parser.addErrorListener(listener); console.log('JavaScript input:'); console.log(input); console.log('Python output:'); try { const tree = parser.expressionSequence(); const output = new PythonGenerator().start(tree); console.log(output); // console.log(tree.toStringTree(parser.ruleNames)); } catch (error) { console.log(error); }
ãšã©ãŒãªããžã§ã¯ãã«å«ãŸããŠããæ å ±ã®ãããã§ãçºçããäŸå€ãæ£ããåŠçããæ¹æ³ãããã°ã©ã ãäžæãŸãã¯ç¶è¡ããæ¹æ³ãæçãªãã°ãéå§ããæ¹æ³ãæåŸã«ãªããŸããã³ã³ãã€ã©ã®æ£ãããœãŒã¹ããŒã¿ãšèª€ã£ããœãŒã¹ããŒã¿ããµããŒããããã¹ããäœæããæ¹æ³ã決å®ã§ããŸãã
![](https://habrastorage.org/webt/r5/pz/_r/r5pz_rrkvjcau1t7xe4xdxorv2k.png)
ãããã«
誰ããã³ã³ãã€ã©ãæžãããã«é Œãã ããããã«åæããŠãã ããïŒ ããã¯éåžžã«èå³æ·±ããã®ã§ãããéåžžã®ããã°ã©ãã³ã°ã¿ã¹ã¯ãšã¯å€§ããç°ãªãå¯èœæ§ããããŸãã ANTLRã䜿çšããŠJavaScriptã§ã³ã³ãã€ã©ãŒãèšè¿°ãããšããèãæ¹ãæŠèª¬ããããã«ãæãåçŽãªããŒãã®ã¿ãèæ ®ããŸããã ãã®æ©èœã¯ãæž¡ãããåŒæ°ã®ã¿ã€ããæ€èšŒããæ¡åŒµJSONãŸãã¯BSONãµããŒããææ³ã«è¿œå ããèå¥åããŒãã«ã䜿çšããŠtoJSONïŒïŒãtoStringïŒïŒãgetTimestampïŒïŒãªã©ã®ã¡ãœãããèªèããããšã§æ¡åŒµã§ããŸãã å®éãå¯èœæ§ã¯ç¡éã§ãã
ãã®èšäºã®å·çæç¹ã§ã¯ãMongoDBã³ã³ãã€ã©ãŒã«é¢ããäœæ¥ã¯ãŸã å§ãŸã£ãã°ããã§ãã ã³ãŒãå€æãžã®ãã®ã¢ãããŒãã¯æéãšãšãã«å€åããããããæé©ãªãœãªã¥ãŒã·ã§ã³ãç»å Žããå¯èœæ§ãé«ããããããé¢é£æ§ã®é«ãæ å ±ãå«ãæ°ããèšäºãæžãããšãã§ããŸãã
ä»æ¥ãç§ã¯ã³ã³ãã€ã©ãŒã®äœæã«éåžžã«æ ç±ãåŸããŠããããã®ããã»ã¹ã§åŸãç¥èãä¿æããããšæã£ãŠããŸãã
ãããã¯ãããã«æ·±ãæãäžãããå Žåã¯ã以äžã®ãªãœãŒã¹ãèªãã§ãå§ãããŸãã
- ãããã»ãã€ãã«ããèšèªã®èšèª
- Niklaus Wirthã«ããã³ã³ãã€ã©æ§ç¯
- ã³ã³ãã€ã©ãŒ èè ã®ååãæè¡ãããŒã« Alfred V. AhoãMonica S. LamãRavi SetiãJeffrey D. Ullman
- Positive Technologiesã®Ivan Kochurkinã«ããããªãŒæ§é ã®åŠçãšçµ±åãããAST
- A.ã¢ããRãã»ãã£ãJããŠã«ãã³ã«ããè¬æŒãã³ã³ãã€ã©ã®åºç€ã
ãŸããèšäºã§äœ¿çšãããŠãããªãœãŒã¹ãžã®ãªã³ã¯ïŒ
- ãžã§ãŒã ãºã»ã«ã€ã«ã«ããè¶ å°åã³ã³ãã€ã©ãŒ
- Minko Gechevã«ãã25è¡ã®JavaScriptã§ã®ç°¡åãªã³ã³ãã€ã©ã®å®è£
- Peter Olsonã«ããJavaScriptã§ç°¡åãªã€ã³ã¿ãŒããªã¿ãŒãäœæããæ¹æ³
- JavaScriptã®è§£æïŒ Gabriele Tomassettiã«ããããŒã«ãšã©ã€ãã©ãª
- Gabriele Tomassettiã«ããANTLR Megaãã¥ãŒããªã¢ã«
- Ivan Khudyashovã«ããANTLR 4ã®MySQLææ³
- Ivan Kochurkinã«ããããªãŒæ§é ãšçµ±äžãããASTã®åŠç
- IANT Kochurkinã«ããANTLRãšRoslynã䜿çšãããœãŒã¹è§£æã®çè«ãšå®è·µ
- Antlr4- Saumitra Srivastavã«ãã蚪åè 察ãªã¹ããŒãã¿ãŒã³
ã³ã³ãã¹ããŒã ãç¹ã«ã³ã³ãã€ã©ã®å·çãžã®æå°ãšè²¢ç®ãããŠãããAnna Herlihy ãèšäºã®æ§é ã«é¢ããæšå¥šäºé ãããã³Oksana Nalyvaikoãžã®ã¿ã€ãã«ã€ã©ã¹ããžã®ã¬ã¿ãªã³ã°ã«ã€ããŠãã¬ãã¥ã¢ãŒã®Alex Komyagin ã Misha Tyulenevã«æè¬ããŸãã
Mediumã«é¢ããèšäºã®è±èªçïŒ ANTLRã䜿çšããJavaScriptã®ã³ã³ãã€ã©ãŒ