前言
雖然現在做的很歡快!但是因爲除了語法樹外沒有涉及到編譯原理的知識——比如遞歸下降、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