当解析器花费太长时间时如何设置超时?

发布于 2025-01-09 21:58:33 字数 688 浏览 1 评论 0原文

我在 C# 中使用 ANTLR4 和以下代码示例:

    AntlrInputStream antlrStream = new AntlrInputStream(text);
    MyLexer myLexer = new(new AntlrInputStream());
    myLexer.SetInputStream(antlrStream);
    CommonTokenStream myTokens = new CommonTokenStream(myLexer);
    parser = new MyParser(myTokens)
     {
       BuildParseTree = true,
     };
    IParseTree tree = parser.startRule();

MyLexer/MyParser 派生自类 Lexer/Parser< Anlr4.Runtime 的 /code> 由 ANTLR4 自动生成。

在极少数情况下,对于特定的文本,startRule() 会永远持续下去,并且永远不会结束。我希望能够为解析设置某种“超时”并抛出异常。

有什么建议推荐的方法是什么?

I'm using ANTLR4 in C# with the following code sample:

    AntlrInputStream antlrStream = new AntlrInputStream(text);
    MyLexer myLexer = new(new AntlrInputStream());
    myLexer.SetInputStream(antlrStream);
    CommonTokenStream myTokens = new CommonTokenStream(myLexer);
    parser = new MyParser(myTokens)
     {
       BuildParseTree = true,
     };
    IParseTree tree = parser.startRule();

Class MyLexer/MyParser are derived from the classes Lexer/Parser of Anlr4.Runtime and were auto generated by ANTLR4.

In some rare cases, with specific text, startRule() takes forever and never finishes. I want to be able to set some kind of a "Timeout" for the parsing and throw an Exception.

Any advice what is the recommended way to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谈下烟灰 2025-01-16 21:58:33

前阵子我暂时看了这个。您本质上可以在生成的解析器上创建一个包装器并重写其中一种方法。我将 ANTLR 与 Kotlin 一起使用,所以请原谅下面的示例。

class InterruptibleParser : YourParser() {

  override fun enterRule() {
    if (Thread.interrupted()) {
        throw InterruptedException()
    }
    return super.enterRule()
  }
}

我尝试使用 enterRuleconsumegetContext ——我不记得哪个函数被足够频繁地调用。

但是通过上述工作,您可以实例化解析器并在一段时间后中断其线程。可能会让你的解析速度相当慢(如果我没记错的话,可能会慢 25% 左右)。无论如何,希望这会有所帮助。

I looked at this temporarily a while back. You can essentially create a wrapper over the generated parser and override one of the methods. I use ANTLR with Kotlin, so excuse the below example.

class InterruptibleParser : YourParser() {

  override fun enterRule() {
    if (Thread.interrupted()) {
        throw InterruptedException()
    }
    return super.enterRule()
  }
}

I tried it with either enterRule, or consume, or getContext -- I don't remember which function gets called frequently enough.

But with the above working, you can instantiate the parser and interrupt its thread after a certain amount of time. Would likely make your parsing fairly slower (maybe around 25% slower if I'm remembering correctly). Anyways, hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文