简体   繁体   English

解析器组合器中的递归堆栈空间不足

[英]Recursion in parser combinator running out of stack space

I've been creating a simple parser combinator library in Java and for a first attempt I'm using programatic strcutures to define both the tokens and the parser grammar, see below: 我一直在用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()

If I take the first Parser "SEXPRESSION" defined using the builer I can explain the structure: 如果我使用构造器定义的第一个解析器“ SEXPRESSION”,我可以解释其结构:

Parameters to addParser: 要添加参数的参数:

  1. Name of parser 解析器名称
  2. an ImmutableList of disjunctive Option s ImmutableListOptionImmutableList

Parameters to Option.of: Option.of的参数:

  1. An array of Element s where each element is either a Terminal , or a ParserPlaceholder which is later substituted for the actual Parser where the names match. 一个Element数组,其中每个元素都是一个Terminal或一个ParserPlaceholder ,稍后将替换名称匹配的实际Parser

The idea is to be able to reference one Parser from another and thus have more complex grammars expressed. 这个想法是要能够从另一个Parser引用一个Parser ,从而表达更复杂的语法。

The problem I'm having is that using the grammar above to parse a string value such as "(+ 1 2)" gets stuck in an infinite recursive call when parsing the RPAREN ')' as the "SEXPRESSIONS" and "EXPRESSION" Parsers have "one or many" cardinaltiy. 我遇到的问题是,当使用RPAREN')'解析为“ SEXPRESSIONS”和“ EXPRESSION”解析器时,使用上面的语法来解析诸如“(+ 1 2)”这样的字符串值会陷入无限递归调用中具有“一个或多个”基数。

I'm sure I could get creative and come up with some way of limiting the depth of the recursive calls, perhaps by ensuring that when the "SEXPRESSION" parser hands off to the "EXPRESSION" parser which then hands off to the "SEXPRESSION" parser, and no token are taken, then drop out? 我敢肯定,我可以发挥创意,并提出某种方法来限制递归调用的深度,方法可能是确保当“ SEXPRESSION”解析器移交给“ EXPRESSION”解析器时,再将其移交给“ SEXPRESSION”解析器,并且没有令牌,然后退出? But I don't want a hacky solution if a standard solution exists. 但是我不希望有一个标准的解决方案。

Any ideas? 有任何想法吗?

Thanks 谢谢

Not to dodge the question, but I don't think there's anything wrong with calling an application using VM arguments to increase stack size. 不要回避这个问题,但是我认为使用VM参数来增加堆栈大小调用应用程序没有任何问题。

This can be done in Java by adding the flag -XssNm where N is the amount of memory the application is called with. 在Java中,可以通过添加标志-XssNm来完成此操作,其中N是调用应用程序所使用的内存量。

The default Java stack size is 512 KB which, frankly, is hardly any memory at all. 默认的Java堆栈大小为512 KB ,坦率地说,几乎没有任何内存。 Minor optimizations aside, I felt that it was difficult, if not impossible to work with that little memory to implement complex recursive solutions, especially because Java isn't the least bit efficient when it comes to recursion. 除了次要的优化之外,我觉得很难,甚至不可能用很少的内存来实现复杂的递归解决方案,尤其是因为Java在递归方面的效率不是最低。

So, some examples of this flag, as as follows: 因此,此标志的一些示例如下:

  • -Xss4M 4 MB -Xss4M 4 MB
  • -Xss2G 2 GB -Xss2G 2 GB

It also goes right after you call java to launch the application, or if you are using an IDE like Eclipse, you can go in and manually set the command line arguments in run configurations. 在调用java启动应用程序之后,或者在使用诸如Eclipse之类的IDE时,它也可以正常运行,您可以进入并在运行配置中手动设置命令行参数。

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM