奥斯陆
2008年10月28日
奥斯陆是微软的一个项目,人们对其有所耳闻,但直到本周的PDC大会才公布了一些细节。我们所知的是,它与模型驱动软件开发和领域特定语言有关。
几周前,我和我的语言专家同事丽贝卡·帕森斯提前预览了PDC的发布演讲,与唐·博克斯、乔·德拉·利贝拉和维杰·拉吉一起。这是一个非常有趣的演示,足以让我相信奥斯陆是一项值得关注的技术。它本质上是一个语言工作台。我不会在这里尝试对该工具进行全面回顾,而只是分享我从演示中获得的一些零散印象。它确实很有趣,我认为我应该在这里发布我的感想。随着PDC的公开发布,我相信在接下来的几周内你将听到更多关于它的消息。在描述我的想法时,我将使用很多我在我的书中开发的语言,所以你可能会发现术语有点密集。
奥斯陆有三个主要组件
- 一种用于文本DSL的建模语言(目前代号为M)
- 一个用于图形DSL的设计界面(名为Quadrant)
- 一个存储库(没有名称),它在关系数据库中存储语义模型。
(所有这些名称都是当前的代号。营销部门将继续使用相同的智慧,将“Avalon和Indigo”替换为“WPF和WCF”。我只是希望他们能将“Windows”重命名为“Windows技术基础”。)
文本语言环境是自举的,并提供三种基本语言
- MGrammar:定义语法制导翻译的语法。
- MSchema:定义语义模型的模式。
- MGraph:是一种用于表示语义模型种群的文本语言。因此,虽然MSchema表示类型,但MGraph表示实例。Lisp程序员可能会将MGraph视为具有丑陋语法的s表达式。
你可以在MGraph中表示任何模型,但语法通常不太好。使用MGrammar,你可以为自己的DSL定义语法,这允许你用自己的DSL编写脚本,并构建一个解析器将它们转换为更有用的东西。
使用我书中介绍的状态机示例,你可以使用MSchema定义一个状态机语义模型。然后,你可以用MGraph(以一种丑陋的方式)填充它。你可以使用MGrammar构建一个体面的DSL来填充它,以定义语法并驱动解析器。
有一个语法编译器(称为mg
),它将接收MGrammar中的输入文件并将其编译成他们称为图像文件或.mgx文件的东西。这与大多数解析器生成工具不同。大多数解析器生成工具接收语法并生成代码,这些代码必须编译成解析器。相反,奥斯陆的工具将语法编译成解析规则的二进制形式。然后有一个单独的工具(mgx
)可以接收输入脚本和已编译的语法,并输出输入脚本的语法树的MGraph表示。
更有可能的是,你可以将已编译的语法作为资源添加到自己的代码中。有了它,你可以调用奥斯陆作为.NET框架提供的通用解析器机制,提供对已编译语法文件的引用,并生成一个内存中的语法树。然后,你可以遍历这棵语法树,并用它来做任何你想做的事情——我称之为树构建的解析策略。
解析器为你提供了语法树,但这通常与语义模型不同。因此,你通常会编写代码来遍历树并填充用MSchema定义的语义模型。完成此操作后,你可以轻松地获取该模型并将其存储在存储库中,以便可以通过SQL工具访问它。他们的演示展示了通过DSL输入一些数据并访问存储库中相应的表,尽管我们没有深入到复杂的结构。
你也可以使用Quadrant来操作语义模型实例。你可以为模式定义一个图形表示法,然后系统可以投影模型实例,使用该表示法创建图表。你也可以更改图表,这将更新模型。他们展示了对模型的两个图形投影的演示,更新一个会使用观察者同步更新另一个。通过这种方式,使用Quadrant似乎与MetaEdit之类的图形语言工作台类似。
在开发奥斯陆的过程中,他们一直在其他微软项目中使用它,以积累使用经验。到目前为止,主要项目包括ASP、工作流和Web服务。
更多关于M的信息
我们大部分时间都在研究文本环境。他们有一种方法可以将已编译的语法连接到文本编辑控件,以提供具有各种完成和突出显示功能的语法感知文本编辑器。然而,与MPS之类的工具不同,它仍然是一个文本编辑器。因此,你可以自由地剪切和粘贴文本片段并操作文本。如果解析你所做的操作时出现问题,该工具会给你一些波浪线,但它会保留文本编辑体验。
我认为我喜欢这一点。当我第一次遇到它时,我相当喜欢MPS的理念:“它看起来像文本,但实际上它是一个结构化编辑器”。但最近我开始认为我们因此失去了很多东西,所以奥斯陆的工作方式很有吸引力。
他们拥有的另一个不错的文本语言工具是帮助编写MGrammars的编辑器。这是一个分成三个垂直窗格的窗口。中间窗格包含MGrammar代码,左窗格包含一些输入文本,右窗格显示使用MGrammar解析输入文本的MGraph表示。它非常以示例为驱动。(但是它是临时的,不像测试。)该工具类似于ANTLR中直接使用语法处理示例文本的功能。在谈话中,丽贝卡将这种风格称为“轶事测试”,这是一个我必须记住偷来的短语。
他们使用的解析算法是GLR解析器。语法语法与EBNF相当,并且具有用于树构建表达式的符号。他们在词法分析器中使用他们自己的正则表达式符号变体,以使其与他们的其他工具更一致,这可能会让像我这样更习惯于ISO/Perl正则表达式符号的人感到困扰。它大多相似,但不同之处足以让人讨厌。
他们语法符号的一个不错的功能是,他们提供了构造来轻松创建参数化规则——有效地允许你编写规则子例程。规则也可以被赋予属性(也称为注释),类似于.NET的语言属性。因此,你可以通过使用属性标记语言来使整个语言不区分大小写。(有趣的是,他们使用“@”来标记属性,就像Java语法一样。)
运行语法的默认方式是进行树构建。事实证明,树构建是语法在处理一些输入时调用的默认类的行为。此类有一个接口,你可以编写自己的类来实现它。这将允许你进行嵌入式翻译和嵌入式解释。它与代码操作不同,因为操作代码不在语法中,而是在这个其他类中。我认为这可能更好,因为操作内部的代码经常会淹没语法。
他们谈论了一些将一种语言嵌入另一种语言并优雅地切换解析器以处理这种情况的能力——进入Converge已经探索过的领域。我们没有深入研究这一点,但这将很有趣。
他们提到的一个有趣的小细节是,他们最初打算只为图形语言提供工具。然而,他们发现图形语言对于许多问题并不适用——包括定义模式。因此,他们开发了文本工具。
(这是给营销部门的一个想法。如果你坚持使用“M”这个名字,你可以使用这部优秀的电影作为营销灵感;-))
比较
显然,该工具与Intentional Software和JetBrains MPS之类的工具处于同一空间,我在2005年将它们称为语言工作台。奥斯陆并不完全符合我当时给出的语言工作台的定义。特别是文本组件不是一个投影编辑器,你也不必使用基于抽象表示(语义模型)的存储表示,相反,你可以以更传统的方式存储文本源。这种对持久抽象表示的依赖较少类似于Xtext。在某个时候,我确实需要重新思考我认为语言工作台的定义元素是什么。目前,让我们说Xtext和奥斯陆感觉像语言工作台,在我重新审视定义之前,我会将它们视为语言工作台。
在这个比较中,一个特别有趣的地方是将奥斯陆与微软的DSL工具进行比较。它们是不同的工具,有很多重叠,这让你想知道它们是否都有存在的空间。我听到过一些模糊的“它们可以协同工作”的短语,但我还没有被说服。这可能是那些(在大公司中很常见)的情况之一,其中多个半竞争的项目正在开发。最终,这可能导致其中一个被搁置。但很难对此进行推测,因为这在很大程度上取决于公司政治,因此几乎不可能从任何人那里得到一个直接的答案(即使你得到了,也很难判断它是否是一个直接的答案)。
奥斯陆与其同类产品共享的关键要素是,它提供了一个工具包来定义新的语言,将它们集成在一起,并为这些语言定义工具。因此,你获得了外部领域特定语言的语法自由度以及良好的工具——这解决了外部DSL的主要缺点之一。
奥斯陆支持文本和图形DSL,并且似乎对它们都进行了合理地支持(尽管我们在文本上花费了更多时间)。在这方面,它似乎提供了比MPS和Intentional(结构化文本)以及MetaEdit/微软的DSL工具(图形)更多样化的选择。它在文本支持方面也与众不同,因为它提供了真正的自由文本输入,而不是Intentional/MPS的高度结构化文本输入。
使用一个可以插入文本编辑器的已编译语法,我认为这是一种支持输入DSL脚本的非常好的方法。其他工具要么要求你拥有完整的语言工作台机制,要么使用代码生成来构建编辑器。传递一个我可以插入编辑器的语法表示,我认为这是一种很好的方法。当然,如果该语言工作台是开源的(据我所知,MPS将是开源的),那么这可能会使这个问题变得无关紧要。
将这类东西存储在存储库中的一个大问题是处理版本控制。我们可以在一个共享数据库(道德上等同于一个团队在一个共享驱动器上编辑其代码的一个副本)上进行协作的想法,我认为这几乎是不负责任的。因此,我倾向于对任何建议这种方法的供应商持怀疑态度。奥斯陆团队明智地建议,你将文本文件视为权威来源,这允许你使用常规的版本控制工具。当然,对于许多微软商店来说,坏消息是该工具是TFS(或者,天哪,VSS),但使用纯文本文件作为源代码的巨大优势是,你可以使用众多版本控制系统中的任何一个来存储它。
我个人很喜欢大多数工具倾向于运行时解释而不是代码生成和编译。传统上,解析器生成器和许多语言工作台都假设您将从模型生成代码而不是解释它们。代码生成很好,但它总是有一种凌乱的感觉,并且往往会导致各种绊倒你的方式。因此,我更喜欢运行时重点。
我只用了几个小时,所以不能对 Oslo 做出任何深远的判断。但是,我可以说它看起来像是一项非常有趣的技术。我喜欢它的地方是它似乎提供了一条使用语言工作台的良好途径。微软的支持将是一件大事,尽管我们确实需要记住,关于 Longhorn 的承诺很多都没有实现。但总的来说,我认为这是语言工作台场景中一个有趣的补充,也是一个可以使 DSL 更加普遍的工具。