2015-07-11 22 views
4

我似乎一直在努力編寫DCG來解析輸入文件。但它似乎應該很簡單?是否有任何提示或技巧來思考這個問題?創建文件輸入dcg的一般模式是什麼?

對於一個具體的例子,可以說我想解析一個fasta文件。 (https://en.wikipedia.org/wiki/FASTA_format)。我想閱讀每個描述和每個序列的後面跟蹤。

:- use_module(library(pio)). 
:- use_module(library(dcg/basics)). 
:- portray_text(true). 
:- set_prolog_flag(double_quotes, codes). 
:- set_prolog_flag(back_quotes,string). 

fasta_file([]) -->[]. 
fasta_file([Section|Sections]) --> 
    fasta_section(Section), 
    fasta_file(Sections). 


fasta_section(Section) --> 
    fasta_description(Description), 
    fasta_seq(Sequence), 
    {Section =.. [section,Description,Sequence]}. 

fasta_description(Description) --> 
    ">", 
    string(Description), 
    {no_gt(Description), 
    no_nl(Description)}. 


fasta_seq([]) --> []. 
fasta_seq(Seq) --> 
    nt([S]), 
    fasta_seq(Ss), 
    {S="X"->Seq =Ss;Seq=[S|Ss]}. 

nt("A") --> "A". 
nt("C") --> "C". 
nt("G") --> "G". 
nt("T") --> "T". 
nt("X") --> "\n". 

no_gt([]). 
no_gt([E|Es]):- 
    dif([E],">"), 
    no_gt(Es). 

no_nl([]). 
no_nl([E|Es]):- 
    dif([E],"\n"), 
    no_nl(Es). 

現在這顯然是錯誤的。我想該行爲是

?-phrase(fasta_section(S),">frog\nACGGGGTACG\n>duck\nACGTTAG"). 
S = section("frog","ACGGGGTACG"); 
S = section("duck","ACGTTAG"); 
false. 

但是,如果我做了phrase(fasta_file(Sections),">frog\nACGGGGTACG\n>duck\nACGTTAG).科統一使用節/ 2秒的列表,這是我想要的,但我現在的代碼似乎相當hacky-我是如何處理的換行符例如。

+0

錯字:'S =「X」 - >'應該讀取'[S] =「X」 - >' – false

+0

[This answer] (HTTP://計算器。com/a/12942551/772868)將會對你感興趣。 – false

+1

用{{Section = section(Description,Sequence)}替換'{Section = .. [section,Description,Sequence]}'' – false

回答

0

肯定,有「小」打字的問題:

nt("A") -->"A", 
nt("C") -->"C", 
nt("G") -->"G", 
nt("T") -->"T". 

應該

nt("A") -->"A". 
nt("C") -->"C". 
nt("G") -->"G". 
nt("T") -->"T". 

反正,我也有過調試DCG我的問題,我寫了一個解析器Prolog的一個加載MySQL轉儲(真正的SQL,真的),並且當發現意想不到的東西時,例如轉義字符串或UTF8(?)奇怪的編碼,它是一種痛苦。

我會建議使用短語/ 3,看看是否有一個不可分開的尾巴。此外,可以幫助在已知的,表現良好的序列之後放置一些調試輸出。

當然,我假設您已經嘗試使用SWI-Prolog調試器。

此外,提防

... 
dif([E],">"), 
... 

你設置一下雙引號相應的標誌嗎?在DCG機構,重寫機械照顧匹配的,但默認情況下一個在SWI-Prolog的代碼序列不匹配雙引號中的字符串...

編輯

我認爲這將不解決有關總體戰略的懷疑......無論如何,這是我將如何處理這個問題?

fasta_file([]) -->[]. 
fasta_file([Section|Sections]) --> 
    fasta_section(Section), 
    fasta_file(Sections). 

fasta_section(section(Description,Sequence)) --> 
    fasta_description(Description), 
    fasta_seq(SequenceCs), {atom_codes(Sequence, SequenceCs)}, !. 

fasta_description(Description) --> 
    ">", string(DescriptionCs), "\n", {atom_codes(Description, DescriptionCs)}. 

fasta_seq([S|Seq]) --> nt(S), fasta_seq(Seq). 
fasta_seq([]) --> "\n" ; []. % optional \n at EOF 

nt(0'A) --> "A". 
nt(0'C) --> "C". 
nt(0'G) --> "G". 
nt(0'T) --> "T". 

現在

?- phrase(fasta_file(S), `>frog\nACGGGGTACG\n>duck\nACGTTAG`). 
S = [section(frog, 'ACGGGGTACG'), section(duck, 'ACGTTAG')] ; 
false. 

注意:fasta_seq // 1子句的順序很重要,因爲它實現了'渴望'解析 - 主要是爲了提高效率。正如我所說的,我不得不解析SQL,幾個MB是常見的。

編輯

?- phrase((string(_),fasta_section(S)), `>frog\nACGGGGTACG\n>duck\nACGTTAG`,_). 
S = section(frog, 'ACGGGGTACG') ; 
S = section(duck, 'ACGTTAG') ; 
false. 

fasta_section // 1是意味着以匹配確定序列。爲了全部回溯,我們必須提供回溯點。在這種情況下,來自庫(dcg/basics)的字符串// 1執行作業

+1

對不起,逗號是這個問題中的拼寫錯誤。 我現在使用雙引號這些東西和反向引號的字符串,因爲它似乎是最兼容的做事方式。 – user27815

+0

如果我想要使用fasta_section // 1和返回軌道來查找每個解決方案,那麼該怎麼辦? – user27815

+0

@ user27815:看最後一次編輯... – CapelliC

相關問題