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

如何在Prolog中实现CFG?解析代码测试不通过求助

修正Prolog上下文无关文法解析器问题

核心问题分析

  1. 原CFG的Num规则存在逻辑错误,正确的多位数定义应该是Num → Digit | Num Digit(你写的Num → Digit | Num是左递归死循环,无法匹配连续数字)。
  2. 当前num谓词仅实现了单个数字的匹配,无法处理输入中的多位数(比如'3','2'组成的连续数字序列)。
  3. parse谓词的参数处理错误,没有正确接收输入列表并验证完全匹配。

修正后的完整代码

% 解析入口:接收输入列表,确保整个序列被完全解析
parse(Lst) :- lines(Lst, []).

% 实现 Lines → Line ; Lines | Line
lines(X, A) :- line(X, Y), semicolon(Y, Z), lines(Z, A).
lines(X, Y) :- line(X, Y).

% 实现 Line → Num , Line | Num
line(X, A) :- num(X, Y), comma(Y, Z), line(Z, A).
line(X, Y) :- num(X, Y).

% 修正后的 Num 规则:匹配单个数字或连续多个数字
num(X, Y) :- digit(X, Y).
num(X, Y) :- digit(X, T), num(T, Y).

% 匹配分号(修正拼写错误)
semicolon([';' | T], T).
% 匹配逗号
comma([',' | T], T).

% 匹配单个数字,用member简化代码
digit([X | T], T) :- 
   member(X, ['0','1','2','3','4','5','6','7','8','9']).

关键修正说明

  • parse谓词:改为直接接收输入列表,调用lines(Lst, [])确保输入被完全解析到空列表,没有剩余字符。
  • num谓词:恢复递归匹配逻辑,既支持单个数字,也支持连续多个数字的组合,解决多位数识别问题。
  • digit谓词:用member/2替代重复的;判断,代码更简洁易维护。
  • 拼写修正:将simecolon改为规范的semicolon,不影响功能但提升代码可读性。

测试验证

运行查询:

?- parse(['3', '2', ',', '0', ';', '1', ',', '5', '6', '7', ';', '2']).

会返回true,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 16:32:55