Преобразовать абстрактное синтаксическое дерево (AST) в F # - PullRequest
4 голосов
/ 19 сентября 2011

Я пытаюсь создать AST для таблицы логики принятия решений. Одна из вещей, которую я хотел бы сделать с дискриминационным объединением, представляющим мой 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. Я не совсем пытался скомпилировать приведенный выше пример, поэтому, пожалуйста, простите любые грамматические ошибки.

1 Ответ

2 голосов
/ 19 сентября 2011

Хм, на основе вашего 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")]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...