Свободные интерфейсы описываются контекстно-свободными или регулярными грамматиками? - PullRequest
3 голосов
/ 25 марта 2012

Я играю с беглыми интерфейсами в стиле текста Мартина Фаулера, и мне интересно, является ли описываемая ими грамматика контекстно-свободной или регулярной?Я говорю об интерфейсах, таких как этот:

var car = new Car();
car.Configure().MakeCar.With.Wheels(4).And.Engine.Using.Petrol;

Я пытаюсь написать программу, которая может их генерировать.В настоящее время требуется ввод контекстно-свободной грамматики, но у меня, похоже, есть некоторые трудности в преобразовании этого в приложение с исходным кодом.Я подозреваю, что ответ заключается в том, что я могу обращаться только к обычным грамматикам, поскольку состояние «стека» не может быть известно, так как результат каждого «терминального» метода должен быть известен заранее.

То, что у меня сейчас есть, работает, но оно не работает на определенных грамматиках.

Редактировать: Я перешел на обычные грамматики, код с открытым исходным кодом и работает сейчасесли кто-то хочет поиграть с ним.https://github.com/Dervall/Snout

1 Ответ

2 голосов
/ 25 марта 2012

набор опций в любой точке определяется методами, доступными в классе в этой точке. класс, возвращаемый этим методом, определяет следующий набор методов.

так что правила для грамматики, которая генерирует цепочку, это правильная правильная грамматика , где начальные символы - это классы, символы - это методы, а нетерминалы - это классы, возвращаемые методами:

class Car:
    configure: Configurator

class Configurator:
    with: Configurator // noise method
    and: Configurator // noise method
    wheels: int -> Configurator
    windows: int -> WindowDetails

class WindowDetails:
    transparent -> Configurator
    tinted -> Configurator

игнорирование метода args (int):

Car -> "configure" Configurator
Configurator -> "with" Configurator
Configurator -> "and" Configurator
Configurator -> "wheels" Configurator
Configurator -> "windows" WindowDetails
WindowDetails -> "transparent" Configurator
WindowDetails -> "tinted" Configurator

но то, что это не в состоянии уловить, является аргументом в пользу колес (количество колес). и обычная грамматика не может справиться с этим, потому что разные целочисленные аргументы могут привести к разным классам (например, после "(2)" у вас есть Конфигуратор или WindowDetails?):

Configurator -> "wheels" Integer
Configurator -> "windows" Integer
Integer -> ?

так что это зависит от того, что вы хотите. цепочка методов может быть описана регулярной грамматикой. но обычная грамматика также не может описывать аргументы, передаваемые методам. AFAICT.

вы можете обрабатывать аргументы, добавляя сложность контекстно-свободных грамматик, потому что тогда вы можете сделать что-то вроде:

Configurator -> "wheels" Integer Configurator
Configurator -> "windows" Integer WindowDetails

с дополнительной информацией, необходимой для правильного продолжения после целочисленного аргумента.

ПРИМЕЧАНИЕ : приведенное выше предполагает, что имена методов уникальны для всех классов. если у вас есть два разных класса с одним и тем же именем метода, тогда у вас будут проблемы, очевидно (я надеюсь) (и это может быть не так уж редко, если вы используете такие вещи, как «с» и «и» ....)

...