ã¯ããã«
質åã¯ããã®èšäºã¯æ£ç¢ºã«ã¯äœã§ããïŒ ããã§ã¯ãããã¹ã圢åŒãè§£æããå¿ èŠãããããã©ã€ãã©ãªã䜿çšã§ããªãå Žåã«ãæå€±ãæå°éã«æããŠèªè ãç¶æ³ããæãåºããããã«æ¯æŽããŸãã ã€ãŸãã絶察çãªç¹å®ã®åé¡ãäžè¬çãªææ®µã§è§£æ±ºããããšã§ãã
ããã«äºçŽããŸãããããã¯èªäœã¯éåžžã«è€éã§ããã ãã§ãªããéåžžã«äžå¯èœãªããã1ã€ã®èšäºã§ãã¹ãŠãã«ããŒããããšã¯äžå¯èœã§ãã ãããã£ãŠãç§ã¯äžè¬ããå§ããŠãå ·äœçã«ãç¹ã«ãã®èšäºã§ã¯ãæŠå¿µã«æ·±ãæãäžããã®ã§ã¯ãªããããŒã«ã®æŠèŠã瀺ããŸãïŒãã ããéåžžã«ç¹å®ã®è§£æã¿ã¹ã¯ã解決ããããã«äœ¿çšã§ããŸãïŒã ããããèªè ãèå³ãæã£ãŠãããªãããã®èšäºã¯ç¹å®ã®è³ªåãããè©³çŽ°ã«æããã«ã§ãããµã€ã¯ã«ã«å€ããã§ãããã
ãããã¯ã«é¢ããæ å ±ãæ£åšãããã°ãã°äžå®å šã§ãããããç§ã¯ãããæžãããšã«ããŸããããã·ã¢èªã«ã¯éåžžã«å°ãªãæ å ±æºããããååšããæ å ±ã¯èªè ãéåžžã«å ·äœçãªæ°åŠã«ç²ŸéããŠããããšãæå³ããŸãã ãããã£ãŠããããã¯ããé ãé¢ããèªè ã圌ã®ïŒæ³åäžã®ïŒå£çæã«èŠçãæããªãããã«ããã®ãããã¯ãã§ããã ãç°¡åã«èª¬æããããšã«ããŸããã
æ°ãã€ããŠãèšäºã¯å€§ãããããã€ãã®å Žæã¯ããŸãé¢çœããªãã§ããããããããããªããã°æç¢ºã§ã¯ãªããããããŸããã
åºæ¬çãªæŠå¿µ
ãããã¯ã«ã€ããŠè©±ãåã«ã誀解ããªãããã«åºæ¬æŠå¿µã決å®ããå¿ èŠããããŸãã ããã¯ãã®èšäºã®çšèªéã§ãã äžè¬çã«åãå ¥ããããŠããçšèªãšäžèŽããå ŽåããããŸãããäžè¬çã«èšãã°ãèè ã®é ã®äžã«åœ¢æãããŠããåçã瀺ããŠããããã矩åã§ã¯ãããŸããã
ã ããïŒ
- å ¥åæåã¹ããªãŒã ïŒä»¥éã å ¥åã¹ããªãŒã ãŸãã¯ã¹ããªãŒã ïŒ-æ§æè§£æçšã®æåã®ã¹ããªãŒã ãããŒãµãŒå ¥åã«äŸçµŠãããŸã
- ããŒãµãŒ/ããŒãµãŒ ïŒ ããŒãµãŒãã¢ãã©ã€ã¶ãŒ ïŒ-å ¥åã¹ããªãŒã ãåãå ¥ãããããASTã«å€æããããã°ã©ã ãããã³/ãŸãã¯å®è¡å¯èœé¢æ°ãææ³èŠçŽ ã«ãã€ã³ãã§ããããã«ããããã°ã©ã
- AST ïŒAbstract Syntax TreeïŒ/ ASD ïŒAbstract Syntax TreeïŒïŒ åºåããŒã¿æ§é ïŒ-è§£æãããã¹ããªãŒã ã®ææ³ãšãã®ã³ã³ããŒãã³ã端æ«ã®éçµç«¯ãšã³ãã£ãã£ã®éå±€ã衚ããªããžã§ã¯ãæ§é ã ããšãã°ã代æ°ã¹ããªãŒã ïŒ1 + 2ïŒ+ 3ã¯ãEXPRESSIONïŒEXPRESSIONïŒNUMBERïŒ1ïŒOPERATORïŒ+ïŒNUMBERïŒ2ïŒïŒOPERATORïŒ+ïŒNUMBERïŒ3ïŒïŒãšããŠè¡šãããšãã§ããŸãã ååãšããŠããã®ããªãŒã¯çµæãååŸããããã«ããŒãµãŒã¯ã©ã€ã¢ã³ãã«ãã£ãŠäœããã®åœ¢ã§åŠçãããŸãïŒããšãã°ããã®åŒã®å¿çãã«ãŠã³ãããïŒ
- CFG ïŒæèèªç±ææ³ïŒ/ KSG ïŒæèèªç±ææ³ïŒ-ããŒãµãŒã®çä¿¡æååãèšè¿°ããããã«äœ¿çšãããæãäžè¬çãªææ³ã®çš®é¡ïŒãã¡ããããã ãã§ã¯ãããŸããïŒã ã«ãŒã«ã®äœ¿çšã¯ã³ã³ããã¹ãã«äŸåããªããšããäºå®ã«ãã£ãŠç¹åŸŽä»ããããŸãïŒäœããã®æ¹æ³ã§ã³ã³ããã¹ããèšå®ããå¯èœæ§ãæé€ãããã®ã§ã¯ãããŸãããããšãã°ã颿°ãåŒã³åºãããã®ã«ãŒã«ã¯ãã³ã¡ã³ãã«ãŒã«ã§èšè¿°ãããã¹ããªãŒã ãã©ã°ã¡ã³ãå ã«ãããã©ããã¯é¢ä¿ãããŸããïŒã çµç«¯æåãšéçµç«¯æåã«å®çŸ©ããããããã¯ã·ã§ã³ã«ãŒã«ã§æ§æãããŸãã
- 端æ«èšå· ïŒ ç«¯æ« ïŒ-æå®ãããè§£æèšèªã®å Žå-çä¿¡ã¹ããªãŒã ã§çºçããå¯èœæ§ã®ãããã¹ãŠã®ïŒååïŒèšå·ã®ã»ãã
- éçµç«¯æå ïŒ çµç«¯ã§ã¯ãªã ïŒ-æå®ãããè§£æèšèªã®å Žå -å ¥åã¹ããªãŒã ã«ã¯ãªãããææ³èŠåã«åå ããŠãããã¹ãŠã®æåã®ã»ããã
- è§£æèšèª ïŒã»ãšãã©ã®å Žåã CJS ïŒ ã³ã³ããã¹ãããªãŒèšèª ïŒããããŸãïŒ-ãã¹ãŠã®ç«¯æ«èšå·ãšé端æ«èšå·ã®åèšãããã³ç¹å®ã®å ¥åã¹ããªãŒã ã®CSGã ããšãã°ãèªç¶èšèªã§ã¯ãçµç«¯èšå·ã¯èšèªã§äœ¿çšããããã¹ãŠã®æåãæ°åãå¥èªç¹ã§ãããçµç«¯èšå·ã¯åèªãæã§ã¯ãããŸããïŒãããŠãäž»èªãè¿°èªãåè©ãå¯è©ãªã©ã®ãã®ä»ã®æ§é ïŒããããææ³èªäœã¯ææ³ã§ãèšèªã
- BNF ïŒããã«ã¹-ããŠã¢åœ¢ãããã«ã¹æ£èŠåœ¢ïŒ/ BNF ïŒããã«ã¹-ããŠã¢åœ¢ïŒ-ããã€ãã®æ§æã«ããŽãªãŒãä»ã®ã«ããŽãªãŒãéããŠé 次å®çŸ©ããããã©ãŒã ã å€ãã®å ŽåãããŒãµãŒãžã®å
¥åãèšå®ããããã«çŽæ¥äœ¿çšãããCSGãã¬ãŒã³ããŒã·ã§ã³ãã©ãŒã ã 1ã€ã®éçµç«¯èšå·ãåžžã«å®çŸ©ãããŠãããšããäºå®ãç¹åŸŽã§ãã å€å
žã¯åœ¢åŒã®èšé²ã®åœ¢åŒã§ã
< > ::= <.1> | <.2> | . . . | <.n>
ABNFïŒAugmentedBNFïŒãEBNFïŒExtendedBNFïŒãªã©ãå€ãã®çš®é¡ããããŸããäžè¬ã«ããããã®åœ¢åŒã¯éåžžã®BNFã¬ã³ãŒãã®æ§æãå€å°æ¡åŒµããŸãã - LLïŒkïŒãLRïŒkïŒãSLRã...ã¯ãããŒãµãŒã¢ã«ãŽãªãºã ã®ã¿ã€ãã§ãã ãã®èšäºã§ã¯ã誰ããèå³ãæã£ãŠããå Žåããããã«ã€ããŠè©³ããã¯èª¬æããŸããã以äžã§ã¯ããããã«ã€ããŠåŠã¶ããšãã§ããè³æãžã®ãªã³ã¯ã瀺ããŸãã ãã ããããŒãµãŒã®ææ³ã«é¢ããå¥ã®åŽé¢ã«ã€ããŠè©³ãã説æããŸãã LL / LRããŒãµãŒã°ã«ãŒãã®ææ³ã¯BNFã§ããããã¯äºå®ã§ãã ãããããã¹ãŠã®BNFææ³ãLLïŒkïŒãŸãã¯LRïŒkïŒã§ããªãããšãäºå®ã§ãã ãšã«ãããLL / LRïŒkïŒã®æåkã¯ã©ãããæå³ã§ããïŒ ããã¯ãææ³ãè§£æããããã«ãæå€§kåã®çµç«¯ã·ã³ãã«ãäžæµã§å èªã¿ããå¿ èŠãããããšãæå³ããŸãã ã€ãŸããææ³ãè§£æïŒ0ïŒããã«ã¯ãçŸåšã®æåãç¥ãã ãã§æžã¿ãŸãã ïŒ1ïŒã®å Žå-çŸåšã®æåãšæ¬¡ã®1æåãç¥ãå¿ èŠããããŸãã ïŒ2ïŒ-çŸåšããã³2次ãªã© 以äžã«ãç¹å®ã®ããŒãµãŒçšã®BNFã®éžæ/ã³ã³ãã€ã«ã«ã€ããŠããå°ã話ããŸãããã
- PEG ïŒ æ§æè§£ææ§æ ïŒ/ RVææ³ -èšèªã®æååãèªèããããã«äœæãããææ³ã 代æ°çã¢ã¯ã·ã§ã³+ã-ã*ã/ã®éè² ã®æ°ã®ãã®ãããªææ³ã®äŸã¯æ¬¡ã®ãšããã§ãã
Value â [0-9]+ / '(' Expr ')'
Product â Value (('*' / '/') Value)*
Sum â Product (('+' / '-') Product)*
Expr â Sum
æåŸã«ãåºæ¬çãªæŠå¿µã«ã€ããŠèª¬æããŸããã è§£ææ¹æ³ã®éžæã«ç§»ããŸãããã
è§£æãªãã·ã§ã³
ããŒãµãŒãäœæããã¿ã¹ã¯ã«çŽé¢ãããšããœãªã¥ãŒã·ã§ã³ã¯ååãšããŠ4ã€ã®äž»ãªãªãã·ã§ã³ã«ãªããŸãã
- é¡ã®åé¡ã解決ããŸããã€ãŸããå ¥åã¹ããªãŒã ãæåããšã«åæããææ³ã®ã«ãŒã«ã䜿çšããŠãASDãæ§ç¯ããããå¿ èŠãªã³ã³ããŒãã³ãã«å¯ŸããŠå¿ èŠãªæäœãããã«å®è¡ããŸãã ãã©ã¹ã®ç¹-ãã®ãªãã·ã§ã³ã¯ãã¢ã«ãŽãªãºã ãšæ°åŠçåºç€ã®ååšã«é¢ããŠæãç°¡åã§ãã çæ-ããŒãµãŒãæ§ç¯ãããšãã«ãã¹ãŠã®ææ³èŠåãèæ ®ãããã©ããã«ã€ããŠã®æ£åŒãªåºæºããªããããå¶çºçãªãšã©ãŒã®ç¢ºçã¯æå€§ã«è¿ããªããŸãã éåžžã«æéãããããŸãã äžè¬ã«ãç¹ã«ASDã®æ§ç¯ãå®è£ ããŠããªãå Žåã¯ãç°¡åã«å€æŽã§ãããæè»æ§ãããŸããããŸããã ããŒãµãŒãé·æéåäœããŠããŠããå®å šã«æ£ããåäœããããšã確èªããããšã¯ã§ããŸããã ãã©ã¹ãšãã€ãã¹ã®ã ãã®ãªãã·ã§ã³ã§ã¯ããã¹ãŠããªãã®æã®çŽæ¥æ§ã«äŸåããŸãã ãã®ãªãã·ã§ã³ã«ã€ããŠã¯è©³ãã説æããŸããã
- æ£èŠè¡šçŸã䜿çšããŸãïŒ ããã§ã¯ãåé¡ã®æ°ãæ£èŠè¡šçŸã«ã€ããŠåè«ãèšãã€ããã¯ãããŸããããäžè¬çã«ããã®æ¹æ³ã¯æé ãªäŸ¡æ Œã§ã¯ãããŸãããããŸãè¯ããããŸããã è€éãªææ³ã®å Žåãç¹ã«ã«ãŒã«ãæé©åããŠäœæ¥é床ãäžããããšãããšãåžžé£ã§ã®äœæ¥ã¯å°çã«å€ãããŸãã äžè¬ã«ããã®æ¹æ³ãéžæããå Žåã幞éãç¥ãã ãã§ãã æ£èŠè¡šçŸã¯è§£æçšã§ã¯ãããŸããïŒ ãããŠãç§ã¯ãã®å察ã確信ããªãããã«ããŸãããã ãããã¯ãæ€çŽ¢ããã³çœ®æçšã«èšèšãããŠããŸãã ããããä»ã®ç®çã«äœ¿çšããããšãããšãå¿ ç¶çã«æå€±ãçããŸãã ãããã䜿çšããŠãåæãå€§å¹ ã«é ãããã©ã€ã³ã«æ²¿ã£ãŠäœåºŠãééãããããè³çްèã倱ããèéããææ¡è ºãé€å»ããæ¹æ³ãèŠã€ããããšããŸãã ããããããã®æ¹æ³ãåã®æ¹æ³ãšäº€å·®ãããããšããããšã§ãç¶æ³ã¯ãããã«æ¹åãããã§ãããã ãããããªãã äžè¬ã«ãå©ç¹ã¯ä»¥åã®ããŒãžã§ã³ãšã»ãŒåãã§ãã æ£èŠè¡šçŸãç¥ãå¿ èŠãããã ãã§ããããã®äœ¿ç𿹿³ãç¥ãã ãã§ãªãã䜿çšããŠãããªãã·ã§ã³ã®åäœéåºŠãææ¡ããããšããå§ãããŸãã ãã€ãã¹ã®ãã¡ã以åã®ããŒãžã§ã³ãšã»ãŒåãã§ãããæéãããããªãç¹ãç°ãªããŸãã
- 倿°ã®BNFè§£æããŒã«ã䜿çšããŸãããïŒ ãã®ãªãã·ã§ã³ã¯ãã§ã«è峿·±ããã®ã§ãã ãŸããlex-yaccãŸãã¯flex-bisonåã®ããªã¢ã³ããæäŸãããŸããæ¬¡ã«ãå€ãã®èšèªã§ãBNFãè§£æããããã®ãã€ãã£ãã©ã€ãã©ãªãèŠã€ããããšãã§ããŸãã æ€çŽ¢ããŒã¯ãŒãã«ã¯ãLLãLRãBNFã䜿çšã§ããŸãã ãã€ã³ãã¯ããããã®ãã¹ãŠãäœããã®åœ¢ã§BNFã®ããªãšãŒã·ã§ã³ãå ¥åãšããŠåãå ¥ããLLãLRãSLRãªã©ãããŒãµãŒãåäœããç¹å®ã®ã¢ã«ãŽãªãºã ã§ãããšããããšã§ãã ã»ãšãã©ã®å Žåããšã³ããŠãŒã¶ãŒã¯ã䜿çšãããã¢ã«ãŽãªãºã ã®çš®é¡ã«ç¹ã«é¢å¿ãæã¡ãŸããããææ³ã®è§£æã«ã¯äžå®ã®å¶éããããŸããïŒä»¥äžã§è©³ãã説æããŸãïŒãäœæ¥æéãç°ãªãå ŽåããããŸãïŒãã ããã»ãšãã©ãOïŒLïŒã宣èšããŸãããLã¯æåã¹ããªãŒã ã®é·ãã§ãïŒã ãã©ã¹-å®å®ããããŒã«ããããæç¢ºãªåœ¢åŒã®èšé²ïŒBNFïŒãåäœæéã®é©åãªæšå®ãããã³ã»ãšãã©ã®çŸä»£èšèªã®BNFã¬ã³ãŒãã®ååšïŒå¿ èŠã«å¿ããŠãsqlãpythonãjsonãcfgãyamlãhtmlãcsvãªã©ïŒ ãã€ãã¹é¢-ããŒã«ã®ã€ã³ã¿ãŒãã§ã€ã¹ã¯åžžã«æçœã§äŸ¿å©ã§ã¯ãªãããããªãã¿ã®ãªãèšèªã§äœããæžãå¿ èŠããããŸããããã¯ãããŸããŸãªããŒã«ã§ææ³ãçè§£ããæ©èœã§ãã
- PEGã®è§£æããŒã«ã䜿çšããŸãïŒ ããã¯è峿·±ããªãã·ã§ã³ã§ããããŸããããã«ãã©ã€ãã©ãªã¯å°ãè±å¯ã§ãããéåžžã¯ãããã«ç°ãªãæä»£ã«ãããŸãïŒPEGã¯Brian Fordã«ãã£ãŠ2004å¹Žã«ææ¡ãããŸããããBNFã®ã«ãŒãã¯1980幎代ã«äŒžã³ãŠããŸãïŒãã¢ã€ãã³ããããäž»ã«GitHubã§ç掻ããŠããŸã å©ç¹-é«éãã·ã³ãã«ãå€ãã®å Žå-ãã€ãã£ãã ãã€ãã¹ãã-å®è£ ã«åŒ·ãäŸåããŸãã 仿§ã«ããPEGã®æ²èгçãªæšå®å€ã¯OïŒexpïŒLïŒïŒã®ããã§ãïŒå¥ã®ããšããã®ãããªææ³ãäœæããããã«äžçæžåœåªåããå¿ èŠããããŸãïŒã ã©ã€ãã©ãªã®æç¡ã«å€§ããäŸåããŸãã äœããã®çç±ã§ãå€ãã®PEGã©ã€ãã©ãªã®äœæè ã¯ãããŒã¯ã³åãšæ€çŽ¢/眮ææäœãååã«æ€èšããASTã䜿çšããªãããææ³èŠçŽ ã«é¢æ°ããã€ã³ãããããšããèããŠããŸãã ããããäžè¬çã«ããã®ãããã¯ã¯ææã§ãã
è§£æã®åé¡ã解決ããŸã
ãã«ãŒããã©ãŒã¹ãšæ£èŠè¡šçŸãªãã·ã§ã³ãã¹ãããããŠãé çªã«è¡ããŸãããã
BNF
ãã®ãããããŒãµãŒã¢ã«ãŽãªãºã ããŸãã¯ãããã䜿çšããææ³ã«ã€ããŠããå°ã説æãããšããæ¥ãŸããã ãã®ãããæãäžè¬çãªã®ã¯GLRïŒæå€§OïŒL ^ 3ïŒãŸãã¯æå€§OïŒL ^ 4ïŒãäžéšã®ãœãŒã¹ã§ã¯ïŒantlrïŒïŒãLRãLALRããã³LL-ãã¹ãŠOïŒLïŒå ã§ãã GLRã«ã¯æãã倧é£ããããããŸã-ææ³ã®ãããŸãããããããåŠçã§ããŸãããããã«ããé床ãé ããªããŸãã ã€ãŸããããŒãµãŒã«ãã£ãŠåŠçãããææ³ã®ã¯ã©ã¹ã®ããµã€ãºãïŒããŒãµãŒã®ãã¯ãŒãšåŒã³ãŸãããïŒãèæ ®ããå Žåãä»ã®æ¡ä»¶ãçããå Žåããã¯ãŒã¯GLR> LR> LALR> SLR> LLã®ããã«åæ£ãããŸãã ãªãœãŒã¹æ¶è²»éã¯ãããããéã«è¿ãã§ãã ããããææ³ã«æ»ããŸãã
LRããŒãµãŒå šäœã®ææ³ãã³ã³ãã€ã«ãŸãã¯æ€çŽ¢ããããšã¯éåžžã«ç°¡åã§ããããèã®äžãã§ã³ã³ãã€ã«ããBNFãããŒãµãŒã«èœã¡çããŠåŠçãããå¯èœæ§ãé«ããªããŸãã äž»ãªããšã¯ãææ³ãå®å šã§ããããšã§ããã€ãŸããå ¥åã¹ããªãŒã ã®èãããããã¹ãŠã®ç¶æ³ãèšè¿°ããããã«ãã©ã®ã«ãŒã«ãé©çšããå¿ èŠããããïŒéžæããLRããŒãµãŒã«å¿ããŠïŒãç¥ãããšãã§ãããã©ãããèªåã§çè§£ããããšããŸãã
LRããŒãµãŒã®å Žåãæ¬¡ã®ã¿ã€ãã®ç«¶åãçºçããå¯èœæ§ããããŸãã
- Shift-reduceïŒ
NT ::= x NT | x
NT ::= x NT | x
ã ããã§ãé·ãx> kã æ¬¡ã®ããã«è§£æ±ºããNT ::= xK; K ::= K | e
NT ::= xK; K ::= K | e
- ç³ã¿èŸŒã¿ïŒreduce-reduceïŒïŒ
NT :: = e
A ::= NT
B ::= NT
D ::= B uv | A uw
NT :: = e
A ::= NT
B ::= NT
D ::= B uv | A uw
ãããã§é·ãu> k
次ã®ããã«è§£æ±ºãããŸãã
R ::= Au
J ::= Bu
D ::= Rw | Jv
LLããŒãµãŒã¯ããã©ãŒã ã®ç«¶åã«ãã£ãŠç¹åŸŽä»ããããŸãïŒããããåæ§æããã®ã«å¿ èŠã§ãããååã§ã¯ãããŸãããèŠæ±ã«å¿ããŠãLLïŒkïŒææ³ã«æ¬¡ã®èšäºã§è©³ããçŠç¹ãåœãŠãããšãã§ããŸãïŒã
å·Šååž°ïŒ
NT ::= NT x | y
NT ::= NT x | y
ïŒxãyã¯ç«¯æ«/é端æ«ã®ä»»æã®æååã§ãããyã¯NTã§å§ãŸããŸããïŒ
äŸïŒ
E ::= E + T | T
E ::= E + T | T
次ã®ããã«åå®åŒåã§ããŸãã
E ::= TZ
Z ::= '+' TZ | x
å·Šå ååè§£ïŒ
NT ::= ax | ay
NT ::= ax | ay
ãããã§aã¯ããŒãµãŒã®é·ã> kã®æååã§ãã ããã«ç°¡åã«è§£æ±ºã§ããŸã
NT ::= aC; C = x|y
NT ::= aC; C = x|y
ããã§ãç§ãã¡ã¯äœã決ããŸãã
ããŠãããã¯ç°¡åãªèšç®æ©ã ãšããŸãããïŒ
OPERATOR ::= "+ "| "-" | "*" | "/" STMT ::= "(" STMT ")" | STMT OPERATOR STMT | FLOAT | INT FLOAT ::= INT "." INT INT ::= (POSITIVE_DIGIT INT | DIGIT ) | DIGIT POSITIVE_DIGIT ::= "1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9" DIGIT ::= POSITIVE_DIGIT | "0"
èªè ãã€ã³ã¿ãŒãããã§é»åã®ææ³ãèŠã€ããããšãããšãå€ãã®å Žåãå ç®/æžç®ããã³ä¹ç®/é€ç®ã®æŒç®ãç°ãªãææ³æ§é ã«ãã£ãŠåŠçãããããšãããããŸãã ããã¯ãç¹ã«ãæäœã®åªå é äœãªã©ã®ç¬éãææ³ã§èæ ®ããããã«ïŒãŸããææ³ã®ãããŸãããæããã«ããããã«ïŒè¡ãããŸãã ããã¯èšäºã®åŸåã§è¡ããŸãã
ãã€ãã£ãPythonãœãªã¥ãŒã·ã§ã³ãèŠã€ããããšããŠããŸããããã®å€ããèŠã€ããŠããŸã ã
- parglareã䜿çšããŸã ã ããã¯ãããªãåºãç¯å²ã®æ©èœïŒã€ã³ã©ã€ã³é¢æ°ãåªå
é äœä»ããããªãŒãããããããææ³åæãææ³ã®åŠçã«ãã£ãŠåŸãããCAã®ããžã¥ã¢ã©ã€ã¶ãŒïŒãåããLR / GLRããŒãµãŒãå®è£
ããPythonã©ã€ãã©ãª/ cliããŒã«ã§ãã
pip install parglare
ããŒã°ã¬ã¢ãæ±ããããã«é»åãåå®åŒåãã
OPERATOR : "+ "| "-" | "*" | "/" | = STMT : "(" STMT ")" | STMT OPERATOR STMT | FLOAT | INT FLOAT : INT "." INT INT : (POSITIVE_DIGIT INT | DIGIT ) | DIGIT POSITIVE_DIGIT : "1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9" DIGIT : POSITIVE_DIGIT | "0"
ååã§ããïŒ calc.pgã«ä¿åããcli-toolã䜿çšããŸã
pglr --debug check calc.pg Error in file "/home/survivor/tests/calc.pg" at position 1,42 => "" | "/" | *=\nSTMT ". Expected: Name or StrTerm or RegExTerm
ãã£ãšïŒ äœãäœåãªãã®ãããããã§ãã ãã³ãŽïŒ äœããã®çç±ã§æ¿å ¥ããŸãã| =ã/ãã®åŸïŒããããç§ã¯åœŒã®åºèº«å°ãç¥ã£ãŠããŸãïŒãã ããããã¯èšäºã®ãããã¯ã«ã¯é©çšãããŸããïŒïŒã äž»ãªããšã¯ãããã°ã©ã ããããæç¢ºã«ç€ºããŠããããšã§ãã ããã«ãä¿®æ£åŸãããã°ã©ã ã¯äžåšãscããŸãã INTèŠåã®éçµç«¯èšå·ãšãã©ã±ããã®æå®ã®æåŸã åæ§æãããããŒãžã§ã³ã¯æ¬¡ã®ããã«ãªããŸãã
STMT : "(" STMT ")" | STMT OPERATOR STMT | FLOAT | INT; OPERATOR : "+ "| "-" | "*" | "/"; FLOAT : INT "." INT; INT : POSITIVE_DIGIT INT | POSITIVE_DIGIT DIGIT | DIGIT; POSITIVE_DIGIT : "1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"; DIGIT : POSITIVE_DIGIT | "0";
ãã®çµæãpglrã¯ãã¹ãŠãæ°ã«å ¥ã£ãŠãããæ¬¡ã®ããã«äŒããŸãã
Grammar ok!
ãããïŒ
There are 4 Shift/Reduce conflicts. Either use 'prefer_shifts' parser mode, try to resolve manually or use GLR parsing. There are 7 Reduce/Reduce conflicts. Try to resolve manually or use GLR parsing.
ããŠããããã°åºåã®äžã«ããããã®çŸããïŒãããŠçè§£ã§ããïŒèª¬æãèªãããšãã§ããŸãã ããã§ã¯ãèããŠã¿ãŸãããã ãŸããæãè³¢ããªããpositive_digitãæšãŠãŸãããã 0034誰ãã0034ãæžããå Žå-第äžã«ã圌ã¯èªåèªèº«ãéªæªãªããããªã§ããã第äºã«ãPythonãå«ãã»ãšãã©ã®PLã¯ãããæ°å€ã«å€æããéã«äœãèšãããåã«34ãäžããŸããããã§å€§äžå€«ã§ãã æ¬¡ã«ãããããint / floatã®åé¢ãåç §ããŠãã ãããç°¡åã«ããããã«ããã¹ãŠã®æµ®åå°æ°ç¹æ°ãæ³å®ããŠããŸãã ãŸããpglrã¯BNFã®æ£èŠè¡šçŸãçè§£ããŠããŸãããããå©çšããŸãããã ååŸãããã®ïŒ
STMT : "(" STMT ")" | STMT OPERATOR STMT | FLOAT; OPERATOR : "+ "| "-" | "*" | "/"; FLOAT : /\d+(\.\d+)?/;
ãããŠãŸã
There are 4 Shift/Reduce conflicts. Either use 'prefer_shifts' parser mode, try to resolve manually or use GLR parsing.
ãŸããããã¯ãããããããªããææ³
*** GRAMMAR *** Terminals: + EOF ) ( FLOAT STOP * / - \d+(\.\d+)? EMPTY NonTerminals: OPERATOR S' STMT Productions: 0: S' = STMT STOP 1: STMT = STMT OPERATOR STMT 2: STMT = ( STMT ) 3: STMT = FLOAT 4: OPERATOR = + 5: OPERATOR = - 6: OPERATOR = * 7: OPERATOR = /
æ¬åœã«äœããè§£æããŠã¿ãŸãããã
from parglare import Grammar from parglare import Parser grammar = Grammar.from_file('calc.pg') parser = Parser(grammar, build_tree=True, prefer_shifts=True) result = parser.parse('1 + 2 / (3 - 1 + 5)')
ååŸãããã®ïŒ
result <NonTerm(start=0, end=19, sym=STMT)>
ããªãŒã§result.childrenãååŸã§ããŸãã åæã«æçµåŒãèšç®ããããšãã§ããŸãããããã§ã¯è¡ããŸããã ãªããžã§ã¯ãã®ããªãŒã«ã¢ã¯ã»ã¹ã§ããããšãéèŠã§ããçµç«¯èšå·ã«ã€ããŠã¯ããããã®ãæå³ããå¯èœã§ãããããã§äœã§ãã§ããŸãã
ç«¶åç¶æ³ãä¿®æ£ãããå Žåãææ³ç«¶åã¯ä»ã«ã©ã®ããã«è§£æ±ºã§ããŸããïŒ
ããã€ãã®ãªãã·ã§ã³ããããŸãïŒ
- ææ³ãäœãçŽããŠåé¡ã解決ãã
ããšãã°ã次ã®ããã«ïŒ
STMT : TERM | STMT ADDOP TERM ; TERM : FACTOR | FACTOR MULOP FACTOR ; FACTOR : "(" STMT ")" | NUMBER; ADDOP : "+" | "-"; MULOP : "*"|"/"; NUMBER: /\d+(\.\d+)?/;
ã芧ã®ãšãããã¿ã¹ã¯ã¯è€éã§ãããããã»ã©è€éã§ã¯ãããŸããã ããã«ããã®ãããªããªãŒãæ£ç¢ºã«åæããã°ãç°¡åã«ãªããŸãã - parglareèªäœã®ããŒã«ã䜿çšãã
ãã®å Žåã解決çã¯ããå ·äœçã§ãããå Žåã«ãã£ãŠã¯ãã䟿å©ã§ãã Parglareã¯ãã«ãŒã«ã®åªå é äœä»ãã«é©ããããŒã«ããããæäŸããŸããããšãã°ãç®è¡åŒã§ã¯ãæäœã®åªå 床ãšçµåæ§ïŒæäœãå®è¡ãããåŽ-å·Šããå³ãŸãã¯å³ããå·ŠïŒãåªå 床ãé«ãã»ã©ãæäœã¯ïŒä»ã«å¯ŸããŠïŒæ©ãå®è¡ãããŸããã®ãããªè¡šèšã®ææ³ã¯æ¬¡ã®ããã«ãªããŸãã
STMT : STMT ADDOP STMT {1, left} | STMT MULOP STMT {2, left} | "(" STMT ")" | NUMBER; ADDOP : "+" | "-"; MULOP : "*"|"/"; NUMBER: /\d+(\.\d+)?/;
è§£æãããŸããããæ£ããæ©èœããŠããŸããã ããšãã°ã
1 + 2 / (3 - 1 + 5)
getïŒéããªãŒè§£æã䜿çšïŒ
['1', u'+', ['2', u'/', [u'(', ['3', u'-', ['1', u'+', '5']], u')']]]
ããã¯æããã«ãäºæ³ãããçµæãšäžèŽããŸããã
['1', u'+', ['2', u'/', [u'(', [['3', u'-', '1'], u'+', '5'], u')']]]
é埳-BNFã«èšè¿°ãããŠããæšæºãã€ã³ãã䜿çšããããšããå§ãããŸãã è¯éºã§ã¯ãŒã«ãªãã®ã¯èŒããŠã¯ãŒã«ã§ãããåžžã«æ©èœãããšã¯éããŸããã ãŸãã¯ç§ã¯ãããã調çããæ¹æ³ãç¥ããŸããã ã»ãšãã©ã®è§£æã©ã€ãã©ãª-ããŒãžã§ã³alphaããããŸã| ããŒã¿çã
ãã®ãã°ã«ã€ããŠã®èè ã«ãããšãæ¬è³ªçã«ãã¢ã«ãŽãªãºã ã¬ãã«ã§ã®å·ŠããŒãµãŒã®çµåæ§ã¯ãã·ããã§ã¯ãªãçž®å°ãåªå ããããšãæå³ãããšããäºå®ã«ããçºçããŸãã ã€ãŸããå®éã«ã¯ãã«ãŒã«ããåãèœãšããããšãã§ããå ŽåããŸãã¯ãã®ãã¬ãŒã ã¯ãŒã¯å ã§ç¶è¡ã§ããå Žåãåãèœãšãããšããå§ãããŸãã è§£æã¯å·Šããå³ã«è¡ããããããããã¯å·Šçµåæ§ãæå³ããŸãã ãšã©ãŒã®çç±ã¯ãADDOP / MULOPå ã®ã«ãŒã«ã®åªå 床ãå®çŸ©ãããŠããªãããã«ãã«ãŒã«å šäœãç ŽãããŠããããã§ãã
ãã ããåªå 床ãèšå®ããŠãïŒããšãã°ïŒ
ADDOP: â+â {1}
| â-â {1}
ADDOP: â+â {1}
| â-â {1}
ïŒãå¥ã®ãšã©ãŒãåå ã§åäœããŸããã
æåŸã«ãparglareããã¥ã¡ã³ããŒã·ã§ã³ã®ã«ãŒã«ã«çŽæ¥ãã€ã³ããããã€ã³ã©ã€ã³é¢æ°ã®äŸã
from parglare import Parser, Grammar grammar = r""" E: E '+' E {left, 1} | E '-' E {left, 1} | E '*' E {left, 2} | E '/' E {left, 2} | E '^' E {right, 3} | '(' E ')' | number; number: /\d+(\.\d+)?/; """ # Define inline functions bound to grammar rule actions = { "E": [lambda _, nodes: nodes[0] + nodes[2], # for rule[0] â+â lambda _, nodes: nodes[0] - nodes[2], # for rule[1] â-â lambda _, nodes: nodes[0] * nodes[2], # for rule[2] â*â lambda _, nodes: nodes[0] / nodes[2], # for rule[3] â/â lambda _, nodes: nodes[0] ** nodes[2], # for rule[4] â^â lambda _, nodes: nodes[1], # for rule[5] â()â - just get the middle lambda _, nodes: nodes[0]], # for rule[6] just get node "number": lambda _, value: float(value), # for rule - convert to float } g = Grammar.from_string(grammar) parser = Parser(g, debug=True, actions=actions) result = parser.parse("34 + 4.6 / 2 * 4^2^2 + 78") print("Result = ", result) # Output # -- Debuging/tracing output with detailed info about grammar, productions, # -- terminals and nonterminals, DFA states, parsing progress, # -- and at the end of the output: # Result = 700.8
- ææ³ãäœãçŽããŠåé¡ã解決ãã
- 次ã«ãANTLRã¹ã¿ã³ãã¢ãã³ããŒã«ã詊ããŠãã ããã
ã€ã³ã¹ããŒã«ã¯éåžžã«ç°¡åã§ããLinuxã®å Žåã¯
$ 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'
python2ã§äœæ¥ããã«ã¯ããŸã ã€ã³ã¹ããŒã«ããå¿ èŠããããŸã
pip install antlr4-python2-runtime
次ã«ã圌ã®ããã«ææ³ãäœã£ãŠã¿ãŠãã ããã 圢åŒãå°ãç°ãªããããäºéåŒçšç¬ŠãäžéåŒçšç¬Šã«çœ®ãæããæ£èŠè¡šçŸããããã«æžãæããWSã®è¡šèšã远å ããŸããããã¯ã以åã®ããŒã«ã§ããã©ã«ãã§èšå®ãããŠããŸããã ç§ãã¡ã®å Žåã®å·Šã®ååž°ã¯ãå³ã«æžãçŽãã ãã§é€å»ã§ããŸãã
éèŠãªãã€ã³ãïŒ ANTLRã«ã¯ããŒãµãŒã«ãŒã«ãšææ³ã«ãŒã«ããããŸãã è§£æã«ãŒã«ã«ãããçµæã®ASTã«ããŒãã衚瀺ãããŸãã ããã«ãææ³/æ§æè§£æã®ã«ãŒã«ã§å¯èœãª/äžå¯èœãªéãããããŸãã ç¹ã«ãè§£æã«ãŒã«ã«ã¯æ£èŠè¡šçŸã¯ãããŸããã ããã«ãããŒãµãŒã¯å ¥åã«ãŒã«ãéå§éã¿ãŒããã«ãåä¿¡ããå¿ èŠããããŸãïŒäžè¬ã«ããã¹ãŠã¯å€å°è€éã§ããããã®å Žåã¯ããã§ååã§ãïŒã äžè¬ã«ãANTLRã«ã¯ããªã匷åãªæ§æããããã€ã³ã©ã€ã³é¢æ°ïŒãããã«ç°ãªã圢åŒã§ã¯ãããŸããïŒããã³éçµç«¯ã®éçµç«¯èšå·ãªã©ããµããŒãããŠããããšã«æ³šæããŠãã ããã ãã®çµæãææ³ã¯æ¬¡ã®ããã«ãªããŸãã
grammar calc; stmt : term | term addop stmt ; term : factor | factor mulop factor ; factor : '(' stmt ')' | NUMBER; addop : '+' | '-'; mulop : '*'|'/'; NUMBER: [0-9]+|[0-9]+.[0-9]+; WS : [ \t\r\n]+ -> skip ;
ãã¡ã€ã«ã¯calc.g4ãšåŒã°ããŸãïŒããã¯éèŠã§ãïŒãã¡ã€ã«åã¯å éšã®ææ³ã®ååãšäžèŽããå¿ èŠããããŸãïŒã
JavaããŒãµãŒãäœæããŸãã
antlr4 calc.g4 javac calc*.java grun calc stmt -gui
次ã«ãäœããã®å ¥åïŒããšãã°ã1 + 2 / (3 - 1 + 5)
ïŒãäžããè¡ã®çµããïŒ* nixã®å Žåã¯ctrl-z
ctrl-d
ããŠã£ã³ããŠã®å Žåã¯ctrl-z
ïŒãæŒããŠãçµæã確èªããŸãã ã€ã³ã¿ã©ã¯ãã£ããªçŸããæ§æè§£æããªãŒã衚瀺ãããŸããã èŠããããŒããããããèãããç»åãšããŠãšã¯ã¹ããŒãããããšãã§ããŸãã
python2ããŒãµãŒãäœæããŸãã
antlr4 -Dlanguage=Python2 calc.g4
ããã«ããªã¹ããŒãææ³ã«çžãä»ããŠæ¥œããããšãã§ããŸãã
import sys from antlr4 import * from calc_bakLexer import calc_bakLexer from calc_bakListener import calc_bakListener from calc_bakParser import calc_bakParser class StmtPrinter(calc_bakListener): def __init__(self): self.map_results = {} self.result = 0 def exitStmt(self, ctx): print("Oh, a stmt! {}".format(ctx.getText())) def main(argv): input = FileStream(argv[1]) print(input) lexer = calc_bakLexer(input) stream = CommonTokenStream(lexer) parser = calc_bakParser(stream) tree = parser.stmt() printer = StmtPrinter() walker = ParseTreeWalker() walker.walk(printer, tree) if __name__ == '__main__': main(sys.argv)
...誀åäœããããã°ã©ã ããæ¥œãã¿ãã ããã ããæ£ç¢ºã«ãæ£ç¢ºã«ããããäºæ³å€ã«ã
python ./calc_antlr_min.py ./example.antlr 1 + 2 / (3 - 1 + 5) Oh, a stmt! 5 Oh, a stmt! 1+5 Oh, a stmt! 3-1+5 Oh, a stmt! 2/(3-1+5) Oh, a stmt! 1+2/(3-1+5)
ã芧ã®ãšãããããã§ã¯çµåæ§ããæ£ãããã§ãã ãããŠãå æžç®ãä¹ç®é€ç®ã®æäœ-å·Šã ç§ã¯æ£çŽã«æ°æ¥é詊ããŸããïŒåæã®ãŸãŸïŒïŒè§£æ±ºçãèŠã€ããããã«ïŒãã¡ãããç§ã¯ããããã€ãããŸããã§ããããåèšã§12-15æéãæ®ºããŸããïŒã é¢é£æ§ã®ããŒã«ãŒãããã¥ã¢ã«ã®å±±ãææ³ã®åå®åŒå.... ããŸããããŸããã§ããã 解決çããããšç¢ºä¿¡ããŠããŸãã ãŸããææ³èšç®æ©ã®äŸã¯ãã¡ãã§ãã ããããå¯èœã§ããã°ãäžè¬çãªææ³ã®èгç¹ãã解決çãèŠã€ãããã£ãã®ã§ãã æçµçã«ãç®æšã¯åé¡ã解決ããããšã§ã¯ãªããåŠç¿ããããšã§ããã
ãããŠãç§ã®å€±æãèªããŸãã ã¯ããåé¡ã¯è§£æ±ºäžã§ãã ããããããã¥ã¡ã³ãã ãã䜿çšããŠãäžè¬çãªãããã¯ãæ€çŽ¢ããŠãã解決ã§ããŸããã§ããã çç±...æåã«ãANTLRã®æ¬ãé€ããŠããããã¯ãŒã¯äžã§å©çšå¯èœãªãœãŒã¹ã¯è©³çްãšè¡šçŸåã«éãã¯ãããŸããã 第äºã«ããããã¯ãŒã¯ã«ã¯ãç°ãªãïŒäºææ§ã®ãªãïŒããŒãžã§ã³ã®ANTLRã«é¢ããè³æããã£ã±ãã§ãã ããããéçºãªã©ãã¹ãŠãçè§£ããŠããŸãã ããããäœããã®çç±ã§ã楜åšãç¥ãéçšã§ãèè ã¯åŸæ¹äºææ§ã®æŠå¿µãèããããšããªããšæããŠããŸããã äžè¬çã«ãæ²ããã§ãã
æŽæ°ãã
æ£ããææãããŠããããã«ã1ã€ã®ããããåªããŠããã2ã€ã®ããããåªããŠããŸãã
å³ããå·Šãžã®ææ³ã®åå®åŒåã¯ãæåéããæã®ã¯ãªãã¯ãã§å®è¡ãããŸãïŒè¿œå ããŠãããValentin Nechayevã®netch80ã«æè¬ããŸãïŒ-亀æããã ãã§ã
stmt : term | term addop stmt ;
ã«
stmt : term | stmt addop term ;
ãã®å ŽåãANTLRã¯ïŒæããã«æé©åã®ããã«ïŒè³ªåãªãã§å·Šååž°ãåŠçããŸãã ãã®å Žåã®åçŽãªãªã¹ããŒã®çµè«
python ./calc_antlr_min.py ./example.antlr 1 + 2 / (3 - 1 + 5) Oh, a stmt! 1 Oh, a stmt! 3 Oh, a stmt! 3-1 Oh, a stmt! 3-1+5 Oh, a stmt! 1+2/(3-1+5)
ãã°
å®éããããã¯BNFã®åçŽåããã圢åŒã§ãããããã°ã©ããŒã¯äžè¬ã«ããã«ã€ããŠç¥ãå¿ èŠã¯ãããŸããã BNFãšã¯ç°ãªããæåã¯æ£èŠè¡šçŸã«äŒŒãŠããŸãã å®éãããã¯ãæšæºã«åŸã£ãŠãæ£èŠè¡šçŸã䜿çšã§ããBNFã§ãããšèšãããšãã§ããŸãïŒãŸããéçµç«¯æååã®å éšã ãã§ãªãã衚çŸèªäœã§ãããçšåºŠè¯ãïŒPEGã¯
A = B ( XC)*
,
Z = R (K)?
, âA B X C, â âZ R K 0 1 â). , , . , PEG , . BNFãå«ãããŒãµãŒïŒéžæã®ææ§ãïŒãã®åé¡ã解決ããããã«ãPEGã«ã¯çŽ æŽãããã·ãªã¢ã«ãŸãã¯ã/ãæŒç®åããããŸããåçã®ä»£æ¿ã説æããæŒç®åã|ããšã¯ç°ãªããã/ãã¯ã«ãŒã«ã解決ãããé åºãæç¢ºã«ç€ºããŸããããšãã°ã
A / B / C / D
Aãšæ¯èŒããé©åã§ãªãå Žåã¯Bãšæ¯èŒããé©åã§ãªãå Žåã¯Cãšæ¯èŒãããªã©ã瀺ããŸãããã®ãããPEGææ³ã®æäœã¯ç°¡åã§ãããŸããæšå¥šäºé -æ¯èŒã®é åºã«ç¡é¢å¿ã§ãªãå Žåã¯ãã/ããšæžãããšããå§ãããŸããããã«ãããããŒãµãŒã«ãšã£ãŠãããŸããªç¶æ³ã®æ°ãæžããŸãããã ããä»ã®ããŒã«ãšåæ§ã«ãããã¯æ³šæããŠåŠçããå¿ èŠããããŸãã
ãŸããæ³šæããŠãã ãããPEGããŒãµãŒã®äœæè ã¯ãæšæºãå¿ èŠãªæ¹æ³ã§çè§£ããåŸåãããã«åŒ·ããããããŸããŸãªå®è£ ã®èªåœã¯å€§ããç°ãªãå¯èœæ§ããããŸãã
ããã§ã¯ãç·Žç¿ã«ç§»ããŸããããèè parglareã®ã¢ã«ããžãª
ã䜿çšããŸãã
pip install arpeggio
次ã«ãããã¥ã¡ã³ããèŠãŠããã®ã©ã€ãã©ãªã®ASTã§ã®äœæ¥ã«æšå¥šãããããžã¿ãŒãã³ãã¬ãŒãããANTLRã§æšå¥šããããªã¹ããŒã«éåžžã«äŒŒãŠããããšã確èªããŸãã幞ããªããšã«ãããã§ã¯å®éšå šäœã«ååãªæéãè²»ãããŸãããããã¹ãŠãé£ãããªãããšãããããŸããã
from arpeggio.cleanpeg import ParserPEG from arpeggio import PTNodeVisitor, EOF, visit_parse_tree # Setting up our simple grammar calc_grammar = """ number = r'\d+(\.\d+)?' factor = number / "(" stmt ")" term = factor (mulop factor)* stmt = term (addop term)* addop = "+" / "-" mulop = "*" / "/" calc = stmt EOF """ #Creating a visitor class to calculate the result class CalcVisitor(PTNodeVisitor): def visit_number(self, node, children): return float(node.value) def visit_factor(self, node, children): # Children are list-like structure of VISITED node results # visits are made from depth to top return children[0] def visit_term(self, node, children): # For such rules you may use, for example children["factor"] # Though, you need to know, that children["factor"] is a list of ALL # factor's of this term if len(children) == 1: return children[0] else: res = children[0] for i in xrange(len(children) / 2): if children[2 * i + 1] == '*': res *= children[2 * (i + 1)] else: res /= children[2 * (i + 1)] return res def visit_stmt(self, node, children): if len(children) == 1: return children[0] else: res = children[0] for i in xrange(len(children) / 2): if children[2 * i + 1] == '+': res += children[2 * (i + 1)] else: res -= children[2 * (i + 1)] return res # Don't forget about root rule for your parser, as it will be produced as # a parsing result parser = ParserPEG(calc_grammar, "calc") input_expr = "(4-1)*5+(2+4.67)+5.89/(1.2+7)" print(input_expr) parse_tree = parser.parse(input_expr) result = visit_parse_tree(parse_tree, CalcVisitor( #debug=True )) print(result) input_expr = "1 + 2 / (3 - 1 + 5)" print(input_expr) parse_tree = parser.parse(input_expr) result = visit_parse_tree(parse_tree, CalcVisitor( #debug=True )) print(result)
èµ·åæã«ã次ã衚瀺ãããŸãã
python ./calc_arpeggio.py (4-1)*5+(2+4.67)+5.89/(1.2+7) 22.3882926829 1 + 2 / (3 - 1 + 5) 1.28571428571
ããžã¿ãŒãããªãŒãã©ã®ããã«æ©ãåããã確èªãããå Žåã¯ããããã°ã®ã³ã¡ã³ããå€ãããšãã§ã
ãŸããç¹ã«ãstmtã«ãŒã«ãštermã«ãŒã«ã«æ³šæãæããšããããã«ä»»æã®æ°ã®èŠçŽ ãããããšãæããã«ãªããŸãããããã£ãŠãããã«ãããæ°åŠçæäœã®é£æ³æ§ã®åŠçã¯å®å šã«å®å šã«ç§ãã¡ã®è¯å¿ã«ããã£ãŠããŸãããããã®å€æŽã«ãããããããããã°ã©ã ã¯ã·ã³ãã«ã§ç°¡åã§ãã
äžè¬çãªçµè«
å®éãããã€ãã®çµè«ããããŸãã
- , . , , , . , . â . , .
- . , , .
- . , , . , - , - (- js, python, lua ruby â ). , â stand-alone â, .
- () . â:â â=â BNF, . . , 20. - , , . . , âŠ
- , ââ . , .
- , , C (, Bison), â â. , , ( , â ). , â . , .
ãããã«
çµè«ãšããŠãããã¯è峿·±ãç ç©¶ã§ãã£ããšèšãããã§ããç§ã¯èªåã®çºèŠãå¯èœãªéãã·ã³ãã«ã§çè§£ãããããã®ã«ããããšããŸããããæ¢åã®ããŒã«ã䜿çšããã®ã«ååãªäžè¬çãªçšèªã§ãã£ãŠããæ°åŠããé ãé¢ããããã°ã©ããŒã§ããããã¯ãæç¢ºã«ãªãããã«ãã®èšäºãæžãããšãã§ãããšæããŸãã
質åãããããšãã§ããŸãããããã¯ã«é¢ãã詳现ã®å€ããè奮ããå Žåã¯ãä»ã®èšäºãæžãã®ã«åœ¹ç«ã¡ãŸãã
çŽæã©ãããèšäºã®ãããã¯ã«é¢ããããã€ãã®äŸ¿å©ãªãªã³ã¯ïŒ
- è±èªã§ãŠã£ãããã£ã¢ïŒãã·ã¢ã¯ã¯ããã«å°ããèšäºã§ãïŒïŒ
CFG
BNF
LL
LR
PEGã®ã - ãæ°åŠçãªèæ¯ã®ãªãã人ã®ããã«ããã£ãšçå£ã«èªãå¿ èŠããã人ã¯ãAãAxoãJãUllmanããæ§æåæã翻蚳ãç·šéã®çè«ãã®æ¬ããå§ãããŸããããšãã°ãããã«ãããŸããå¿ èŠã«å¿ããŠããã·ã¢èªã®ç¿»èš³ã§ã¯éåžžã«ç°¡åã§ãã