2015-05-01 26 views
4

我是Prolog的新手,我正在试图理解一个语法如何从DCG转化为正常的明确子句。 我知道DCG符号只是Prolog中正常定义子句的语法糖。我开始描述正常语法和DCG之间的一些相似之处,但是没有应用相同的模式,所以我在问是否存在一些我缺少的规则或可能有效的转换算法。有没有一种方法或算法将DCG转换为Prolog中的正常子句?

这里是我的工作的语法,这里是我为了做翻译的是语法:

expr --> term, addterm. 
addterm --> []. 
addterm --> [+], expr. 
term --> factor, multfactor. 
multfactor --> []. 
multfactor --> [*], term. 
factor --> [I], {integer(I)}. 
factor --> ['('], expr, [')']. 

这实际上语法检查算术运算的语法正确性。 第一条规则实际上很容易转换,因为它的模式类似于正常的定语法,第四条也是如此。但是我不知道其他四个。这里是如何转换的规则:

expr(E0,E) :- term(E0,E1), addterm(E1,E). 
+1

在SWI-Prolog中,您可以使用'listing/1'来查看为DCG生成的Prolog代码。例如,试试:“? - 列出(expr // 0).'和'? - 列出(factor // 0)。”。 – mat

回答

4

您正处在正确的轨道上!继续走,你会得到这样的事情:

expr(Xs0,Xs) :-       % expr --> 
    term(Xs0,Xs1),      % term, 
    addterm(Xs1,Xs).      % addterm. 

addterm(Xs0,Xs) :-      % addterm --> 
    Xs0 = Xs.       % []. 
addterm(Xs0,Xs) :-      % addterm --> 
    Xs0 = [+|Xs1],      % [+], 
    expr(Xs1,Xs).      % expr. 

term(Xs0,Xs) :-       % term --> 
    factor(Xs0,Xs1),      % factor, 
    multfactor(Xs1,Xs).     % multfactor. 

multfactor(Xs0,Xs) :-     % multfactor --> 
    Xs0 = Xs.       % []. 
multfactor(Xs0,Xs) :-     % multfactor --> 
    Xs0 = [*|Xs1],      % [*], 
    term(Xs1,Xs).      % term. 

factor(Xs0,Xs) :-      % factor --> 
    Xs0 = [I|Xs],      % [I], 
    integer(I).       % {integer(I)}. 
factor(Xs0,Xs) :-      % factor --> 
    Xs0 = ['('|Xs1],      % ['('], 
    expr(Xs1,Xs2),      % expr, 
    Xs2 = [')'|Xs]. `     % [')'].  
3

如果您的Prolog系统提供expand_term/2内置谓词,你可以用通常扩展语法规则为条款。例如:

?- expand_term((a --> b, c), Clause). 
Clause = (a(_G1012, _G1013):-b(_G1012, _G1028), c(_G1028, _G1013)). 

为一点更可读的输出(并且为此),尝试:

?- expand_term((a --> b, c), Clause), numbervars(Clause, 0, _). 
Clause = (a(A, B):-b(A, C), c(C, B)). 

numbervars/3是大多数的Prolog系统中发现的事实标准谓词。

4

一些Prolog的系统的方式,是从一个由@Repeat和@PauloMoura答案不同的翻译DCG中以条款:终端直接与统一被分析/生成的列表中的成员被对谓词'C'/3的调用所取代。例如

a(X) --> b(X), [x, y], c(X). 

被翻译成

a(A,B,C) :- 
    b(A,B,D), 
    'C'(D,x,E), 
    'C'(E,y,F), 
    c(A,F,C). 

这个谓词是预定义的这些系统做统一为这些答案,通过该条款

'C'([X|S],X,S). 

,但它可以被重新定义如果需要,由用户提供。

这是DCG中定义的部分,首先提出在费尔南多·佩雷拉和大卫·沃伦纸定从句语法的语言分析,在人工智能,13,1980年,并且是差异阿兰一个Colmerauer等人以前的文章变态文法。使用'C'/3谓词,原名为connects,使得DCG独立于待解析/生成的字符串的表示方式:在上面给出的翻译中,没有什么要求变量BF代表列表,并且'C'/3可以重新定义为将它们解释为其他类型的术语。为了避免效率损失,本文建议在编译过程中使用案例列表对DCG条款进行预处理。

相关问题