在PROLOG中创建DCG解析器

问题描述 投票:0回答:1

我必须在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([tutorial | W],W)。n([library | W],W)。

v([went | W],W)。v([saw | W],W)。


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

谢谢!

parsing prolog context-free-grammar dcg
1个回答
0
投票

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

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), !.

这里是结果 Results.

您可以看到最后一句话仍然失败,这是因为如果您遵循算法或算法的流程,您会发现规则's'调用规则'vp',该规则仅允许'det'跟随用“ v”表示,因此,如果您看到第三句话的第一个单词“ In”,则“ vp”中的“ det”将起作用,但是下一个单词“ library”将不会在“ v”上成功,因为“库”不是动词,所以这就是它失败的原因。总而言之,如果您希望第三个句子成功,那么您必须对语法进行一些更改。顺便说一下,有一种更好的方法,可能会稍微复杂一点,但是一旦您了解了如何使用它,就会更快地工作,并且更容易通过使用Prolog DCG https://www.swi-prolog.org/pldoc/man?section=DCG来创建复杂的语法。我提到的情况是您不知道的。

© www.soinside.com 2019 - 2024. All rights reserved.