4

我正在嘗試爲決策邏輯表設計AST。我希望能夠用代表我的AST的歧視聯盟做的事情之一是由於不同的原因轉變其中的一部分。爲了清楚起見,我要給你一個例子在F#中轉換抽象語法樹(AST)

判定邏輯表

@ VAR = 10; Y;

上面的內容可以看作是有一條規則,條件VAR = 10用Y條目輸入此規則。

抽象語法樹定義(簡化本示例)

type expression = 
    | Value of double 
    | Variable of string 
    | Equality of expression * expression 

type entry = 
    | Entry of string 

type entries = 
    | Entries of entry list 

type conditional = 
    | ConditionEntries of expression * entries 

type condition 
    | Condition of expression * string 

type rule = 
    | Rule of condition list 

渲染(變換前)

ConditionEntries(
    Equality(
     Variable("VAR"), 
     Value(10.0)), 
    Entries(["Y"])) 

渲染(變換後)

Rule(
    Condition(
     Equality(
      Variable("VAR"), 
      Value(10.0) 
     ), 
     Entry("Y") 
    ) 
) 

現在我想要做的就是轉換上面的樹來展開條目中表示的規則。我的想法是我可以使用遞歸函數和模式匹配來做到這一點,但我現在有點麻煩了。

我想實際上我想要做的是每當我看到一個ConditionEntries節點時,我想爲條目與條目組合的條目列表中的每個字符串發出新規則。這有任何意義嗎?

在此先感謝您的任何建議。

p.s.我還沒有試圖編譯上面的例子,所以請原諒任何語法錯誤。

回答

2

嗯,根據您的AST,這是非常壞了,這裏是一個tranform功能產生從輸入你想要的輸出(儘管它不是遞歸的,只是使用List.map一些模式匹配。expression是你唯一的遞歸式但它看起來不像你想遞歸處理它?):

let ex1 = 
    ConditionEntries(
     Equality(
      Variable("VAR"), 
      Value(10.0)), 
     Entries([Entry("Y")])) 

let ex2 = 
    ConditionEntries(
     Equality(
      Variable("VAR"), 
      Value(10.0)), 
     Entries([Entry("X");Entry("Y");Entry("Z")])) 

let transform ces = 
    match ces with 
    | ConditionEntries(x, Entries(entries)) -> 
     entries 
     |> List.map (function Entry(entry) -> Condition(x, entry)) 


//FSI output: 
> transform ex1;; 
val it : condition list = 
    [Condition (Equality (Variable "VAR",Value 10.0),"Y")] 
> transform ex2;; 
val it : condition list = 
    [Condition (Equality (Variable "VAR",Value 10.0),"X"); 
    Condition (Equality (Variable "VAR",Value 10.0),"Y"); 
    Condition (Equality (Variable "VAR",Value 10.0),"Z")] 
+0

對不起,關於分解AST,我想我只包括相關部分,以簡潔。謝謝你的回答,我會稍後再試一次。還有一個問題:如果ConditionEntries和Condition屬於另一個節點,轉換函數是否會發生很大變化? (即我只想改變樹的「部分」而不是整體) –

+0

嗨傑弗裏,無後顧之憂,分手的AST對我來說並不令人反感,我只是表達了對你模仿你的方式的擔憂語言可能太複雜(AST中內置了太多的語義?)。 –

+0

關於你的後續問題,我不確定沒有看到大圖,但通常如果你只想轉換樹的一部分,你可以有一個最終的通用匹配,它只是返回樹的分支不變,像'... |分支 - >分支 –