自家製簡易プログラミング言語個人ノート(1)


(ブログを書くのは穴を掘ったら必ず記入するように注意することです)
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!