2011-11-02 78 views
2

所以我有這樣的語法:前綴解析使用的Prolog

expr(op(T,B,E)) => [term(T), binop(B), expr(E)]. 
    expr(T) => [term(T)]. 

    term(N) => [num(N)]. 
    term(L) => [lvalue(L)]. 
    term(pre(O,L)) => [incrop(O), lvalue(L)]. 
    term(post(L,O)) => [lvalue(L), incrop(O)]. 
    term(E) => ['(', expr(E), ')']. 

    lvalue($(E)) => [$, expr(E)]. 

    incrop(++) => [++]. 
    incrop(--) => [--]. 

    binop(+) => [+]. 
    binop(-) => [-]. 

    num(0) => [0]. 
    num(1) => [1]. 
    num(2) => [2]. 
    num(3) => [3]. 
    num(4) => [4]. 
    num(5) => [5]. 
    num(6) => [6]. 
    num(7) => [7]. 
    num(8) => [8]. 
    num(9) => [9]. 

,目標是根據規則來解析輸入,並分離剩餘的後綴。例如,

| ?- parse_prefix(expr(E), [$,1,+,2], S). 

E = op($(1),+,2) 
S = [] ? ; 

E = $(op(1,+,2)) 
S = [] ? ; 

E = $(1) 
S = [+,2] ? ; 

no 

| ?- parse_prefix(expr(E), [9], S). 

E = 9 
S = [] ? ; 

no 


| ?- parse_prefix(expr(E), [9,+,$,1,+], S). 

E = op(9,+,$(1)) 
S = [+] ? ; 

E = 9 
S = [+,$,1,+] ? ; 

我寫了下面的謂詞:

%Base Case: No Token, No Suffix 
parse_prefix(_,[],[]). 

%Direct Matching: ex) parse_prefix(num(9),[9],S) 
parse_prefix(NT,[Head|Tail],S):- 
    NT =>[Head], 
    write('two '), 
    parse_prefix(expr(E),Tail,S). 
%General Matching: ex) parse_prefix(expr(E),_,S) 
parse_prefix(NT,[Head|Tail],S):- 
    NT => [Head1|Tail1], 
    %write(Head1), 
    %write('one\n'), 
    parse_prefix(Head1,[Head|Tail],S). 

,我有很多與遞歸和回溯混亂..

我會永遠愛誰可以幫助我這個人。

預先感謝您。

+1

請描述輸出應該是什麼樣子。 –

+1

我想他所描述的「目標是根據規則解析輸入,並分離剩餘的後綴」。是DCG中兩個額外參數的常見行爲。由於他沒有在語法規則中使用cut或some,所以[$,1,+,2]可以用一個空的後綴,即op($(1),+,2)得到兩個完整的解析。和$(op(1,+,2)),正如他典型的要求。 –

回答

2

您已經接近解決方案。定義你自己的operator =>/2代表你自己的gammar規則並且不會與 - >/2發生衝突。但是我在語法規則體的表示方面遇到了問題。我沒有看到你在語法規則體中區分終端和非終端。

一個建議是投票選擇(A1,...,An)來表示體內的一個連接詞,而不是[A1,..,An]。然後將[T]用於終端,將NT用於非終端。所以,下面的規則,

term(E) => ['(', expr(E), ')']. 

行文:

term(E) => ['('], expr(E), [')']. 

然後,您可以調整你的規則和定義parse_prefix/3如下。我給你的終端與結合和非末端的情況下:

parse_prefix([T],I,O) :- !, I=[T|O]. 
parse_prefix((A,B),I,O) :- !, parse_prefix(A,I,H), parse_prefix(B,H,O). 
parse_prefix(NT,I,O) :- (NT => Body), parse_prefix(Body,I,O). 

可以添加附加的情況下的空生產([])和輔助條件({}),或使其更加靈活是能夠使用終端列表([T1,..,Tn])。另外還有一些控制結構是可能的,但是當你試圖做一個切割(!)時,按照元解釋器的方法,事情會變得有點討厭。

而不是編寫一個元解釋器parse_prefix/3,你也可以做自己的術語重寫,最終到達一個方法,將給定的伽馬規則首先轉換成普通的Prolog,然後從那裏執行它們。在這裏你會找到一個簡單的食譜:

http://www.jekejeke.ch/idatab/doclet/blog/en/docs/int/jan/098_2011/097_dcg_expansion/package.html

再見

+0

謝謝,它幫助我想出了更好的謂詞! – CosmicRabbitMediaInc