自家製簡易プログラミング言語個人ノート(1)
(ブログを書くのは穴を掘ったら必ず記入するように注意することです)
githubアドレスhttps://github.com/lucyTheSlayer/orange
暇な時間を利用して、自分でプログラミング言語を勉強する準備をして、Orangeと名付けました.
Orangeの最終目標はpythonの簡略化版であり、oopのサポートがある(ここまで続けてほしい)
そこで何年も前の古い本「コンパイル原理と実践」をめくって、本の後のソースコードに従って叩く.本の中のTINY言語のフォーマットはあまりにも醜いので、そのソースコードを相応に修正しなければならない.主にいくつかのキーワードを追加し、REPEAT文を現代感の強いWHILEなどに変更した.現在のOrangeのコードサンプルは以下の通りです.
この中の賦課番号は:=、このような古い方式も人に見られてとても苦しくて、後で(本当に後がありますか?)また直しましょう.
現在の進捗状況では,上記のコードをバイトコードに変換できるが,解釈器はまだやっていないので,果たしてこのバイトコードが正しいかどうかはまだ言えない.以下に、コンパイルプロセス全体の概要を示します.
1)lexer語法分析
このモジュールは、ファイルからソースコードを読み出し、tokenとして上位parserに返して使用することを担当し、上記のコードはlexerを経て以下の形式になる.
もちろん、構文解析器は、すべてのコンテンツを一気にtoken化するのではなく、parserがtokenを取得するためにアクティブに呼び出す必要があります.
2)parser構文解析
構文解析は最も重要な一環であり、ここではソースコードを構文ツリーに変換する上から下への方法を採用しています.
3)意味分析
文法ツリーがあれば、好きなようにすることができます.このステップでシンボルテーブルを作成し、ここでタイプチェックをします.例えば、c言語のint a=「abc」という明らかなタイプエラーがあれば、もう一歩チェックしなければなりません.
4)コード生成
これは最も感動的な瞬間であり、コンパイラ部分の最終成果の展示部分でもある.最終的に私のOrangeソースコードは以下のバイトコードに変わりました
okay、クールに見えますが、本の中で著者が採用しているこのようなアセンブリ言語のフォーマットはまだ不快に見えますが(個人的にpythonのバイトコードスタイルを推奨しています)、今は学習段階で、先に勉強して、後で自分の好きなフォーマットに変更します(本当に後ろにありますか?)
この中のwhile文のバイトコードは私が自分で生成したので、正しいかどうか分かりませんが、すべてvmマシンコードが終わるのを待たなければなりません(本当のコードが終わるのですか?)しました.
この文は私の个人の娯楽が使っているだけで、もちろんもしあなたが不幸にもここを见て、何もgetしていないことを発见して、とても怒って、それではここで、私は《コンパイルの原理と実践》という本を推荐して、本の中のソースコードについて1回歩いて、多くはすべて豁然として明るくなりました.すべての技術、plz read the fucking source code!
githubアドレスhttps://github.com/lucyTheSlayer/orange
暇な時間を利用して、自分でプログラミング言語を勉強する準備をして、Orangeと名付けました.
Orangeの最終目標はpythonの簡略化版であり、oopのサポートがある(ここまで続けてほしい)
そこで何年も前の古い本「コンパイル原理と実践」をめくって、本の後のソースコードに従って叩く.本の中のTINY言語のフォーマットはあまりにも醜いので、そのソースコードを相応に修正しなければならない.主にいくつかのキーワードを追加し、REPEAT文を現代感の強いWHILEなどに変更した.現在のOrangeのコードサンプルは以下の通りです.
apple := 200;
banana := 100;#ohoh123
if(apple0){
write i;
i := i - 1;
}
この中の賦課番号は:=、このような古い方式も人に見られてとても苦しくて、後で(本当に後がありますか?)また直しましょう.
現在の進捗状況では,上記のコードをバイトコードに変換できるが,解釈器はまだやっていないので,果たしてこのバイトコードが正しいかどうかはまだ言えない.以下に、コンパイルプロセス全体の概要を示します.
1)lexer語法分析
このモジュールは、ファイルからソースコードを読み出し、tokenとして上位parserに返して使用することを担当し、上記のコードはlexerを経て以下の形式になる.
ID, name= apple
:=
NUM, val= 200
;
ID, name= banana
:=
NUM, val= 100
;
reserved word: if
(
ID, name= apple
<
ID, name= banana
)
{
ID, name= orange
:=
ID, name= apple
*
ID, name= banana
;
ID, name= banana
:=
NUM, val= 12
*
ID, name= apple
-
NUM, val= 32
;
}
ID, name= i
:=
NUM, val= 10
;
reserved word: while
(
ID, name= i
>
NUM, val= 0
)
{
reserved word: write
ID, name= i
;
ID, name= i
:=
ID, name= i
-
NUM, val= 1
;
}
もちろん、構文解析器は、すべてのコンテンツを一気にtoken化するのではなく、parserがtokenを取得するためにアクティブに呼び出す必要があります.
2)parser構文解析
構文解析は最も重要な一環であり、ここではソースコードを構文ツリーに変換する上から下への方法を採用しています.
Assign to : apple
Const: 200
Assign to : banana
Const: 100
If
Op: <
Id: apple
Id: banana
Assign to : orange
Op: *
Id: apple
Id: banana
Assign to : banana
Op: -
Op: *
Const: 12
Id: apple
Const: 32
Assign to : i
Const: 10
While
Op: >
Id: i
Const: 0
Write
Id: i
Assign to : i
Op: -
Id: i
Const: 1
3)意味分析
文法ツリーがあれば、好きなようにすることができます.このステップでシンボルテーブルを作成し、ここでタイプチェックをします.例えば、c言語のint a=「abc」という明らかなタイプエラーがあれば、もう一歩チェックしなければなりません.
Building Symbol Table...
Symbol table:
Variable Name Location Line Numbers
banana 1 2 3 4 5
orange 2 4
i 3 7 8 9 10 10
apple 0 1 3 4 5
Checking Types...
Type Checking Finished
4)コード生成
これは最も感動的な瞬間であり、コンパイラ部分の最終成果の展示部分でもある.最終的に私のOrangeソースコードは以下のバイトコードに変わりました
* TINY Compilation to TM Code
* File: hello.orangebc
* Standard prelude:
0: LD 6,0(0) load maxaddress from location 0
1: ST 0,0(0) clear location 0
* End of standard prelude.
* -> assign
* -> Const
2: LDC 0,200(0) load const
* assign
* -> Const
4: LDC 0,100(0) load const
* if
* -> Op
* -> Id
6: LD 0,0(5) load id value
* Id
8: LD 0,1(5) load id value
* assign
* -> Op
* -> Id
16: LD 0,0(5) load id value
* Id
18: LD 0,1(5) load id value
* assign
* -> Op
* -> Op
* -> Const
22: LDC 0,12(0) load const
* Id
24: LD 0,0(5) load id value
* Const
28: LDC 0,32(0) load const
* assign
* -> Const
33: LDC 0,10(0) load const
* while
* -> Op
* -> Id
35: LD 0,3(5) load id value
* Const
37: LDC 0,0(0) load const
*
40: JLT 0,2(7) br if false
41: LDC 0,1(0) true case
42: LDA 7,1(7) unconditional jmp
43: LDC 0,0(0) false case
* Id
45: LD 0,3(5) load id value
* assign
* -> Op
* -> Id
47: LD 0,3(5) load id value
* Const
49: LDC 0,1(0) load const
*
okay、クールに見えますが、本の中で著者が採用しているこのようなアセンブリ言語のフォーマットはまだ不快に見えますが(個人的にpythonのバイトコードスタイルを推奨しています)、今は学習段階で、先に勉強して、後で自分の好きなフォーマットに変更します(本当に後ろにありますか?)
この中のwhile文のバイトコードは私が自分で生成したので、正しいかどうか分かりませんが、すべてvmマシンコードが終わるのを待たなければなりません(本当のコードが終わるのですか?)しました.
この文は私の个人の娯楽が使っているだけで、もちろんもしあなたが不幸にもここを见て、何もgetしていないことを発见して、とても怒って、それではここで、私は《コンパイルの原理と実践》という本を推荐して、本の中のソースコードについて1回歩いて、多くはすべて豁然として明るくなりました.すべての技術、plz read the fucking source code!