3

您如何将以下 DCG 翻译成 PROLOG 的普通定句?

expr_regular --> cor_ini,numero,guion,numero,cor_fin.
cor_ini --> ['['].
numero --> ['0'];['1'];['2'];['3'];['4'];['5'];['6'];['7'];['8'];['9'].
cor_fin --> [']'].
guion --> ['-'].

编辑:我想将 DCG 翻译成普通的 PROLOG 子句,因为我不能在同一代码中同时使用 DCG 和普通子句(在我的情况下)。我有这两条代码:

件1:

traducir(Xs, Ys) :- maplist(traduccion, Xs, Ys).
traduccion('^',comeza_por).
traduccion('[',inicio_rango).
traduccion('0',cero).
traduccion('-',a).
traduccion('9',nove).
traduccion(']',fin_rango).

如何使用它的一个例子是:

?- traducir(['[','0','-','9',']'],[]).
true .

第 2 部分:

 traducir--> cor_ini,numero,guion,numero,cor_fin.
 cor_ini --> ['['].
 numero --> ['0'];['1'];['2'];['3'];['4'];['5'];['6'];['7'];['8'];['9'].
 cor_fin --> [']'].
 guion --> ['-'].

如何使用它的一个例子是:

traducir(['^','[','0','-','9',']'],X).
X = [comeza_por, inicio_rango, cero, a, nove, fin_rango].

我想将两个代码合二为一,以测试 traducir 是否写得好(如果它遵循 DCG)并将您输入的内容翻译成文本,因此最终程序应该能够执行以下操作:

?- traducir(['^','[','0','-','9',']'],X).
X = [comeza_por, inicio_rango, cero, a, nove, fin_rango].
?- traducir(['[','0','-','9',']'],[]).
true .
4

3 回答 3

2

在 SWI-Prolog 中,您可以listing/1直接在上使用:

?- forall(member(NT,[expr_regular//0,cor_ini//0,numero//0,cor_fin//0,guion//0]),
          listing(NT)).
expr_regular(A, F) :-
    cor_ini(A, B),
    numero(B, C),
    guion(C, D),
    numero(D, E),
    cor_fin(E, F).

cor_ini(['['|A], A).

numero(A, B) :-
    (   A=['0'|B]
    ;   A=['1'|B]
    ;   A=['2'|B]
    ;   A=['3'|B]
    ;   A=['4'|B]
    ;   A=['5'|B]
    ;   A=['6'|B]
    ;   A=['7'|B]
    ;   A=['8'|B]
    ;   A=['9'|B]
    ).

cor_fin([']'|A], A).

guion([-|A], A).

true.

就是这样!您可能会受益于查看相关问题的答案“ Is there a way or a algorithm to convert DCG into normal definite clause in Prolog? ”。

于 2015-06-26T07:01:33.460 回答
1

好吧,我真的不明白你的问题。无论如何,如果您出于某种原因不想使用漂亮的 DCG 语法,您仍然可以使用类似的东西wildcard_match/2,或者重新发明轮子并自己使用差异列表来重新实现 DCG,或附加。对于wildcard_match/2部分:

expr_regular(R) :- wildcard_match('[[][0-9]-[0-9]]', R).
于 2011-12-04T17:04:53.210 回答
1

你的语法非常简单:只是终端。所以我们可以翻译成一个非常具体的模式(注意:不允许泛化)。

expr_regular(S, G) :-
    S = [0'[, N1, 0'-, N2, 0']|G], numero(N1), numero(N2).
numero(N) :-
    memberchk(N, "0123456789").

唯一值得注意的是它是 ISO 标准字符表示法......

于 2011-12-04T20:15:20.447 回答