首页 > 解决方案 > 在 PROLOG 中创建 DCG 解析器

问题描述

我必须在 PROLOG 中实现一个上下文无关的解析器,它使用可以生成的语法:

I saw a tutorial.
I went in a library.
In library a tutorial I saw. 

(我知道它在语法上不正确,但我需要看看如何匹配模式)

我收到一个输入作为查询 - 让我们假设它是第一句话 - 我必须打印成功解析的规则应用数量,否则为 false。

为了实现这一点,我找到了这些语法:


s(X,Z):- vp(Y,Z), np(X,Y)。
np(X,Z):- det(X,Y), n(Y,Z)。
np(X,Z):- det(X,Y), n(Y,Z), np(X,Z)。
vp(X,Z):- det(X,Y), v(Y,Z)。

det([i|W],W)。
det([a|W],W)。
det([in|W],W)。

n([教程|W],W)。
n([库|W],W)。

v([去了|W],W)。
v([锯|W],W)。


它适用于前 2 个句子,但我不知道如何使它适用于最后一个句子,我不知道如何打印成功解析的规则应用数量。

谢谢!

标签: parsingprologcontext-free-grammardcg

解决方案


这将有助于成功解析规则的应用数量。但是,如您所见,它始终与句子中的单词数量相同。我所做的是在每个规则的参数中实现一个“计数器”,每次“基本规则”成功时,它都会增加“计数器”的值。

det([i|W], W, A, R) :- R is A + 1.
det([a|W], W, A, R) :- R is A + 1.
det([in|W], W, A, R) :- R is A + 1.

n([tutorial|W], W, A, R) :- R is A + 1.
n([library|W], W, A, R) :- R is A + 1.

v([went|W], W, A, R):- R is A + 1.
v([saw|W], W, A, R):- R is A + 1.

np([], R, R).
np(X, A, R2):- det(X, Y, A, R), np(Y, R, R2).
np(X, A, R3):- det(X, Y, A, R), n(Y, Z, R, R2), np(Z, R2, R3).
vp(X, Z, R2):- det(X, Y, 0, R), v(Y, Z, R, R2).

s(X, R2):- atomic_list_concat(L,' ', X), vp(L, Z, R), np(Z, R, R2), !.

这是结果 结果。

正如你所看到的最后一句话仍然失败,那是因为如果你遵循算法的流程或调用它,你可以看到规则's'调用规则'vp',它只承认'det'后面跟着a 'v',所以如果你看到第三句的第一个单词是'In','vp'中的'det'会起作用,但是下一个单词'library'不会在'v'上成功,因为'library ' 不是动词,所以这就是它失败的原因。总而言之,如果您希望第三句话成功,您将不得不对您的语法进行一些更改。顺便说一句,有更好的方法,可能实现起来有点复杂,但是一旦你了解了如何使用它,使用 Prolog DCG https://www.swi将更快地工作并且更容易创建复杂的语法-序言。. 我提到以防你不知道这一点。


推荐阅读