2010-11-04 41 views
2

目前我正在和Prolog中的DCG玩解析XML文件。我能得到下面的代碼片段,它能夠解析簡單的XML如:序言DCG圖請

<author> <name> <f> arthur </f> 
     <m> conan </m> 
     <l> doyle </l> 
    </name> 
    <bday> <d> 22 </d> 
     <m> 5 </m> 
     <y> 1859 </y> 
    </bday> 
</author> 

<author> <name> <f> william </f> 
     <l> shakespeare </l> 
    </name> 
    <bday> <d> 23 </d> 
     <m> 4 </m> 
     <y> 1564 </y> 
    </bday> 
</author> 
$ 

和DCG被定義爲:

xml([E]) --> element(E). 
xml([E|L]) --> element(E), xml(L). 

element(E) --> begintag(N), elements(L), endtag(N), {E =.. [N|L]}. 

elements(L) --> xml(L). 
elements([E]) --> [E]. 

begintag(N) --> ['<', N, '>']. 
endtag(N) --> ['<', '/', N, '>']. 

會有人請說明DCG是如何工作的這個案例?我很難理解DCG中的參數(例如,[x]([E])中的[E]; xml([E | L])中的[E | L]。) 謝謝!

回答

3

聲明性地思考:DCG總是描述一個列表。在DCG主體中,逗號(「,」)被讀作「然後」。因此,例如,xml // 1描述(按其第一條規則)單個元素或(通過其第二條規則)一個元素,然後再次由xml // 1描述。元素// 1是begintag,然後是元素,然後是endtag等.DCG頭中使用的參數讓您將DCG主體描述的序列與其他信息相關聯,如您特別感興趣的子序列。例如begintag // 1 - 你可以問:

?- phrase(begintag(T), [<, test, >]). 
T = test. 

,並在其他方向:

?- phrase(begintag(test), Ls). 
Ls = [<, test, >]. 

在begintag // 1的情況下,標籤名稱似乎對你很重要,所以你引入了一個參數,一方面可以讓你生成一個帶有給定名稱的開始標籤,另一方面可以讓你解析一個標籤並提取它的名字,o即使是最一般的查詢:

?- phrase(begintag(T), Ls). 
Ls = [<, T, >]. 

它抽象地將XML XML標籤與其名稱相關聯。

+0

謝謝!你有關於構建分析樹的任何提示嗎?即使打開了「跟蹤」,我也很難理解它,而且想出構建解析樹的想法更加困難(即,在識別之後返回解析樹)。 – pippoflow 2010-11-05 00:26:21