lang:自制編程語言4——語法樹引入賦值

前言

雖然現在做的很歡快!但是因爲除了語法樹外沒有涉及到編譯原理的知識——比如遞歸下降、LX分析等等,也就是說等到了某一步做不下去的時候,就又要花一番功夫看編譯原理了!!!


EqExpr類

前一篇給表達式設置了兩種模式,五則運算模式(+ -*/^)和字符串拼接模式(“a”+“b”+“c”),並且增加了一個解釋接口(interpret_str)!這次做的只有一點點的工作,僅僅是增加了一個賦值類

1)1 + 2*3      	  //表達式,result = 5
2)"h"+"ell"+"0"   //表達式,result = hell0
3)a = 1*(2 + 3)   //賦值語句,result = 5
4)a = b = 2       //賦值語句,result = 2

式子1)的語法樹爲:    +
                   /  \
                  1    *
                      / \
                     2   3
                     
式子2)的語法樹爲:     +     
                    /  \
                   +    "0"
                 /  \
              "h"    "ell"
              
式子3)的語法樹爲:    =        
                   /  \
                  a    *
                      / \
                     1   ()
                         |
                         +
                        / \
                       2   3

式子4)的語法樹爲:     = 
                    /  \ 
                   a    =
                       / \
                      b   2

可以看出等於號也是有左結合和右結合的,運算符類解釋的時候要取左右孩子節點的值進行計算或其他處理,而賦值類解釋的時候要取右孩子的返回結果,將其賦值給左孩子,並且在此時確定左孩子標識符的類型,是number(double),還是string,由右孩子的返回結果決定,然後賦值類解釋返回也是這個結果!

如何添加賦值節點進語法樹?

  • exprRoot是表達式的根節點指針——之前這個指針是root
  • root是賦值語句的根節點指針——構造語法樹之後,要麼root=NULL,要麼exprRoot爲空。之後的解釋語法樹操作和打印語法樹操作都需要分兩種情況,要麼root不爲空表示是賦值語句,要麼exprRoot不爲空表示是表達式!!!
  • 第一次遇到等於號(【id =】前綴 ),建立一個以root爲根節點的語法樹,置空exprRoot
  • 第N此遇到等於號,找到最右下面的等於號節點Q,新建一個等於號節點W,把exprRoot上的內容裝上W的左孩子,把W裝上Q的右孩子
  • 最後遇到分號時,同樣找到最右下面的等於號節點Q,把exprRoot的內容裝上Q的右孩子

項目演示

代碼一如既往在這!

當輸入爲:a= “SOMEONESAY:”+“TECH”+“OTAKU”+“save”+“the”+“world”;

詞法分析 time consumed 57 ms
中綴表達式>
                name     pos    type
                  a       0      10
                  =       1      23
        "SOMEONESAY:"       2      11
                  +       3      15
             "TECH"       4      11
                  +       5      15
            "OTAKU"       6      11
                  +       7      15
             "save"       8      11
                  +       9      15
              "the"      10      11
                  +      11      15
            "world"      12      11
                  ;      13      32
全局中綴表達式 time consumed 76 ms
初始化語言環境 time consumed 0 ms
語法分析·構造語法樹 time consumed 1 ms
------------------------------------------------------------
=
├── a
└── +
    ├── +
    │   ├── +
    │   │   ├── +
    │   │   │   ├── +
    │   │   │   │   ├── "SOMEONESAY:"
    │   │   │   │   └── "TECH"
    │   │   │   └── "OTAKU"
    │   │   └── "save"
    │   └── "the"
    └── "world"
------------------------------------------------------------
語法分析·顯示語法樹 time consumed 54 ms
語法樹是否完全==>true
result = SOMEONESAY:TECHOTAKUsavetheworld
語法分析·解釋語法樹 time consumed 2 ms
語言環境>
          name   isconst         type        funcPtr        num          str
         FALSE     1              2          00000000         0         FALSE
           NIL     1              0          00000000         0         NIL
          TRUE     1              2          00000000         0         TRUE
             a     0              4          00000000         0         SOMEONESAY:TECHOTAKUsavetheworld
顯示環境信息 time consumed 111 ms

當輸入爲:a=b = c = 1 + 2 * 3 - 4 - 20

詞法分析 time consumed 364 ms
中綴表達式>
                name     pos    type
                  a       0      10
                  =       1      23
                  b       2      10
                  =       3      23
                  c       4      10
                  =       5      23
                  1       6       7
                  +       7      15
                  2       8       7
                  *       9      13
                  3      10       7
                  -      11      16
                  4      12       7
                  -      13      16
                 20      14       7
全局中綴表達式 time consumed 709 ms
初始化語言環境 time consumed 0 ms
語法分析·構造語法樹 time consumed 1 ms
------------------------------------------------------------
-
├── -
│   ├── +
│   │   ├── 1
│   │   └── *
│   │       ├── 2
│   │       └── 3
│   └── 4
└── 20
------------------------------------------------------------
語法分析·顯示語法樹 time consumed 17 ms
語法樹是否完全==>true
result = -17
語法分析·解釋語法樹 time consumed 2 ms
語言環境>
          name   isconst         type        funcPtr        num          str
         FALSE     1              2          00000000         0         FALSE
           NIL     1              0          00000000         0         NIL
          TRUE     1              2          00000000         0         TRUE
             a     0              0          00000000         0
             b     0              0          00000000         0
             c     0              0          00000000         0
顯示環境信息 time consumed 406 ms

上面這個演示中,result=-17是對的,但是語法樹不對!!!語言環境也不對!!!

  • 語言環境就是符號表,是一個std::map<std::string,SuatinID*>類型的容器!保存標識符和它的值!

消滅BUG

因爲CSDN上上傳的東西無法修改,也無法刪除!!!所以上面的演示錯了我也就留在這了!接下來修改項目中的BUG,解決上面的問題!!!

在Parser類中添加一個屬性

bool firstEq_flag = true;//是否是第一次命名

修改Parser.cpp文件中的DealToken_Eq函數

void Parser::DealToken_Eq(int& _t) {
		if (exprRoot == NULL&&expTmp) { //等於號左邊沒有標識符,或存在待處理節點
			ThrowException<SuatinErrorType_NoDefined>(file_dir, file_lineNumber, file_lineContent, "[Eq] wrong expression");
			expTmp = NULL;
			return;
		}
		/*
	    第一種情況:
		a      ->           =
		                  /   \
						a      None

		第二種情況:
		         =      +  b     ->                 =
			   /  \                               /   \
			 a    None                          a      =
			                                         /   \
												   b    None
		*/
		
		//第一次遇到等號,並且左邊就是一個標識符
		if (firstEq_flag) {
			if (typeid(*(exprRoot->GetClassType())) == typeid(IDExpr)) {
				root = new EqExpr(exprRoot, NULL);
				completedName_flag = true;//成功命名
				exprRoot = NULL;
				firstEq_flag = false;
				return;
			}
		}
		
		//第N次遇到等號,找到最右的等號節點,取下,換上新小樹
		if (typeid(*(root->GetClassType())) == typeid(EqExpr)) {
			SymbolExpr* eq = dynamic_cast<SymbolExpr*>(root);//轉成SymbolExpr而不是EqExpr是爲了好兼容下面的遞歸操作
			while ( eq->GetRight()) {
				SymbolExpr* eq2 = dynamic_cast<SymbolExpr*>(eq->GetRight());
				eq = eq2;
			}

			EqExpr* tmp = new EqExpr(exprRoot, NULL);
			eq->SetRight(tmp);
			exprRoot = NULL;
			return;
		}
		

		//。。。
		ThrowException<SuatinErrorType_NoDefined>(file_dir, file_lineNumber, file_lineContent, "[Eq] wrong expression");

	}

還有一個錯誤就是,之前的文件內容後面沒有分號!!!我現在將分號作爲了語句解釋(又改了2333)

當輸入爲:a=b = c = 1 + 2 * 3 - 4 - 20;

詞法分析 time consumed 205 ms
中綴表達式>
                name     pos    type
                   a       0      10
                   =       1      23
                   b       2      10
                   =       3      23
                   c       4      10
                   =       5      23
                   1       6       7
                   +       7      15
                   2       8       7
                   *       9      13
                   3      10       7
                   -      11      16
                   4      12       7
                   -      13      16
                  20      14       7
                   ;      15      32
全局中綴表達式 time consumed 190 ms
初始化語言環境 time consumed 0 ms
語法分析·構造語法樹 time consumed 1 ms
------------------------------------------------------------
=
├── a
└── =
    ├── b
    └── =
        ├── c
        └── -
            ├── -
            │   ├── +
            │   │   ├── 1
            │   │   └── *
            │   │       ├── 2
            │   │       └── 3
            │   └── 4
            └── 20
------------------------------------------------------------
語法分析·顯示語法樹 time consumed 55 ms
語法樹是否完全==>true
result = -17
語法分析·解釋語法樹 time consumed 4 ms
語言環境>
          name   isconst         type        funcPtr        num          str
         FALSE     1              2          00000000         0         FALSE
           NIL     1              0          00000000         0         NIL
          TRUE     1              2          00000000         0         TRUE
             a     0              3          00000000       -17
             b     0              3          00000000       -17
             c     0              3          00000000       -17
顯示環境信息 time consumed 180 ms
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章