流畅接口是由无上下文或正则语法描述的吗?

3

我在玩弄马丁·福勒文本中描述的流畅接口风格,我想知道他们所描述的语法是上下文无关还是正则的?我说的是这样的接口:

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

我想编写一个能够生成程序的代码,目前需要输入上下文无关文法,但我似乎有些困难将其转换为源代码应用。我怀疑只能使用常规语法,因为不能确定“堆栈”的状态,每个“终端”方法的结果必须预先知道。
我现在有的代码可以工作,但在某些语法上出现错误。
编辑:我选择了常规语法,该代码已经开源并且可以工作,如果有人想玩一下,请访问https://github.com/Dervall/Snout

它应该是C#中的属性,作为一个示例语言。 - Dervall
确实,我的错误。我错过了var并且由于Fowler的提及而假设为Java。顺便说一句,从CFG生成这个的想法很棒! - Matt Ball
至少这是个想法,但我认为我们不得不采用常规语法,否则我会写出有缺陷的代码。 :) - Dervall
1个回答

2
任何时刻可用的选项集由该点上类可用的方法决定。由该方法返回的类确定下一组方法。
因此,生成该链的文法规则是一个右线性文法,其中起始符号为类,符号为方法,非终结符为方法返回的类。
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

忽略方法参数(int):
Car -> "configure" Configurator
Configurator -> "with" Configurator
Configurator -> "and" Configurator
Configurator -> "wheels" Configurator
Configurator -> "windows" WindowDetails
WindowDetails -> "transparent" Configurator
WindowDetails -> "tinted" Configurator

但是这没有涵盖到车轮的参数(即车轮数量)的论点。由于不同的整数参数可能导致不同的类别(例如,在“(2)”之后,您是否有一个Configurator或WindowDetails?),因此常规语法无法处理它。
Configurator -> "wheels" Integer
Configurator -> "windows" Integer
Integer -> ?

所以这取决于你想要什么。方法链可以用正则语法描述,但正则语法不能描述传递给方法的参数。据我所知。
如果添加上上下文无关语法的复杂性,就可以处理参数,因为这样你可以做类似这样的事情:
Configurator -> "wheels" Integer Configurator
Configurator -> "windows" Integer WindowDetails

这里的“额外信息”是指整数参数之后需要继续进行的信息。 注意:上述假设方法名称在所有类中都是唯一的。如果您有两个不同的类具有相同的方法名称,则会出现问题,显然(我希望如此)(如果您使用“with”和“and”之类的东西,这种情况可能并不罕见...)。

我不介意不处理参数,因为我们需要在编译时知道返回的类是什么,以便呈现下一组选项。但你的意思是语法类是 正则语法而不是 上下文自由 的,对吗? - Dervall
以上使用了正则语法。在简单的方法链中,我看不到需要上下文无关语法的必要性。它们只需要处理参数(过于简化,但任何带括号的东西都倾向于暗示上下文无关,因为一旦括号关闭,你需要“弹回”到之前正在做的事情)。所以,“是的”。请参见更新。 - andrew cooke
我明白了,我尝试使用普通的LR分析表来生成“状态”类,但问题是,你无法根据单个状态确定哪个状态将成为规约的目标。当然,我可以生成ExpandoObject并跟踪堆栈,但那样我就没有语法高亮了,这也是重点所在。看起来正则文法是正确的选择。 - Dervall
我不理解LR分析,所以无法帮助你了解细节。但是,由于正则语法是上下文无关语法的子集,我认为你应该能够使其工作。https://en.wikipedia.org/wiki/Chomsky_hierarchy - 正则语法真的很简单。它几乎只能做方法链。一个上下文无关语法可以做更多(包括方法链)。 - andrew cooke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接