Upload
yuki-igarashi
View
1.018
Download
0
Embed Size (px)
DESCRIPTION
第2回 立命館・全国高校生ソフトウェア創作コンテストICT Challenger +R 2012で発表した際に使用した、プレゼン資料です。 SlideShare向けに、一部修正してあります。
Citation preview
VBCPP (ぶいびーしーぷらすぷらす)
(slideshare用の修正版)
はじめに
鈴木さんと一緒に「HTML5で音ゲー」企画を進めています。(去年の10月頃~)
譜面制作用のエデゖタ、”dosStudio”
を制作しています!
HTML5Step公式サト:
http://html5step.bonprosoft.com/
VBCPPとは
パーサーをプラグンとして追加することで、対応できる言語を増やすことができるコンパラ(のようなもの)
VBCPPが定義する抽象構文木を利用し、パーサーから返ってきたデータを一括管理することで、他の言語で書いた関数、変数、クラス他を利用することもできる
.NETを参照できる為、ラブラリは豊富!
もうちょっと具体的にわかりやすく…
普通のコンパラ VBCPP
ゕニメーションを 使った説明が あります
AST構築 AST修正 バイナリ生成
もう少し詳しく…
ゕニメーションを 使った説明が あります
制作のきっかけ
「この部分を他の言語で記述できたらどうなるのだろう…」という好奇心!
DSLとかを混ぜることができると楽そう!
言語だってプラグンにすれば面白そう!
プラグンなら1人ですべての言語を制作する必要もないため、楽!(共有できる)
もっと気軽に言語処理系を作りたい!
VBCPPの4つの特徴
複数の言語間でデータをやり取りできる
.NET Frameworkを参照できる
名前変換テーブル/ラブラリ機能によって、よりオリジ
ナルの操作感に近づけることができる
2つの型決定方法によりパーサーの負担を減らすことができる
VBCPPの特徴(1)
パーサーから受け取ったデータをVBCPPが一括管理する
→他の言語で書いたクラスや変数、関 数を利用することができます
ex.) VBとC#で共同FizzBuzz等
(お互いが順番にデータを処理し ていく、等)
VBCPPの特徴(2)
.NET Frameworkを参照できる
→ストリーム操作(ex.StreamReader) からフゔル入出力ダゕログ (ex.OpenFileDialog)まで使用するこ とができるため、より高度なゕプリケ ーションを作成することができます。
VBCPPの特徴(3)
名前変換テーブル・ラブラリによって、より言語オリジナルの形に近づけることができる
.NET Frameworkのクラス名・関数名・そして引
数を自由に再定義して使うことができます。
int main() { int num; printf(“hoge”); }
Before -> After
int -> Integerstr -> Stringprintf -> Console.WriteLine
Integer main() { Integer num; Console.WriteLine(“hoge”); }
本来であれば、.NET Framework
を使用する関係上、名前は.NET
Framework準拠でなくてはなりませんが、これらの機能を使うと…
VBCPPの特徴(4)
2つの型決定システムがあり、パーサーの決定を尊重することができる
→パーサーが必要に応じて、IntegerやString等のデータ
型の確定を行うことができます
(もちろんVBCPPに任せることもできます)
•抽象構文木に名前のみを指定し、実行時にVBCPPが自動評価します。
プラグインが
型決定を行わない
•抽象構文木に型を指定し、実行時にはそのままその型が採用されます。
プラグインが
型決定を行う
VBCPPの使い方
VBCPPのバナリ生成方法は以下の3通り
1. VBCPP標準ビルダを使用してコマンドプロンプト等から利用する方法
2. あるプログラムからGenerator(Core内)をロードし、ASTを渡す方法
3. あるプログラムからCompiler(Core内)をロードし、プラグンのンスタンスとコードを渡す方法 (2と3はVBCPP標準ビルダの文法に縛られる必要もありません。)
&&entry = “エントリポイント名" &&<code language=“言語名“ methodName=“関数名(必要なら)”> ~~コード部分~~ &&</code>
<参考:VBCPP標準ビルダの構文>
VBCPPの使い方(2)
そのまま使う。
VBCPP.exeをそのまま実行します。
ソースコードの識別にはVBCPP標準ビルダ用の構文 を使用します。
&&entry = “エントリポイント名" &&<code language=“言語名“ methodName=“関数名(必要なら)”> ~~コード部分~~ &&</code>
VBCPP標準ビルダの構文
&&entry = "Main" &&<code language="VB"> Public Sub Main() Dim d As New Windows.Forms.OpenFileDialog If d.ShowDialog = Windows.Forms.DialogResult.OK Then Console.WriteLine("Path"+d.FileName) Console.WriteLine("=====Body=====") Dim st As New IO.StreamReader(d.FileName) Console.WriteLine(st.ReadToEnd) st.Close() End If Console.WriteLine("Repeat words after HelloWorld with Brainfuck.") printf(“Let's start!!”) BFHello() End Sub &&</code> &&<code language="BF" methodName="BFHello"> +++++++++[>++++++++>+++++++++++>+++++<<<- ]>.>++.+++++++..+++.>-.------------.<++++++++.--------. +++.------.--------.>+. +[>,.<] &&</code>
VBCPPの使い方(2)-2
実演(VBとBrainf*ckの混在コード)
Brainfuckコードを標準ビルダの構文によって関数化している
VBにはないprintf関数を呼び出している (本当はConsole.WriteLine関数に変換している)
StreamReaderとOpenFileDialogを使ってフゔルの内容を読み込みます
(.NET Frameworkを使用する例)
VBCPPの使い方(3)
自作言語のバナリ生成ラブラリとして使う。
VBCPP Coreをロードし、自作言語のパーサーで
生成したASTをジェネレータに直接渡すことで、バ ナリを生成することができます。
• コードを解析する • ASTを構築する
自作コンパラ
Generator(VBCPP Core内)
• ASTを元にバナリを生成
直接ASTを渡す
VBCPPの使い方(4) 難解プログラミング言語(のようなもの)として使う (たいていのプログラムなら1行文で組めます。)
ただ難解なだけではなく、.NETも利用出来るので実用的
VBCPP Coreをロードし、コードから木を書き、 直接
渡すことで、バナリを生成することができます。
Dim Gen As New Generator()
Dim path As String =
System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Lo
cation), "hoge.exe")
Gen.Generate("SampleApp", New VBCPP_Program( _
New AST_Class.VBCPP_ClassList( _
New AST_Class.VBCPP_Class("Test", _
New AST_Class.VBCPP_ClassItemList( _
New VBCPP_Field("g_str", New VBCPP_Type(GetType(String)), FieldAttributes.Public Or
FieldAttributes.Static, 0, "Test.vb"), _
New AST_Class.VBCPP_Method("Main", New VBCPP_Type(GetType(Void)), Nothing, _
New VBCPP_Body(New VBCPP_StatementList(New VBCPP_Assignment( _
New VBCPP_CallExpression("g_str", Nothing, Nothing, Nothing), _
New VBCPP_Literal("代入する値です。", VBCPP_LiteralType.VBCPP_STRING), 0))), _
MethodAttributes.Public Or MethodAttributes.Static, "VB", 0, "Test.vb")), TypeAttributes.Public, "VB",
"test,vb", 0)), _
New AST_Class.VBCPP_MethodList, New AST_Enum.VBCPP_EnumList, New VBCPP_ImportList), _
Nothing, New NameTableList, New NameList("Test", New NameList("Main")), path)
ex.) AST該当部分 (非常に冗長)
VBCPPの使い方(4)-2
1文ASTプログラミング ~FizzBuzz~
数字を順番に出力し、特にその中でも…
3の倍数ならFizz
5の倍数ならBuzz
15の倍数ならFizzBuzz
を出力する言葉遊び
出力例) 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, Fizz Buzz, …
For i = 0 To 100
If i Mod 15 = 0 Then
Console.WriteLine("FizzBuzz")
ElseIf i Mod 5 = 0 Then
Console.WriteLine("Buzz")
ElseIf i Mod 3 = 0 Then
Console.WriteLine("Fizz")
Else
Console.WriteLine(i)
End If Next
<<参考: VBでのFizzBuzz>>
VBCPPの使い方(4)-2
1文ASTプログラミング ~FizzBuzz~
Const FileName As String = "hoge.vb"
Const Line As Integer = 0
Const MaxValue As Integer = 100
Dim Program As New VBCPP_Program( _
Nothing, _
New VBCPP_MethodList( _
New VBCPP_Method( _
"Main", _
New VBCPP_Type(GetType(Void)), _
Nothing, _
New VBCPP_Body(New VBCPP_StatementList( _
New VBCPP_DeclareLocalVariable( _
New VBCPP_LocalVariable("i", New VBCPP_Type(GetType(Integer)), 0, FileName), _
Line), _
New VBCPP_ForStatement( _
New VBCPP_Assignment( _
New VBCPP_CallExpression("i", Nothing, Nothing, Nothing), _
New VBCPP_Literal("1", VBCPP_LiteralType.VBCPP_INTEGER), _
Line), _
New VBCPP_Literal(MaxValue, VBCPP_LiteralType.VBCPP_INTEGER),
New VBCPP_Assignment(New VBCPP_CallExpression("i", Nothing, Nothing, Nothing), _
New VBCPP_BinaryExpression( _
New VBCPP_CallExpression("i", Nothing, Nothing, Nothing), _
New VBCPP_Literal(1, VBCPP_LiteralType.VBCPP_INTEGER), _
VBCPP_BinaryOPType.VBCPP_Add), _
Line), _
New VBCPP_Body(New VBCPP_StatementList( _
New VBCPP_IfStatement( _
New VBCPP_BinaryExpression( _
New VBCPP_BinaryExpression( _
New VBCPP_CallExpression("i", Nothing, Nothing, Nothing), _
New VBCPP_Literal("15", VBCPP_LiteralType.VBCPP_INTEGER), _
VBCPP_BinaryOPType.VBCPP_Modulo), _
New VBCPP_Literal(0, VBCPP_LiteralType.VBCPP_INTEGER), _
VBCPP_BinaryOPType.VBCPP_Equal), _
New VBCPP_Body(New VBCPP_StatementList( _
New VBCPP_CallStatement(New VBCPP_CallExpression("Console", Nothing, Nothing, _
New VBCPP_CallExpression("WriteLine", Nothing, New VBCPP_ArgumentList( _
New VBCPP_Argument(New VBCPP_Literal("FizzBuzz", VBCPP_LiteralType.VBCPP_STRING),
Line) _
), Nothing)), Line))), _
New VBCPP_Body(New VBCPP_StatementList( _
New VBCPP_IfStatement( _
New VBCPP_BinaryExpression( _
New VBCPP_BinaryExpression( _
New VBCPP_CallExpression("i", Nothing, Nothing, Nothing), _
New VBCPP_Literal("5", VBCPP_LiteralType.VBCPP_INTEGER), _
VBCPP_BinaryOPType.VBCPP_Modulo), _
New VBCPP_Literal(0, VBCPP_LiteralType.VBCPP_INTEGER), _
VBCPP_BinaryOPType.VBCPP_Equal), _
New VBCPP_Body(New VBCPP_StatementList( _
New VBCPP_CallStatement(New VBCPP_CallExpression("Console", Nothing, Nothing, _
New VBCPP_CallExpression("WriteLine", Nothing, New VBCPP_ArgumentList( _
New VBCPP_Argument(New VBCPP_Literal(“Buzz”,
VBCPP_LiteralType.VBCPP_STRING), Line) _
), Nothing)), Line))), _
New VBCPP_Body(New VBCPP_StatementList( _
New VBCPP_IfStatement( _
New VBCPP_BinaryExpression( _
New VBCPP_BinaryExpression( _
New VBCPP_CallExpression("i", Nothing, Nothing, Nothing), _
New VBCPP_Literal("3", VBCPP_LiteralType.VBCPP_INTEGER), _
VBCPP_BinaryOPType.VBCPP_Modulo), _
New VBCPP_Literal(0, VBCPP_LiteralType.VBCPP_INTEGER), _
VBCPP_BinaryOPType.VBCPP_Equal), _
New VBCPP_Body(New VBCPP_StatementList( _
New VBCPP_CallStatement(New VBCPP_CallExpression("Console", Nothing, Nothing, _
New VBCPP_CallExpression("WriteLine", Nothing, New VBCPP_ArgumentList( _
New VBCPP_Argument(New VBCPP_Literal(“Fizz”,
VBCPP_LiteralType.VBCPP_STRING), Line) _
), Nothing)), Line))), _
New VBCPP_Body(New VBCPP_StatementList( _
New VBCPP_CallStatement(New VBCPP_CallExpression("Console", Nothing, Nothing, _
New VBCPP_CallExpression("WriteLine", Nothing, New VBCPP_ArgumentList( _
New VBCPP_Argument(New VBCPP_CallExpression("i", Nothing, Nothing, Nothing), Line)), _
Nothing)), Line)) _
), Line))), Line))), Line))),Line))), _
Reflection.MethodAttributes.Public, _
"VB", Line, FileName)), _
Nothing, _
New VBCPP_ImportList(New VBCPP_Import(New NameList("System"))))
Gen.Generate("SampleApp", Program, Nothing, Nothing, New NameList("Main"), Path)
VBCPPの使い方(4)-2
1文ASTプログラミング ~FizzBuzz~
所要時間: 1時間30分程度
IntelliSenseが途中からおかしくなる
1つ間違えると、他にまで影響する→高度な集中力
82行にも及ぶ、1文 (本当はもっと省略できますが…)
動いた時の感動! 疲れました。
よくありそうな質問
Q. 簡単なプログラムのAST式を書くのがこんなに大変だったら、パーサー作成は相当大変かと思うのですが…
A. (必ずしも) そんなことはありません!
VBCPPのAST式は冗長ではありますが、それぞれが独立して存在することができるため、
パーツを組み合わせるようにして、木を構築することができます。
よくありそうな質問(2)
SimpleVBParserの例
(語句解析部分を省略して、Reduction部分の一部のみを表示しています)
VBCPPの今後
ベントやデリゲート等の対応
名前変換テーブルの改善(引数等の対応付け)
さらにプラグン製作者の負担が減るよう(表
現が楽になるよう)ASTのパターンを追加
抽象構文木の対話型による生成&ビルド
VBCPPの今後(2)
プラグンを充実させて、”より実用的な”環境を
作成したプラグンみんなで共有しあえる環境を (プラグンの共有サトとか)
まとめ
言語処理系は楽しい!(奥が深い!)
プラグンを書くだけで、手軽にバナリが動く喜びを感じられる!
プラグンを制作することで、慣れ親しんだ言語と向き合えることもできる!
言語特有の特徴/表現を、いかに工夫して統一された木に表現する(一般化する)か、プラグン製作者の力試しにもなる!
プログラミング言語「ICT+R」 新幹線の時間を使って(東京~京都間)、パーサーを作ってみました!
基本的にはBrainfuckの命令置換です。 Brainfuck命令 ICT+R命令
+ !
- ?
> C
< R
, T
. +
[ I
] .
東京駅発 静岡周辺
(富士山が見える所)
プログラミング言語「ICT+R」 特徴
「!ICT+R.」でプログラムがかける!
直感的ではないため、脳トレに!
ICT+R ! I C T + R .
Brainfuck + [ > , . < ]
⇒ Echoプログラム