MDSF:LOP-使用MPS来做个计算器的示例
在上一篇面向語言編程LOP(Language Oriented Programming)方法介紹中介紹了LOP以及一種LOP的實(shí)現(xiàn)方法MPS,本篇主要講解一下使用MPS1.5的一個(gè)示例,以便大家能更好的理解是如何使用MPS實(shí)現(xiàn)LOP項(xiàng)目的。
需求
計(jì)算一個(gè)Java/PHP開發(fā)人員的收入,輸入在Java和PHP項(xiàng)目投入的時(shí)間,計(jì)算器自動(dòng)計(jì)算收入值,界面表示如下:
目標(biāo)
通過寫以下4行代碼來生成這個(gè)計(jì)算器(10和5是常量)
?
view sourceprint?| 1 | calculator MySalary |
| 2 | input PHP Hours |
| 3 | input Java Hours |
| 4 | output Java Hours*10 + PHP Hours*5 |
?
主要步驟
- 生成前面目標(biāo)中提到的語法的一種語言來實(shí)現(xiàn)計(jì)算器。語言定義基本的邏輯概念、組成規(guī)范、關(guān)系以及各自的行為
- 生成一個(gè)生成器,定義構(gòu)建swing應(yīng)用程序的規(guī)則
- 使用我們創(chuàng)建的語言來實(shí)現(xiàn)一個(gè)計(jì)算器
下面主要講解一下語言定義部分,代碼生成器部分請(qǐng)參考MPS1.5的示例
生成項(xiàng)目
生成一個(gè)新的項(xiàng)目,項(xiàng)目名為:calculator
按Next后,生成一種新的語言,設(shè)定語言命名空間為:?jetbrains.mps.tutorial.calculator(命名空間一般為companyName.meaningful.name)
再按Next,生成一種新的方案(方案是一套特定語言的模型):
理想情況下,語言和使用語言的方案是分離的兩個(gè)項(xiàng)目,但是建議在生成語言時(shí)把這個(gè)項(xiàng)目放在一起,便于測試新的語言。
按Finish后進(jìn)入項(xiàng)目視圖,默認(rèn)展開語言項(xiàng)目jetbrains.mps.tutorial.calculator()節(jié)點(diǎn):
語言項(xiàng)目下有多個(gè)節(jié)點(diǎn),這些節(jié)點(diǎn)前面都帶有M圖標(biāo),分別代表模型的不同方面:
- structure:描述語言語法
- editor:描述編寫語言時(shí)的編輯器
- constraints:描述一些約束
- type system:描述如何計(jì)算節(jié)點(diǎn)類型
jetbrains.mps.tutorial.calculator.sandbox()表示我們的測試方案節(jié)點(diǎn),Modules Pool() 包含一系列可以參考使用的語言和方案,后面會(huì)再介紹這些內(nèi)容。
?
下面我們開始來建立Calculator語言
Calculator概念(concept)
就像類定義它的實(shí)例字段、方法和其他成員的結(jié)構(gòu)一樣,概念定義它的實(shí)例屬性、引用和子概念定義的結(jié)構(gòu)。概念是可以繼承的,缺省每一個(gè)概念都從BaseConcept繼承下來,它將會(huì)繼承父概念的所有屬性、子概念和引用等結(jié)構(gòu)。首先我們需要生成一個(gè)新的概念:Calculator。設(shè)置instance can be root為true,實(shí)現(xiàn)INamedConcepts接口以便具有Name屬性,
?
提示:按Tab/Shift+Tab可以導(dǎo)航編輯焦點(diǎn)<> ;按Ctrl+Space可以打開自動(dòng)完成提示列表
生成一個(gè)編輯器
MPS編輯器看上去是文本編輯器,但是它是一個(gè)直接使用語法樹的一個(gè)結(jié)構(gòu)化編輯器。編輯器使用單元格(cells)來表示概念節(jié)點(diǎn),這里有以下幾種節(jié)點(diǎn)類型:
- 屬性單元格: 編輯節(jié)點(diǎn)屬性
- 常量單元格:顯示常量值
- 集合單元格:在內(nèi)部嵌套其他單元格
前面定義了概念calculator,它的編輯器應(yīng)該為:calculator name
選擇Calculator概念的【Editor】頁簽,新增一個(gè)概念編輯器,
在‘calculator’常量單元格編輯器后按Enter鍵,通過‘{’選擇屬性name:{name}
測試一下概念編輯器
在語言項(xiàng)目中,點(diǎn)擊右鍵選擇 Generate Language 來生成語言。生成之后,我們?cè)诜桨疙?xiàng)目新建一個(gè)模型:
在 Model name中輸入類型 jetbrains.mps.tutorial.calculator.sandbox
把jetbrains.mps.tutorial.calculator語言加入到Model Properties對(duì)話框的Used Languages中,這樣才能使用這個(gè)語言來編寫應(yīng)用:
在測試模型sandbox中新建一個(gè)Calculator概念測試應(yīng)用,顯示如下:
?
到現(xiàn)在我們已經(jīng)簡單建立了第一條語言,下面建立輸入字段概念
給Calculator加上子概念I(lǐng)nputField
新建一個(gè)InputField概念,設(shè)置instance can be root為false,實(shí)現(xiàn)INamedConcepts接口以便具有Name屬性,然后再生成編輯器:[- input { name } -]
為了使得計(jì)算器包含輸入字段,需要把InputField類型作為Calculator概念子對(duì)象:
選擇在Calculator編輯器中的屬性name,按Alt+Enter彈出意圖列表,選擇Add New Line
為了每個(gè)輸入字段顯示一行,我們可以對(duì)子對(duì)象InputField選擇Add newline for children意圖:
按Ctrl+F9重新生成語言后,再次進(jìn)入應(yīng)用界面:
輸出概念:OutputField
生成一個(gè)默認(rèn)的輸出概念:OutputField,編輯器如下:
把OutputField添加到calculator概念子對(duì)象中:
Calculator編輯器更改如下:
現(xiàn)在我們能夠在outfield中輸入任何表達(dá)式:
添加表達(dá)式支持
MPS中有基礎(chǔ)語言,新的語言使用它們需要讓自己的語言擴(kuò)展基礎(chǔ)語言。現(xiàn)在我們需要使用表達(dá)式功能,打開語言屬性對(duì)話框:
在Dependencies 頁簽中的Extended Languages 列表選擇jetbrains.mps.baseLanguage:
BaseLanguage包含一個(gè)Expression概念,它表示一個(gè)表達(dá)式,格式如"2", "2+3", "abc+abc"等。這個(gè)就是我們這里示例中output需要的。
現(xiàn)在給OutputField添加expression子類型:
更改編輯器:
現(xiàn)在可以輸入表達(dá)式,但是還不能通過input計(jì)算,應(yīng)用界面如下:
擴(kuò)展表達(dá)式概念
為了支持通過input來計(jì)算,我們需要生成自己的表達(dá)式類型。建立概念InputFieldReference,從Expression繼承下來,添加InputField為引用概念field
生成InputFieldReference編輯器:%field%-> {name}表示引用概念屬性
應(yīng)用界面如下:MPS的智能引用會(huì)在當(dāng)前上下文決定哪些引用可以使用,這里自動(dòng)完成列表會(huì)列出width
定義生成器
MPS生成器語言使用兩種參數(shù)引用:property macros (marked with $) andnode macros ($$)。
我更關(guān)注的是前面語言定義部分,這部分還沒有具體看,剛興趣的可以參考MPS1.5的示例
?
?
MPS網(wǎng)站
?Download MPS
?A Language Workbench in Action - MPS
?
歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明:轉(zhuǎn)載自周金根 [ http://zhoujg.cnblogs.com/ ]
轉(zhuǎn)載于:https://blog.51cto.com/zhoujg/517108
總結(jié)
以上是生活随笔為你收集整理的MDSF:LOP-使用MPS来做个计算器的示例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 企业文件服务器资源管理方案
- 下一篇: 各大型网站架构分析收集Z