You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scryer Prolog中phrase_from_stream/2结合http_open/3非终止问题

问题:Scryer Prolog中phrase_from_stream/2处理HTTP流无法终止

我在使用Scryer Prolog开发包含HTTP客户端组件的应用时,希望通过流式DCG解析数据,但发现http_open/3实例化的流搭配phrase_from_stream/2时会无限循环,无法终止。尝试结合内容大小、设置Connection: close请求头均无效,但相同逻辑在SWI-Prolog中可正常运行。

复现步骤

  • 执行python -m http.server 8000启动本地简易HTTP服务器
  • 在Scryer Prolog顶层运行以下代码:

正常工作的场景(先读取整个流再解析)

?- use_module(library(charsio)).
   true.
?- use_module(library(dcgs)).
   true.
?- use_module(library(http/http_open)).
   true.

?- http_open("http://127.0.0.1:8000", Stream, []), get_n_chars(Stream, N, Chars), phrase(seq(Data), Chars).
   Stream = '$stream'(0x600000636908), N = 726, Chars = "<!DOCTYPE HTML>\n<ht ...", Data = "<!DOCTYPE HTML>\n<ht ...".

无法终止的场景(流式解析)

?- use_module(library(pio)).
   true.

?- http_open("http://127.0.0.1:8000", Stream, []), phrase_from_stream(seq(Data), Stream).
% 无终止,无限循环

SWI-Prolog中的正常表现

?- use_module(library(http/http_open)).
true.
?- use_module(library(dcg/basics)).
true.
?- use_module(library(pio)).
true.
?- http_open("http://127.0.0.1:8000", Stream, []), phrase_from_stream(string(Data), Stream).
Stream = <stream>(0x600002954400,0x600002974b00),
Data = [60, 33, 68, 79, 67, 84, 89, 80, 69|...] ;
false.

调试建议

  • 跟踪流的EOF状态:用stream_property(Stream, eof_at_end(EOF))检查HTTP响应结束后,流是否被正确标记为已到末尾。若未标记EOF,phrase_from_stream/2会持续尝试读取数据。
  • 简化DCG规则测试:替换seq/1为极简规则,比如:
    read_eof --> [] .
    
    调用phrase_from_stream(read_eof, Stream),看是否能终止,以此排除DCG规则本身的问题。
  • 手动限制读取长度:从HTTP响应头中获取Content-Length,在DCG中只读取对应长度的字符,比如:
    read_n(0) --> [] .
    read_n(N) --> [C], { N1 is N-1 }, read_n(N1) .
    
    结合http_open/3的header(Content-Length, Len)参数获取长度,转换为整数后调用phrase_from_stream(read_n(Len), Stream),验证是否能终止。
  • 对比本地流测试:用本地文件流替代HTTP流,比如open("index.html", read, Stream),再调用phrase_from_stream(seq(Data), Stream),若本地流正常,说明问题出在HTTP流的处理逻辑上。
  • 检查Scryer Prolog的pio库实现:查看library(pio)中phrase_from_stream/2的源码,对比SWI-Prolog的实现,重点看EOF检测和流读取的循环逻辑,定位是否存在库函数的bug。

内容的提问来源于stack exchange,提问作者Rodrigo Setti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 08:07:39