我一直在用Java创建一个简单的解析器组合库,并且我第一次尝试使用程序结构来定义标记和解析器语法,见下文:
final Combinator c2 = new CombinatorBuilder()
/*
.addParser("SEXPRESSION", of(Option.of(new Terminal("LPAREN"), zeroOrMore(new ParserPlaceholder("EXPRESSION")), new Terminal("RPAREN"))))
.addParser("QEXPRESSION", of(Option.of(new Terminal("LBRACE"), zeroOrMore(new ParserPlaceholder("EXPRESSION")), new Terminal("RBRACE"))))
*/
.addParser("SEXPRESSION", of(Option.of(new Terminal("LPAREN"), new ParserPlaceholder("EXPRESSION"), new Terminal("RPAREN"))))
.addParser("QEXPRESSION", of(Option.of(new Terminal("LBRACE"), new ParserPlaceholder("EXPRESSION"), new Terminal("RBRACE"))))
.addParser("EXPRESSION", of(
Option.of(new Terminal("NUMBER")),
Option.of(new Terminal("SYMBOL")),
Option.of(new Terminal("STRING")),
Option.of(new Terminal("COMMENT")),
Option.of(new ParserPlaceholder("SEXPRESSION")),
Option.of(new ParserPlaceholder("QEXPRESSION"))
)).build()
如果我使用builer定义第一个Parser“SEXPRESSION”,我可以解释结构:
addParser的参数:
ImmutableList
的{{1}} Option
醇>
Option.of的参数:
Element
个数组,其中每个元素都是Terminal
或ParserPlaceholder
,后来替换名称匹配的实际Parser
。这个想法是能够从另一个引用一个Parser
,从而表达更复杂的语法。
我遇到的问题是,在解析RPAREN')'作为“SEXPRESSIONS”和“表达“解析者有一个或多个”基数。
我确信我可以发挥创意并想出一些限制递归调用深度的方法,也许是通过确保当“SEXPRESSION”解析器切换到“EXPRESSION”解析器然后将其移交给“SEXPRESSION”解析器,没有令牌,然后辍学?但如果存在标准解决方案,我不想要一个hacky解决方案。
有什么想法吗?
由于
答案 0 :(得分:1)
不要回答这个问题,但我不认为使用VM参数调用应用程序来增加堆栈大小有任何问题。
这可以通过添加标志-XssNm
在Java中完成,其中N
是调用应用程序的内存量。
默认的Java堆栈大小是512 KB
,坦率地说,几乎没有任何内存。除了次要的优化之外,我觉得使用那个小内存来实现复杂的递归解决方案是困难的,尤其是因为Java在递归方面的效率最低。
所以,这个标志的一些例子,如下:
-Xss4M
4 MB -Xss2G
2 GB 在您调用java
启动应用程序之后,或者如果您使用的是Eclipse之类的IDE,您可以进入并在运行配置中手动设置命令行参数。
希望这有帮助!