作者SDNiceBoat (NiceBoat.)
看板C_Sharp
標題[問題] 語法樹的設計.... 樹打結了....
時間Mon Aug 23 23:01:04 2010
可以把任何執行式寫成「樹」
例如:
Math.Atan2(Math.Max(1.1,1.0),Math.Pow(Math.Min(2,Math.E),Math.PI));
就變成
http://ppt.cc/@SRy
這在觀念上沒有問題
如果要對整株樹做些什麼特殊的事情
只要呼叫子層的方法,子層再去呼叫子層就好
簡單來講,就是遞迴
======================================================================
因為C#不提供先把參數塞進委派,到要執行的時候才去執行的功能
所以自己寫了一些小工具來用
當然,用到一點語法樹的觀念。
大致上是像這種東西:
public sealed class ActOrVal<Tout> : ACT<Tout>
{
private Func<Tout> 執行式;
private Tout 數值;
public override Tout GetValue()
{
if (this.執行式 == null) return this.數值;
return this.執行式();
//如果存放的是委派,傳回執行後得到的值
//如果放的是參數,則傳回參數
}
public override ACT<Tout> Get副本()
{
if (this.執行式 == null) return new ActOrVal<Tout>(this.數值);
return new ActOrVal<Tout>(this.執行式);
}
}
public sealed class ActOrVal<Tin1, Tout> : ACT<Tout>
{
private ACT<Func<Tin1,Tout>> 執行式2;
public override Tout GetValue()
{
return this.執行式2.GetValue()((Tin1)this.執行參數);
//把參數塞進委派裡,並執行它,把得到的值傳出去
//另,放委派的東西本身也把她當參數放,所以要執行
//GetValue()才能得到方法
}
public override ACT<Tout> Get副本()
{
return new ActOrVal<Tin1, Tout>(
this.執行參數.Get副本(), this.執行式2.Get副本());
}
}
簡單來說,他可以把委派跟參數吃進去
要用的時候才去執行他
另外,參數本身也可以當作另一個執行式的傳回值,在轉型時就會執行GetValue()
到這邊也還沒有問題.................
=======================================================================
但是,當我想寫個計數器時就出現問題了
public class 計數器 : ACT<bool>
{
int this.iCount;
ACT iWhenEnd;
//這是ACT<Tout>的基底類別,可以直接執行。
//不用管傳回質的問題
public int GetI()
{
return this.iCount;
//設計給樹的末端(ACT<int>)吃的,因為希望做出迴圈的效果
}
public override bool GetValue()
{
總而言之,這段相當於
for(int iCount = 0;iCount<iEndValve;iCount+iadd)
在迴圈內就傳回true
bool RV;
this.iCount += this.iadd;
switch (this.條件)
{
case 條件式.無限迴圈:
RV = true;
case 條件式.正數:
RV = this.iCount < this.iEndValve;
case 條件式.倒數:
RV = this.iCount > this.iEndValve;
}
if (!this.iLastBool) this.iWhenEnd.RunAction();
//沒傳回值的版本是: void RunAction()
//有傳回值的,多一個: Tout GetValue()
//有傳回值的(例如ACT<Tout>)可以轉型為ACT
return RV;
}
public override ACT<bool> Get副本()
{
return (this.iWhenEnd != null) ?
new 計數器(this.iStart,
this.iEndValve, this.iadd,
this.iWhenEnd.Get副本())
:
new 計數器(this.iStart,
this.iEndValve, this.iadd);
}
}
=====================================================================
到這邊.............
我發現我的樹不是長這樣
http://ppt.cc/@SRy
而是有可能會長這樣......
http://ppt.cc/Sz96
因為可能有別的多個節點會拿計數器的.iCount()來用
ACT<Tout>裡面放的可能是樹中的方法,例如.iCount()
同理,之後打算要寫的if....else、while、do...while區塊
都可能會將「樹」變成一張「網」
如果只是執行GetValue()或RunAction()的話還好
只看參數或是Mthod的話,那個還是「樹」
在執行上不會有問題.....
但是..... 取得複本的話怎麼辦?
public sealed class ActOrVal<Tout> : ACT<Tout>
{
public override ACT<Tout> Get副本()
{
if (this.執行式 == null) return new ActOrVal<Tout>(this.數值);
return new ActOrVal<Tout>(this.執行式);
}
}
↑這個的取得複本只會指向「舊的」計時器.GetI()
http://ppt.cc/aDR1
如果因為一個.GetI()而建立一個新的計數器
就會變成這樣
http://ppt.cc/-p@o
因此,在用遞迴複製複本的時候,要想辦法將不同複本都指向正確的目標
請問有辦法讓所有複本都指向新的計數器嗎?
==========================================================================
題目有些複雜,先謝謝你花時間看這個問題。
--
20330
6/17 - □ (本文已被吃掉)
幹!這梗有毒...救命~~
20331
6/17 - □ (本文已被吃掉)
〒 〒 ◤
20332
1 6/17 - □ (本文已被吃掉)
▼▼▼▼
20333
XX 6/17 - 囧 (哈哈拎北有毒)
\▲▲▲▲\ =
●20334
1 6/17 - □ (本文已被吃掉)
20335 6/17 - □ (本文已被吃掉)
口卡口卡嘗百草
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 163.27.109.101
※ 編輯: SDNiceBoat 來自: 163.27.109.101 (08/23 23:05)
※ 編輯: SDNiceBoat 來自: 163.27.109.101 (08/23 23:08)
※ 編輯: SDNiceBoat 來自: 163.27.109.101 (08/23 23:40)
※ 編輯: SDNiceBoat 來自: 163.27.109.101 (08/23 23:41)
→ SDNiceBoat:請問一下1...... 有人看得懂題目嗎? = = 08/25 14:14
推 popmentos:完全看不懂 @_@ 08/25 21:30
→ SDNiceBoat:orz.... 我努力試著讓他白話一點...... 08/25 21:39
推 popmentos:感恩 08/25 21:49
推 tf1515:是說要讓Act<bool>和Act<int>都指向新的計數器嗎? 08/26 13:59
→ SDNiceBoat:沒錯 08/26 14:50
→ SDNiceBoat:可是這裡有個問題,那實際上是指向該物件的「方法」, 08/26 14:50
→ SDNiceBoat:而不是該物件。 08/26 14:51
→ SDNiceBoat:目前是做了個ACT2<Tout>介面,讓ACT<Tout>可以指向 08/26 14:52
→ SDNiceBoat:ACT2<Tout>物件..... 雖然勉強可以解決,但還是有缺點 08/26 14:53
→ SDNiceBoat:那就是.... 不能自動轉型,自己定義的運算子不能用到介 08/26 14:53
→ SDNiceBoat:面,例如:ACT2<Tout> → ACT<Tout> 要手動轉。 08/26 14:54
→ SDNiceBoat:另一個缺點是..... 一種型別只能有一個輸出值。我沒辦 08/26 14:55
→ SDNiceBoat:法讓一個物件同時輸出兩個int值之類的 08/26 14:56
→ SDNiceBoat:說錯了,ACT2<Tout> → ACT<Tout>不是要手動轉,是根本 08/26 14:57
→ SDNiceBoat:沒辦法轉,要用new ACT<Tout>(ACT2<Tout>) 這樣 08/26 14:58