メタ開発環境ViennaTalkにおけるパーサコンビネータの応用
小田朋宏Software Research Associates, Inc.2015/12/18 @宮崎
agenda
パーサコンビネータ
ViennaTalk での実装ViennaVDMGrammarViennaVDMParserViennaVDM2SmalltalkTranslator
ViennaTalk が目指す「メタ開発環境」開発環境を開発するための開発環境仕様の世界と実装の世界を同じ「メタ」に乗せるDynabook的な「コンピューティングメディア」
パーサコンビネータ
パーサコンビネータ
「小さな」パーサを組み合わせて「大きな」パーサを「構成する」
PEG (Parser Expression Grammar)の実装が多い
Haskell の Parsec が有名Smalltalk では PetitParserVDM-SL では VCParser
PEG (Parser Expression Grammar)
● アトム(終端記号、非終端記号、空)● e1 e2 (連結)● e1 / e2 (逐次的選択)● e* (0回以上の繰り返し)● e+ (1回以上の繰り返し)● e? (eまたは空)● 述語
&e (eが受理可能で空を受理する)!e (eが受理不可能で空を受理する)
簡単なPEGパーサコンビネータの例
例:(ここでは連結を, 、*をstarで表記)'a' ↦「a」を受け付けるパーサ
'b' ↦「b」を受け付けるパーサ
'a' , 'b' ↦「ab」を受け付けるパーサ
'a' / 'b' ↦「a」または「b」'a' star ↦ 0個以上の連続した「a」
ViennaTalkでの実例
VDM10 Language Manual での定義multiple assign statement
= ‘atomic’, ‘(’
assign statement, ‘;’, assign statement,
[ { ‘;’, assign statement } ], ‘)’ ;
ViennaTalkでの実際のコード((self reserved: 'atomic') , lparen ,
assignStatement , semicolon, (assignStatement separatedBy: semicolon) withoutSeparators , rparen)
PEGパーサコンビネータの利点
パーサジェネレータと比べて、複数の「ソース」を管理せずに済む
構文定義とパーサの振る舞いの対応が見やすいソースコードの見た目をPEG文法表記に似せることができる文字列/配列操作と同じ演算子を使うことで受け付ける文字列をイメージしやすい
フォーマッタと併せて開発するとコードの共通化や相互にテストすることができる
PetitParser
Lukas Renggli氏によるPharo Smalltalk上のPEGパーサコンビネータ
文法と出力を分離して実装することができるViennaVDMGrammar : PEGによる構文定義
ViennaVDMParser : 抽象構文木を出力ViennaVDM2SmalltalkTranslator
Smalltalkを出力
ViennaTalk での実装
ViennaVDMGrammar
blockStatement^ (lparen , self dclStatement star , (statement separatedBy: semicolon) withoutSeparators ,semicolon optional , rparen)
==> [ :quin | | decls statements |decls := quin second.statements := quin third.{decls.statements} ]
ViennaVDMParser
blockStatement^ super blockStatement==> [ :array |
ViennaNodelabel: 'BlockStatement'withAll: array first , array second ]
ViennaVDM2SmalltalkTranslator
blockStatement^ super blockStatement
==> [ :array | | decls statements vars |decls := array first.statements := array second.vars := decls inject: #() into: [ :vs :decl | vs ,
decl first ].'[|' , (' ' join: vars) , '|' , ('.' join: (decls collect:
#second) , statements) , '] value.' ]
実行例: ViennaVDMGrammar
ViennaVDMGrammar new blockStatementparse: '(dcl a:nat := 0; return a)'
結果#(#(#(#('a' 'nat' '0'))) #('a'))
実行例:ViennaVDMParser
ViennaVDMParser new blockStatementparse: '(dcl a:nat := 0; return a)'
結果(BlockStatement
(DclStatement (AssignmentDefinition 'a' (BasicType 'nat') (SymbolicLiteral '0')))
(ReturnStatement (LocalName 'a')))
実行例:ViennaVDM2SmalltalkTranslator
ViennaVDMParser new blockStatementparse: '(dcl a:nat := 0; return a)'
結果'[|a|a := 0.thisContext viennaReturn: a] value.'
ViennaTalk が目指す「メタ開発環境」
ViennaTalk の現況
メタ開発環境開発環境を開発するための開発環境
仕様の世界と実装の世界を同じ「環境」に乗せる
Dynabook的な「コンピューティング環境」
仕様の世界と実装の世界を同じ「環境」に乗せる
従来のジェネレータのアプローチ仕様から実装を生成する仕様と実装は別々のアーティファクト100%仕様→ 100%実装
ViennaTalkの場合VDM-SLの値 = Smalltalkオブジェクト仕様と実装が同じバイトコードにコンパイルされ実行される
仕様と実装を区別する必要がない漸次的実装(仕様と実装を同時に成長させていく)
トランスレータの現況
ViennaVDM2SmalltalkTranslatorVDM から Smalltalk の自動生成VDM-SLのフラットな仕様をカバー
ただし以下の機能を除く静的型検査動的型検査pre/post/invの実行時検査
独自言語拡張Smalltalk statement
`Smalltalk code`
新しい開発環境(1)VDM->Smalltalk translator
VDM-SLワークスペース
生成されたSmalltalkプログラムVDM-SL仕様
Evaluate it Print it
Evaluate itTranslate it
新しい開発環境(2)VDM->AST translator
生成されたASTVDM-SL仕様
漸次的実装(progressive implementation)
1. 全てがVDM-SL仕様
2. 大部分がVDM-SL仕様、一部が実装言語で記述
3. VDM-SL仕様と実装が混在
4. 大部分が実装、一部がVDM-SL仕様
5. 全てがVDM-SL仕様
今後の予定
ViennaTalkの今後の予定
今年度Web APIの実装VDM-SL フォーマッタの実装ViennaObject, ViennaCompiler の実装
Smalltalk の System Browser 上でVDM-SLの文法でメソッドを記述できるようにする
来年度template VDM, meta VDM の言語設計と実装VDM-SL slicingVDM++やVDM-RTのパーサ
番外編:なぜかくもVDM-SLなのか
VDM++のオブジェクトシステムがSmalltalkのオブジェクトシステムとあまりうまく整合しないため。
ADTベース vs メッセージングベース型システムの違い'=' 演算子のセマンティクス
オブジェクトの仕様をフラットな VDM-SLで記述するほうが素直。ただしVDM++やVDM-RTから構文要素を借りることは十分にありうる
番外編2:pre formal と post formal
形式手法への批判「仕様を完全に書き終わった後でないと何も動かない」
答えはNO形式仕様と実装は同時に始まり同時に終わる
post formal ≠ design, implementationpost formal = 開発終了
pre formal → early formal → rigor formalplanning creativity
productivity