2012-05-11 12 views
0

IそのうちYaccで次のルール私はリンクリストを作成したいを持っている、しかし、私はそれを印刷しようとすると、リスト内の最後のノードを取得しておいてください。Yaccはどのようにこのルールを拡張しますか?

node_list 
:             {$$=NULL;} 
| node_list node         {if ($1 != NULL) $1->next=$2; $$=$2; } 
; 

私の理解では、例えば場合でありますこれは

node_list node3 
node_list node2 node3 
ndoe_list node1 node2 node3 
NULL node1 node2 node3 

として、これを拡大するリスト

node1 
node2 
node3 

Yaccですが、私はGEをしていますので、

node_list 
:             {$$=NULL;} 
| node_list node         {$2->next=$1; $$=$2 ; } 
; 

私は、それぞれの場合に私はあることを理解:上記のコードで最後のノードをめの設定することは、その後、私の推測では、リストがそのように、私はこのコードを試すリヴィア順

node_list node1 
node_list node2 node1 
ndoe_list node3 node2 node1 
NULL node3 node2 node1 

に展開されていることですリストの最後のノードを返すので、1つのノードしか得られないのです。 linkXmlNodeは、今私は最後のノードが3回ごとに繰り返し取得しています

XmlNode * linkXmlNode(XmlNode * first, XmlNode * second) 
{ 
XmlNode * temp = second; 
while (second->next != NULL) 
    second=second->next; 

second->next=first; 
return temp; 
} 

ある

node_list 
:             {$$=NULL;} 
| node_list node         {$$=linkXmlNode($1,$2);} 
; 

:だから、私はこのコードを試してみました。私も他の方向を試してみましたが、今私は、最初のノードを取得:誰かがYaccは素晴らしいことだリストを展開さ方法を正確に知っている場合

XmlNode * linkXmlNode(XmlNode * first, XmlNode * second) 
{ 
if (first == NULL) return second; 
XmlNode * temp = first; 
while (first->next != NULL) 
    first= first->next; 
first->next = second; 
return temp 
} 

を。


EDIT:ANSWER 私は機能仕事上、私の印刷機能でミスをしていました。エラーは、イテレータを印刷する代わりに、パラメータを印刷しているため、同じノードが複数回取得されていたことです。

+2

これは私にとって 'lex'よりも' yacc'によく似ています。 – geekosaur

+0

修正しました。正しい。 – mihajlv

+0

'$ 1'と' $ 2'を印刷しようとしましたか? –

答えて

0

あなたは、次の作品を取得:

=> nodeList 
nodeList node1 => nodeList 
nodeList node2 => nodeList 
nodeList node3 => nodeList 

をだからあなたの最初のケースであなたのリストをオフに開始しますnullの場合、node1が前に付いていて、node2が前に付いています。そしてnode3が前に付いています。ノードをリストの最後にリンクするコードでは、最終的なリストが昇順で表示されるはずですが、私はあなたの編集がそれが正しいことを示唆しているのを見ただけです。

+0

はい、最後の機能は正しいです。あなたの答えについては、それはトップダウンの順序で行くので、解析ですか? – mihajlv

+1

@mihajlv yaccはボトムアップパーサーの一種であるLALRパーサジェネレータですが、文法はおそらくLLトップダウンパーサーを使って解析できます。 – Neil

1
if ($1 != NULL) $1->next=$2; $$=$2; 

戻り$2が、$2$1を指していません。代わりに$1$2を指摘しましたが、$1を返さないので、何も知らないでしょう。 (どのようにそれが関係について知っているだけ$1だことを考えれば$1に取得する方法を知っているはずだけ$2与えられた何かが、ある?)

$2->next=$1; $$=$2 

あなたのリストを取得しますが、逆の順序でなければなりません。それを他の順序で取得するには、先頭と末尾の両方のポインタを渡すか、リストを上書きする前にリストを反転するためにリストの上に追加のルールを挿入する必要があります。

3回目の試行はリンクの点で最も正しいです。同じデータを取得している場合は、リスト要素をどのようにコピーしているかという疑問が残ります。 yacc自体があなたのリストについて何も知らないことに注意してください。 は、リストを全く「展開」しないので、というコードが実行されます。

(最新のコメントは、あなたがあなたの質問を解決したことを示している場合、それは私には明確ではない。)

+0

最新の関数が動作していますが、印刷機能に間違いがありました。リストを反復するイテレータではなくパラメータを出力していたので、同じノードを複数回印刷していました。しかし、説明をありがとう、それは理にかなっています。 – mihajlv

関連する問題