基于Racket Brag的RifL解析器内存超限问题求助
RifL语言解析器内存超限问题求助
背景
我参考《Beautiful Racket》教程开发了自研小众编程语言RifL,目前已完成99%的开发工作。测试时发现,当RifL程序规模足够大时,运行会变慢甚至因内存耗尽崩溃,已定位问题出在基于brag构建的解析器上。
原始解析器语法
#lang brag RifL-program: \[convert-to-deck\] (/NEWLINE \[convert-to-deck\])\* convert-to-deck: convert-to-name /DIVIDER convert-to-stack convert-to-name: ((S-PIP-CARD \[/COMMA\])\* S-PIP-CARD) | ((C-PIP-CARD \[/COMMA\])\* C-PIP-CARD) | ((H-PIP-CARD \[/COMMA\])\* H-PIP-CARD) | ((D-PIP-CARD \[/COMMA\])\* D-PIP-CARD) convert-to-stack: (entry\* /NEWLINE)\* entry\* entry: (S-PIP-CARD | C-PIP-CARD | H-PIP-CARD | D-PIP-CARD| ROYAL-CARD | JOKER | FACE-DOWN) \[/COMMA\]
问题隔离测试
我简化了运行流程,准备了包含分词器、词法分析器、解析器和测试文件的最小复现环境。在128MB内存限制下,第一个小测试示例解析成功,但第二个规模较大的示例触发内存超限。
即使将解析器简化为如下极简语法,内存超限问题依然存在:
RifL-program: [anything] (/NEWLINE [anything])* @anything: (S-PIP-CARD | C-PIP-CARD | H-PIP-CARD | D-PIP-CARD| ROYAL-CARD | JOKER | FACE-DOWN | /COMMA | /NEWLINE | /DIVIDER)*
求助问题
- 是否是我使用brag的方式有误?
- 问题是否出在分词器或词法分析器?
- 若并非我的问题,brag是否存在缺陷?
- 若需替换brag,有无无需重构整个执行器、不用从头构建解析器的替代方案?
另外,特别希望Matthew Butterick或Greg Hendershott能看到这个问题,帮我避免从头编写完整解析器。
内容的提问来源于stack exchange,提问作者Jesse Hamlin-Navias
相关产品推荐
相关产品推荐

