【问题标题】:RegEx Parser written in Prolog用 Prolog 编写的正则表达式解析器
【发布时间】:2011-01-22 07:18:02
【问题描述】:

几个小时以来,我一直在努力解决这个家庭作业问题。我们必须用 Prolog 解析一个正则表达式。在大多数情况下,我使用的谓词都有效,但是有一些正则表达式和字符串组合会导致它们在 SWI-Prolog 中耗尽堆栈空间。这是一个包含两个正则表达式字符串组合的示例,一个有效,一个无效:

star(star(char(a))), []
star(star(char(a))), [a]

第一个有效,第二个用完堆栈。

这是我正在使用的谓词:

re_match(epsilon, []).
re_match(char(Letter), [Letter]).
re_match(star(_), []).
re_match(seq(Rx1, Rx2), List) :- append(List1, List2, List),  re_match(Rx2, List2),  re_match(Rx1, List1).
re_match(alt(Rx1, Rx2), List) :- re_match(Rx1, List); re_match(Rx2, List).
re_match(star(Rx), List) :- append(List1, List2, List), re_match(Rx, List1), re_match(star(Rx), List2).

我不确定我需要进行哪些更改才能使其正常工作,但我不确定还可以做什么。

此外,将 List :- append(List1, List2, List) 更改为 [H|T] 不会对其中一个示例进行评估。

【问题讨论】:

  • 我可以报告它在 GNU Prolog 中运行良好...

标签: regex prolog dcg


【解决方案1】:

考虑使用 DCG 表示法以获得更好的可读性和更容易推断终止属性:

:- op(100, xf, *).

rexp(eps)      --> [].
rexp([T])      --> [T].
rexp(_*)       --> [].
rexp(R*)       --> rexp(R), rexp(R*).
rexp(s(R1,R2)) --> rexp(R1), rexp(R2).
rexp((R1|R2))    --> ( rexp(R1) ; rexp(R2) ).

使用 length/2 生成越来越长的列表以生成与正则表达式匹配的字符串的示例:

?- length(Ls, _), phrase(rexp(s(([a]|[b]),[c]*)), Ls).
Ls = [a] ;
Ls = [b] ;
Ls = [a, c] ;
Ls = [b, c] ;
Ls = [a, c, c] ;
etc.

【讨论】:

  • 终止参数无效。反例:phrase(rexp(eps*),[a]). 列表是固定长度的,但目标仍然没有终止。
  • 我想也可以使用 (.,.) 符号,对吧?还是选择 s(.,.) 符号有什么特殊原因?
  • @j4nbur53:我倾向于避免使用',' 作为函子,因为,(逗号)在Prolog 中已经如此重载:它分隔谓词参数,列出元素 表示连词。
【解决方案2】:

我现在无法访问 SWI Prolog,但这里有一个猜测:

尝试改变

re_match(star(Rx), List) :- append(List1, List2, List),
                            re_match(Rx, List1),
                            re_match(star(Rx), List2).

re_match(star(Rx), List) :- append([H|List1], List2, List),
                            re_match(Rx, [H|List1]),
                            re_match(star(Rx), List2).

强制re_match 在对星型结构进行迭代时“吃点东西”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 2010-10-22
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 1970-01-01
    相关资源
    最近更新 更多