Are fluent interfaces described by contextual or regular grammars?

I'm playing around with fluid interfaces in the style of Martin Fowlers' text, and I'm wondering if the grammar they describe is contextual or normal? I'm talking about interfaces like:

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

      

What I am trying to do is write a program that can generate them. Currently it requires entry into a context free grammar, but it seems to me that there is some difficulty converting this into a source code application. I suspect the answer is that I can only use regular grammars, since the state of the "stack" cannot be known, since the result of each "terminal" method must be known in advance.

Now I have works, but this is on some grammars.

Edit: I went with regular grammars, the code is open source and now works in case anyone wants to play around with it. https://github.com/Dervall/Snout

+3


source to share


1 answer


the set of options at any point is determined by the methods available in the class at that point. the class returned by this method defines the following set of methods.

so the grammar rules that generate the chaining are the correct regular grammar , where start characters are classes, characters are methods, and non-terminal are classes returned by methods:

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

      

ignoring the args (int) method:

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

      

but what this fails to capture is the argument to wheels (number of wheels). and a regular grammar can't handle it because different integer arguments can result in different classes (for example after "(2)" do you have a configurator or WindowDetails?):



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

      

so it depends what you want. the method chain can be described by a regular grammar. but a regular grammar cannot describe the arguments passed to methods either. AFAICT.

you can handle the arguments by adding the complexity of context free grammars, because then you can do something like:

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

      

which has the extra information needed to proceed correctly after an integer argument.

NOTE : the above assumes that method names are unique across all classes. if you have two different classes with the same method name then you are in trouble, obviously (I hope) (and it may not be that uncommon if you use things like "with" and "and" ... .)

+2


source







All Articles