MDSF:LOP-使用MPS来做个计算器的示例

简介:

在上一篇面向语言编程LOP(Language Oriented Programming)方法介绍中介绍了LOP以及一种LOP的实现方法MPS,本篇主要讲解一下使用MPS1.5的一个示例,以便大家能更好的理解是如何使用MPS实现LOP项目的。

需求

计算一个Java/PHP开发人员的收入,输入在Java和PHP项目投入的时间,计算器自动计算收入值,界面表示如下:

目标

通过写以下4行代码来生成这个计算器(10和5是常量)

 

1 calculator MySalary
2 input PHP Hours
3 input Java Hours
4 output Java Hours*10 + PHP Hours*5

 

主要步骤

  • 生成前面目标中提到的语法的一种语言来实现计算器。语言定义基本的逻辑概念、组成规范、关系以及各自的行为
  • 生成一个生成器,定义构建swing应用程序的规则
  • 使用我们创建的语言来实现一个计算器
  看起来完成这个示例使用现有语言会更快些,但是这里我们的意图是想展示是当你如何使用MPS来建立一种特定功能的语言。

下面主要讲解一下语言定义部分,代码生成器部分请参考MPS1.5的示例

生成项目

生成一个新的项目,项目名为:calculator

按Next后,生成一种新的语言,设定语言命名空间为: jetbrains.mps.tutorial.calculator命名空间一般为companyName.meaningful.name)

再按Next,生成一种新的方案(方案是一套特定语言的模型):

理想情况下,语言和使用语言的方案是分离的两个项目,但是建议在生成语言时把这个项目放在一起,便于测试新的语言。

按Finish后进入项目视图,默认展开语言项目jetbrains.mps.tutorial.calculator()节点: 

语言项目下有多个节点,这些节点前面都带有M图标,分别代表模型的不同方面:

  • structure:描述语言语法
  • editor:描述编写语言时的编辑器
  • constraints:描述一些约束
  • type system:描述如何计算节点类型

jetbrains.mps.tutorial.calculator.sandbox)表示我们的测试方案节点,Modules Pool() 包含一系列可以参考使用的语言和方案,后面会再介绍这些内容。

 

下面我们开始来建立Calculator语言

Calculator概念(concept)

  就像类定义它的实例字段、方法和其他成员的结构一样,概念定义它的实例属性、引用和子概念定义的结构。概念是可以继承的,缺省每一个概念都从 BaseConcept继承下来,它将会继承父概念的所有属性、子概念和引用等结构。  

  首先我们需要生成一个新的概念:Calculator。设置instance can be roottrue,实现INamedConcepts接口以便具有Name属性,

 

提示:Tab/Shift+Tab可以导航编辑焦点<> ;按Ctrl+Space可以打开自动完成提示列表

生成一个编辑器

  MPS编辑器看上去是文本编辑器,但是它是一个直接使用语法树的一个结构化编辑器。编辑器使用单元格(cells)来表示概念节点,这里有以下几种节点类型:

  • 属性单元格: 编辑节点属性
  • 常量单元格:显示常量值
  • 集合单元格:在内部嵌套其他单元格

前面定义了概念calculator,它的编辑器应该为:calculator name

选择Calculator概念的【Editor】页签,新增一个概念编辑器,

  1. 添加一个缩进集合类型编辑器:[-
  2. 输入常量:calculator
  3. 建立一个属性单元格编辑器
    在‘calculator’常量单元格编辑器后按Enter键,通过‘{’选择属性name:{name}

测试一下概念编辑器

  在语言项目中,点击右键选择 Generate Language 来生成语言。生成之后,我们在方案项目新建一个模型:

在 Model name中输入类型 jetbrains.mps.tutorial.calculator.sandbox

jetbrains.mps.tutorial.calculator语言加入到Model Properties对话框的Used Languages中,这样才能使用这个语言来编写应用:

在测试模型sandbox中新建一个Calculator概念测试应用,显示如下:

 

到现在我们已经简单建立了第一条语言,下面建立输入字段概念

给Calculator加上子概念InputField

新建一个InputField概念,设置instance can be rootfalse,实现INamedConcepts接口以便具有Name属性,然后再生成编辑器:[- input { name } -]

为了使得计算器包含输入字段,需要把InputField类型作为Calculator概念子对象:

选择在Calculator编辑器中的属性name,按Alt+Enter弹出意图列表,选择Add New Line

为了每个输入字段显示一行,我们可以对子对象InputField选择Add newline for children意图:

Ctrl+F9重新生成语言后,再次进入应用界面:

输出概念:OutputField

生成一个默认的输出概念:OutputField,编辑器如下:

把OutputField添加到calculator概念子对象中:

Calculator编辑器更改如下:

现在我们能够在outfield中输入任何表达式:

添加表达式支持

MPS中有基础语言,新的语言使用它们需要让自己的语言扩展基础语言。现在我们需要使用表达式功能,打开语言属性对话框:

Dependencies 页签中的Extended Languages 列表选择jetbrains.mps.baseLanguage:

BaseLanguage包含一个Expression概念,它表示一个表达式,格式如"2", "2+3", "abc+abc"等。这个就是我们这里示例中output需要的。

现在给OutputField添加expression子类型:

更改编辑器:

现在可以输入表达式,但是还不能通过input计算,应用界面如下:

扩展表达式概念

为了支持通过input来计算,我们需要生成自己的表达式类型。建立概念InputFieldReference,从Expression继承下来,添加InputField为引用概念field

生成InputFieldReference编辑器:%field%-> {name}表示引用概念属性

应用界面如下:MPS的智能引用会在当前上下文决定哪些引用可以使用,这里自动完成列表会列出width

定义生成器

  MPS生成器语言使用两种参数引用:property macros (marked with $) andnode macros ($$)。

  我更关注的是前面语言定义部分,这部分还没有具体看,刚兴趣的可以参考MPS1.5的示例

 

 

MPS网站

 Download MPS

 A Language Workbench in Action - MPS






 本文转自 jingen_zhou 51CTO博客,原文链接:http://blog.51cto.com/zhoujg/517108,如需转载请自行联系原作者





相关文章
VOS3000 AXB功能使用说明
VOS AXB 模块适用于语音市场直连运营商或虚拟运营商 X 号平台的业务需求 与 VOS 系统无缝集成,无需独立服务器部署,节约硬件,网络成本 单机支持不低于 2,000 并发 AXB 呼叫,性能是市面常见 AXB 产品的 2-3 倍 支持设定在呼叫接通后任意时间提前解绑,释放 X 号码资源,无需等到呼叫挂断后释放,大幅提高 X 号码利用率 提供完备的 AXB 计费策略与报表输出,兼容全类型运营商小号接口,保障业务能够平稳开展,持久运营
|
3月前
|
网络协议
PlayAuth+vid播放模式一直显示获取地址出错
极少数用户出现此问题,多数用户都能正常播放
PlayAuth+vid播放模式一直显示获取地址出错
|
8月前
|
Dart 安全 数据安全/隐私保护
Crack App | 某都市魔幻 FM 请求参数 sign 的加密分析
Crack App | 某都市魔幻 FM 请求参数 sign 的加密分析
|
5月前
|
存储 索引
买东西太多折扣套路,使用SwiftUI搭建一个折扣计算器App帮你计算吧(上)
买东西太多折扣套路,使用SwiftUI搭建一个折扣计算器App帮你计算吧(上)
40 1
|
5月前
买东西太多折扣套路,使用SwiftUI搭建一个折扣计算器App帮你计算吧(下)
买东西太多折扣套路,使用SwiftUI搭建一个折扣计算器App帮你计算吧(下)
28 0
某酒店App sign、appcode签名解析(一) 带壳分析 r0tracer
某酒店App sign、appcode签名解析(一) 带壳分析 r0tracer
某酒店App sign、appcode签名解析(一) 带壳分析 r0tracer
|
存储 数据安全/隐私保护 计算机视觉
python 实现dcmtk关联pacs功能 推送下拉影像
1、dcmtk关联pacs的参数介绍 2、dcmtk命令介绍 3、演示工具的功能 4、说明使用的技术 5、遇到的问题 6、工具目前存在的缺点
231 0
python 实现dcmtk关联pacs功能 推送下拉影像
|
Serverless
实验《基于函数计算一键部署掌上游戏机》s deploy报错:Project myFCGame failed to execute
请问怎么解决? 实验《基于函数计算一键部署掌上游戏机》最后一步-部署s deploy,运行报错:Project myFCGame failed to execute
163 1
实验《基于函数计算一键部署掌上游戏机》s deploy报错:Project myFCGame failed to execute
|
算法 数据安全/隐私保护
做个计算器--生成注册码
做个计算器--生成注册码
300 0
|
网络协议 物联网 机器人
阿里云IoT Studio服务开发定时关灯功能示例Demo
IoT Studio服务开发是一个物联网业务逻辑的开发工具,通过编排服务节点的方式快速完成简单的物联网业务逻辑的设计。本文主要使用:定时触发、设备和钉钉机器人节点实现对灯泡的定时控制,并将控制后的结果发送给钉钉机器人。本文以官方文档:定时关灯为基础,针对文档中缺少设备属性上报,钉钉机器人配置参考较老等问题,逐一介绍整个链路的完整实现。
阿里云IoT Studio服务开发定时关灯功能示例Demo