-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParser.cpp
1891 lines (1801 loc) · 69.1 KB
/
Parser.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//
// Created by hzt on 2023/9/25.
//
#include "Parser.h"
#include "Lexer.h"
#include <iostream>
using namespace std;
string funcLabel;
bool isInOtherFunc;//区分中间代码是在主函数还是自定义函数 --注意定义还要分一个全局--既不是主函数 也不是
extern vector<ICode *> mainICodes ;
extern vector<ICode *>globalDef ;
extern int tempMemoryAddressTop;
void Parser::Print_Grammar_Output(const string& s) {
if (enablePrint){
//ouputFile << s << endl;
lexer.outputFile << s << endl;
}
}
void Parser::CompUnit() {
/**
* 这是起始部分 识别符号 先读取一个 需要放权!!!!
* 不应该这样直接全部包揽 允许一定的回溯 在当前那里判断就行
* 按自己的想法去写
*
*/
GET_A_WORD;
while(WORD_TYPE != FINISH){
if ( WORD_TYPE == CONSTTK){ //Decl
Decl();//常量声明部分入口是const
}
else if (WORD_TYPE == INTTK ){
PRINT_WORD;
//PRINT INT 这里之所以输出当前CompUnit右边产生式没有的终结符 是因为不把它当做下一级的非终结符 将它提前到父亲这一级
GET_A_WORD;
if (WORD_TYPE == MAINTK){ //MainFuncDef int main()
MainFuncDef();
}else if(WORD_TYPE == IDENFR){ // int [ident]
/**
*
* 无需peek a letter 读取完ident后 ch已经指向下一个字符了
*/
//lexer.ch = PEEK_A_LETTER;
int pre_line = lexer.line;
while(isspace(lexer.ch)){
if(lexer.ch == '\n'){
lexer.line++;
}
lexer.ch = (char )lexer.sourceFile.get();
}
if (lexer.ch == '('){//FuncDef 从名字<ident>开始 还没有输出functype
//FUNCTYPE
FuncType();
FuncDef(FUNC_INT);
}else if(lexer.ch == ',' || lexer.ch == ';' || lexer.ch == '=' || lexer.ch == '['){
Decl();//变量声明部分 入口是ident
}else{
//Error 缺少;
PRINT_WORD;//print ident
GET_A_WORD;
lexer.line_lastWord = pre_line;
errorHandler.Insert_Error(SEMICOLON_MISSING);
}
}
}else if(WORD_TYPE == VOIDTK){
PRINT_WORD;//PRINT VOID
GET_A_WORD;
FuncType();
if(WORD_TYPE != IDENFR){
//ERROR
}
FuncDef(FUNC_VOID);
}
else if (WORD_TYPE == NOTE){
GET_A_WORD;
}
}
Print_Grammar_Output("<CompUnit>");
}
void Parser::Decl(){
//不可以自调用 在更高层进行循环 Decl只负责一次 由CompUnit多次调用
//进入VarDecl or ConstDecl
//VAR从ident开始 还未PRINT IDENT
//CONST 从CONST开始
if (WORD_TYPE == CONSTTK){
ConstDecl();//常量声明部分 const开始 还未输出const
}else if(WORD_TYPE == IDENFR){
//lexer.ch = PEEK_A_LETTER;
/**
* 问题-1
*/
// while (isspace(lexer.ch)){
// lexer.ch = lexer.sourceFile.get();
// }
// if(lexer.ch == ',' || lexer.ch == ';' || lexer.ch == '=' || lexer.ch == '['){
// VarDecl();//变量声明部分
// }
VarDecl();
}else{
//Error
}
}
void Parser::VarDecl() {
//to VarDef
//start from 正指向ident
vector<Entry*> entries;
VarDef(entries);//有错误就下放到下一层 按照文法编写
while(WORD_TYPE == COMMA){
PRINT_WORD;//PRINT ,
GET_A_WORD;
VarDef(entries);
}
if (WORD_TYPE != SEMICN){
//Error; 缺少分号
errorHandler.Insert_Error(SEMICOLON_MISSING);
// semantic.skip(VARDECL);
// semantic.recordEntries(entries);
return;
}
//不缺少分号 会运行到这儿
PRINT_WORD;//PRINT ;
Print_Grammar_Output("<VarDecl>");
// semantic.recordEntries(entries);
GET_A_WORD;//POINT TO NEXT
}
void Parser::VarDef(vector<Entry*> &entries) {
/**
* WORD_TYPE正指向 IDENTFR
*/
bool error = false;
if (WORD_TYPE != IDENFR){
//Error
}
string ident = WORD_DISPLAY;
int op = 0;
//定义:先在这一层找 找到就报错REDEFINE然后跳到; 没找到就填表
if(tableManager.isRedefine(ident) || inArguments(entries,ident)){
errorHandler.Insert_Error(REDEFINE);
error = true;
}//重定义错误,局部化处理
PRINT_WORD;//PRINT IDENT
GET_A_WORD;
int values[3];
IEntry* exp_iEntries[3];
while(WORD_TYPE == LBRACK){
op++;
PRINT_WORD;//PRINT [
GET_A_WORD;
exp_iEntries[op] = new IEntry;
ConstExp(exp_iEntries[op],values[op],isInOtherFunc); //FIXME不要再相信values 就是无效值
if (WORD_TYPE == RBRACK){
PRINT_WORD;//PRINT ]
GET_A_WORD;
}else{
//Error 缺少右中括号
errorHandler.Insert_Error(RBRACK_MISSING);
// error =true;
}
}
int nums = 0;//数组的长度 会在扫描初始值时设定 同时本身也会设定
IEntry * iEntry;
int total_length,dim1_length;
if (op == 0){
total_length = dim1_length = 1;
iEntry = new IEntry;
}else if(op == 1){
total_length = dim1_length = exp_iEntries[1]->imm;
iEntry = new IEntry(total_length);
}else if(op == 2){
total_length = exp_iEntries[1]->imm*exp_iEntries[2]->imm;//FIXME;数组初始大小
dim1_length = exp_iEntries[2]->imm;
iEntry = new IEntry(total_length);
}
iEntry->dim1_length = dim1_length;
iEntry->total_length = total_length;
Entry * entry;
switch (op) {
case 0:
entry = semantic.fillInfoEntry(ident,VAR);
break;
case 1:
entry = semantic.fillInfoEntry(ident,ARRAY_1_VAR);
break;
case 2:
entry = semantic.fillInfoEntry(ident,ARRAY_2_VAR);
break;
default:
break;
}
bool hasValue = false;
nums = 0;
iEntry->original_Name = ident;
if (WORD_TYPE == ASSIGN){
hasValue = true;
PRINT_WORD;
GET_A_WORD;
iEntry->values_Id = new vector<int>;//values_Id给变量数组
InitVal(iEntry,nums);
}else{
iEntry->values_Id = new vector<int>;
IEntry*p;
for (int i = 0; i <total_length;i++){
iEntry->values_Id->push_back((p = new IEntry)->Id);
//exp_iEntry->original_Name = iEntry->original_Name.append("_").append(to_string(nums)).append("_");
p->original_Name = iEntry->original_Name.append("_").append(to_string(nums)).append("_");
p->canGetValue = true;
p->imm = 0;
}
}
if(!error){
entries.push_back(entry);
semantic.recordEntries(entry);
entry->id = iEntry->Id;
if (ISGLOBAL){
iEntry->isGlobal = true;//MIPS依据这个生成标签或者地址 lw FIXME:标签采用 originalName_id:
}
if (hasValue){
if (op == 0){
intermediateCode.addDef(ISGLOBAL,VAR_Def_Has_Value,iEntry, nullptr, nullptr);//FIXME:addDef本身也是加入ICode 多了一个isGlobal参数
}else{
intermediateCode.addDef(ISGLOBAL,ARRAY_VAR_Def_Has_Value,iEntry, nullptr, nullptr);//FIXME:addDef本身也是加入ICode 多了一个isGlobal参数
}
}else{
if (op == 0){
//后台更新全局变量的初始值
if (ISGLOBAL){
IEntries.at(iEntry->values_Id->at(0))->canGetValue = true;
IEntries.at(iEntry->values_Id->at(0))->imm = 0;
}
intermediateCode.addDef(ISGLOBAL,VAR_Def_No_Value,iEntry, nullptr, nullptr);//FIXME:addDef本身也是加入ICode 多了一个isGlobal参数
}else{
if (ISGLOBAL){
for (auto id: *iEntry->values_Id) {
IEntries.at(id)->canGetValue = true;
IEntries.at(id)->imm = 0;
}
}
intermediateCode.addDef(ISGLOBAL,ARRAY_Def_No_Value,iEntry, nullptr, nullptr);//FIXME:addDef本身也是加入ICode 多了一个isGlobal参数
}
}
}
Print_Grammar_Output("<VarDef>");
}
//当前指向const
void Parser::ConstDecl() {
//
PRINT_WORD;//PRINT CONST
GET_A_WORD;
//当前指向BType(int)
if (WORD_TYPE != INTTK){
//Error
}
PRINT_WORD;//PRINT INT
GET_A_WORD;//当前指向ident
if (WORD_TYPE != IDENFR){
//Error
}
vector<Entry*> entries;
ConstDef(entries);// point to the ident and into ConstDef()
while(WORD_TYPE == COMMA){
PRINT_WORD;//PRINT COMMA
GET_A_WORD;
ConstDef(entries);
}
if (WORD_TYPE != SEMICN){
//Error
errorHandler.Insert_Error(SEMICOLON_MISSING);
// semantic.skip(CONSTDECL);
// semantic.recordEntries(entries);
return;
}
PRINT_WORD;//PRINT ;
Print_Grammar_Output("<ConstDecl>");
// tableManager.insertIntoTable(entries);
GET_A_WORD;//point to next word
}
void Parser::ConstDef(vector<Entry*>& entries) {
if (WORD_TYPE != IDENFR){
//Error
}
bool error = false;
string ident = WORD_DISPLAY;
//定义:先在这一层找 找到就报错REDEFINE 没找到就填表
if(tableManager.isRedefine(ident) || inArguments(entries,ident)){
errorHandler.Insert_Error(REDEFINE);
error = true;
}
PRINT_WORD;
GET_A_WORD;
int op = 0;
IEntry * exp_iEntries[3];
int values[3];
while(WORD_TYPE == LBRACK){
op++;
PRINT_WORD;
GET_A_WORD;
exp_iEntries[op] = new IEntry;
ConstExp(exp_iEntries[op],values[op],isInOtherFunc);
if (WORD_TYPE == RBRACK){
PRINT_WORD;
GET_A_WORD;
}else{
//Error
errorHandler.Insert_Error(RBRACK_MISSING);
// error = true;
}
}
int nums = 0;//数组的长度 会在扫描初始值时设定 同时本身也会设定
IEntry * iEntry;
int total_length,dim1_length;
if (op == 0){
total_length = dim1_length = 1;
iEntry = new IEntry;
}else if(op == 1){
total_length = dim1_length = exp_iEntries[1]->imm;
iEntry = new IEntry(total_length);
}else if(op == 2){
total_length = exp_iEntries[1]->imm*exp_iEntries[2]->imm;//FIXME;数组初始大小
dim1_length = exp_iEntries[2]->imm;
iEntry = new IEntry(total_length);
}
iEntry->dim1_length = dim1_length;
iEntry->total_length = total_length;
Entry * entry;
switch (op) {
case 0:
entry = semantic.fillInfoEntry(ident,CONST);
break;
case 1:
entry = semantic.fillInfoEntry(ident,ARRAY_1_CONST);
break;
case 2:
entry = semantic.fillInfoEntry(ident,ARRAY_2_CONST);
break;
default:
break;
}
nums = 0;
iEntry->original_Name = ident;
//常量定义 必须赋值
if (WORD_TYPE != ASSIGN){
//Error
}else{
PRINT_WORD;
GET_A_WORD;
//FIXME:这里的iEntry可以作为存放初值 --数组 --普通变量
iEntry->values_Id = new vector<int>;
// iEntry->values = new vector<int>;
ConstInitVal(iEntry,nums);
}
//留下对数组长度的补充计算 以及变量值的存储
//已经指向下一个word , or ;
//FIXME:目前认为values只保存在IEntry中 TODO:需要注意同步IEntry和Entry的关系
if(!error){
entries.push_back(entry);
semantic.recordEntries(entry);
entry->id = iEntry->Id;
if(ISGLOBAL){
iEntry->isGlobal = true;
}
if (op == 0){
intermediateCode.addDef(ISGLOBAL,Const_Def_Has_Value,iEntry, nullptr, nullptr);//FIXME:addDef本身也是加入ICode 多了一个isGlobal参数
}else{
intermediateCode.addDef(ISGLOBAL,ARRAY_CONST_Def_Has_Value,iEntry, nullptr, nullptr);//FIXME:addDef本身也是加入ICode 多了一个isGlobal参数
}
}
Print_Grammar_Output("<ConstDef>");
}
//FIXME:至多只有两层 append
//FIXME:value表示目前的个数 dim1_length表示第一层维数的大小 ConstInitVa中的iEntry指向的是数组变量的IEntry
void Parser::ConstInitVal(IEntry *iEntry,int&nums) {
if (WORD_TYPE == LBRACE){
PRINT_WORD;//PRINT {
GET_A_WORD;
ConstInitVal(iEntry, nums);
while(WORD_TYPE == COMMA){
PRINT_WORD;//PRINT ,
GET_A_WORD;
ConstInitVal(iEntry, nums);
}
if(WORD_TYPE != RBRACE){
//Error
}
PRINT_WORD;//PRINT }
GET_A_WORD;
}else{
int value;
auto* _constExp = new IEntry;//true canGet 会在内部进行设置
ConstExp(_constExp, value, isInOtherFunc);
_constExp->startAddress = iEntry->startAddress + 4*nums;
_constExp->original_Name = iEntry->original_Name.append("_").append(to_string(nums)).append("_");
iEntry->values_Id->push_back(_constExp->Id);//值要不统一存到values中 定义时 因为你不知道是数组还是啥 TODO: imm是确定的中间变量再用?
nums++;
}
Print_Grammar_Output("<ConstInitVal>");
}
//FIXME:至多只有两层 append
//FIXME:nums表示目前的个数 一个ConstExp只有一个值 value表示ConstExp当前的算出值
void Parser::ConstExp(IEntry *iEntry,int&value,bool InOtherFunc) {
AddExp(iEntry, value, InOtherFunc);
// iEntry->values->push_back(value);//FIXME: ConstExp一定可以算出来
Print_Grammar_Output("<ConstExp>");
}
//Exp->AddExp
//AddExp->MulExp{[+-]MulExp}
//认为iEntry由下一级反馈 如果是空 说明值已经算出来放进了value 非空说明值为临时变量
void Parser::AddExp(IEntry *iEntry,int&value,bool iInOtherFunc) {
int value1,value2;
IEntry*iEntry1 ,*iEntry2 ;
iEntry1 = new IEntry;
//TODO:理解iEntry的原理
MulExp(iEntry1, value1, iInOtherFunc);
//FIXME:iEntry代表当前语法成分的代表组件 可以存地址 ----只在函数形参实参出现 也可以存值---可以编译时已经算出来的--也可以是运行时
//:FIXME:iEntry只有在最底层能确定部件时才会指向生成的iEntry (new ) 需要根据情况设定属性 op默认为值0) 如果value值有效需要置canGetValue = true 默认为false)
if (WORD_TYPE == PLUS || WORD_TYPE == MINU){
Exp_type =0;
IEntry *ans;
while(WORD_TYPE == PLUS || WORD_TYPE == MINU){
int op = WORD_TYPE == PLUS? 0:1;
if (!isLValInStmt)
Print_Grammar_Output("<AddExp>");
PRINT_WORD;//print + -
GET_A_WORD;
iEntry2 = new IEntry;
MulExp(iEntry2, value2, iInOtherFunc);
if (op == 0){
if (iEntry1->canGetValue && iEntry2->canGetValue){
value = iEntry1->imm + iEntry2->imm;
iEntry1->imm = value;
iEntry1->canGetValue = true;
}else {
ans = new IEntry;
intermediateCode.addICode(IntermediateCodeType::Add, iEntry1, iEntry2, ans);
iEntry1 = ans;
}
}else{
if (iEntry1->canGetValue && iEntry2->canGetValue){
value = iEntry1->imm - iEntry2->imm;
iEntry1->imm = value;
iEntry1->canGetValue = true;
}else{
ans = new IEntry;
intermediateCode.addICode(IntermediateCodeType::Sub,iEntry1,iEntry2,ans);
iEntry1 = ans;
}
}
}
}else{
//error
}
//TODO: imm & address
if (iEntry1->canGetValue){
iEntry->imm = iEntry1->imm;
iEntry->canGetValue = true;
}else{
//TODO:新理解 要么给个具体值 要么给个将来运行时的具体地址
iEntry->imm = iEntry1->imm;
iEntry->canGetValue = iEntry1->canGetValue;
iEntry->startAddress = iEntry1->startAddress;
iEntry->type = iEntry1->type;
iEntry->offset_IEntry = iEntry1->offset_IEntry;
iEntry->original_Name = iEntry1->original_Name;
iEntry->values_Id = iEntry1->values_Id;
iEntry->dim1_length = iEntry1->dim1_length;
iEntry->total_length = iEntry1->total_length;
iEntry->has_return = iEntry1->has_return;
}
if (!isLValInStmt)
Print_Grammar_Output("<AddExp>");
//已经指向下一个
}
//MulExp是项 下面有因子
//MulExp →UnaryExp [*/%] {UnaryExp}
void Parser::MulExp(IEntry *iEntry,int&value,bool InOtherFunc) {
int value1,value2;
IEntry *iEntry1, *iEntry2;
IEntry * ans;
iEntry1 = new IEntry;
UnaryExp(iEntry1, value1, InOtherFunc);
if (WORD_TYPE == MULT || WORD_TYPE == DIV || WORD_TYPE == MOD){
Exp_type = 0;
while(WORD_TYPE == MULT || WORD_TYPE == DIV || WORD_TYPE == MOD){
int op;
switch (WORD_TYPE) {
case MULT:
op = 0;
break;
case DIV:
op = 1;
break;
case MOD:
op = 2;
break;
default:
op = -1;
break;
}
if (!isLValInStmt)
Print_Grammar_Output("<MulExp>");
PRINT_WORD;//print the */%
GET_A_WORD;
iEntry2 = new IEntry;
UnaryExp(iEntry2, value2, InOtherFunc);
if (op == 0){
if (iEntry1->canGetValue && iEntry2->canGetValue){
value = iEntry1->imm * iEntry2->imm;
ans = new IEntry;
ans->canGetValue = true;
ans->imm = value;
}else {
ans = new IEntry;
intermediateCode.addICode(IntermediateCodeType::Mult, iEntry1, iEntry2, ans);
}
}else if(op ==1){
if (iEntry1->canGetValue && iEntry2->canGetValue){
value = iEntry1->imm / iEntry2->imm;
ans = new IEntry;
ans->canGetValue = true;
ans->imm = value;
}else {
ans = new IEntry;
intermediateCode.addICode(IntermediateCodeType::Div, iEntry1, iEntry2, ans);
}
}else{
if (iEntry1->canGetValue && iEntry2->canGetValue){
value = iEntry1->imm % iEntry2->imm;
ans = new IEntry;
ans->canGetValue = true;
ans->imm = value;
}else {
ans = new IEntry;
intermediateCode.addICode(IntermediateCodeType::Mod, iEntry1, iEntry2, ans);
}
}
iEntry1 = ans;
}
}else{
//error
}
if (iEntry1->canGetValue){
iEntry->imm = iEntry1->imm;
iEntry->canGetValue = true;
}else{
//TODO:新理解 要么给个具体值 要么给个将来运行时的具体地址 地址的拷贝!!!
iEntry->imm = iEntry1->imm;
iEntry->canGetValue = iEntry1->canGetValue;
iEntry->startAddress = iEntry1->startAddress;
iEntry->type = iEntry1->type;
iEntry->offset_IEntry = iEntry1->offset_IEntry;
iEntry->original_Name = iEntry1->original_Name;
iEntry->values_Id = iEntry1->values_Id;
iEntry->dim1_length = iEntry1->dim1_length;
iEntry->total_length = iEntry1->total_length;
iEntry->has_return = iEntry1->has_return;
}
if (!isLValInStmt)
Print_Grammar_Output("<MulExp>");
//已经指向下一个
}
void Parser::UnaryExp(IEntry * iEntry,int & value,bool InOtherFunc) {
int func_ident_line;
if (WORD_TYPE == LPARENT || WORD_TYPE == INTCON){
PrimaryExp(iEntry, value, InOtherFunc);
}else if(WORD_TYPE == IDENFR){
string ident = WORD_DISPLAY;
Entry * temp = tableManager.cur;
bool not_define_error = true;
while(temp != nullptr){
if(temp->entries->find(ident) != temp->entries->end()){
not_define_error = false;
break;
}
temp = temp->Father_Entry;
}
if (not_define_error){
errorHandler.Insert_Error(NOT_DEFINE);
// ouputFile << "1 "+to_string(errorHandler.error_line);
}
//lexer.ch = PEEK_A_LETTER; 为了去除所有的空白字符 用peek无法做到
//之所以不用GET_A_WORD 是因为 这样会丢失ident 造成约束不一致
//GET_A_WORD总是从ch当前属于的字符进行划分
lexer.line_lastWord = lexer.line;
func_ident_line = lexer.line;
while(isspace(lexer.ch)){
if(lexer.ch == '\n'){
lexer.line++;
}
lexer.ch = (char )lexer.sourceFile.get();
}
if(lexer.ch == '('){
Entry * func;
bool err = false;
Exp_type = 0;//函数调用时只可能返回值 且实参里真正有Exp是不可能的 所以没用
int RParams_count = 0;
//进入FuncRParams
PRINT_WORD;//PRINT IDENT
ident = WORD_DISPLAY;
//函数未定义
if( ! semantic.isEverDefined(ident,FUNC_INT, false)){//先认为是int函数 不做过多要求
errorHandler.Insert_Error(NOT_DEFINE,func_ident_line);
err =true;
}
//无论是否报错 都继续 报了错就是正常的
GET_A_WORD;//算上 (
PRINT_WORD;//PRINT (
GET_A_WORD;//指向FuncRParams 也可能是无参少了右括号
//可以没有参数
if(WORD_TYPE == RPARENT){// 也要去判断参数个数的问题
/**
* 函数没有参数 不需要压栈
*/
func = nullptr;
temp = tableManager.cur;
while(temp != nullptr){
if (temp->entries->find(ident) != temp->entries->end()){
func = temp->entries->at(ident);
if (func->kind != FUNC_INT && func->kind != FUNC_VOID){
func = nullptr;
}
break;
}
temp = temp->Father_Entry;
}
if (func != nullptr && !(func->fParams->empty()) ){//函数定义时有参数 但是调用没参数 无脑个数问题
// errorHandler.error_line = func_ident_line;
errorHandler.Insert_Error(FUNC_RPARAMS_COUNT_ERROR,func_ident_line);
}else{//没有参数的函数调用 src1函数定义头 src2函数参数IEntry 放在valueId
auto * params = new IEntry;
params->values_Id = new vector<int>;
if (func->kind == FUNC_INT){//空参数
iEntry->canGetValue = false;
iEntry->startAddress = IEntries.at(func->id)->return_IEntry->startAddress;//地址赋值 类似拷贝
intermediateCode.addICode(FuncCall,IEntries.at(func->id), params, iEntry);//FIXME:又返回值的函数 把值给到这个新建的iEntry 需要自己新建iEntry
}else{//此时iEntry没用
intermediateCode.addICode(FuncCall,IEntries.at(func->id), params, nullptr);
}
}
PRINT_WORD;//PRINT )
GET_A_WORD;
}else if(WORD_TYPE == LPARENT || WORD_TYPE == INTCON || WORD_TYPE == IDENFR || WORD_TYPE == PLUS || WORD_TYPE == MINU){
//函数实参的first集
/**
* 函数有参数 需要压栈
*/
func = nullptr;
temp = tableManager.cur;
while(temp != nullptr){
if (temp->entries->find(ident) != temp->entries->end()){
func = temp->entries->at(ident);
if (func->kind != FUNC_INT && func->kind != FUNC_VOID){
func = nullptr;
}
break;
}
temp = temp->Father_Entry;
}
func_name = ident;
errorHandler.error_line = func_ident_line;//记录可能发生错误的行号
auto * find_func = IEntries.at(func->id);//这个是函数定义头
auto * params = new IEntry;//函数实参IEntry 下面的id才是真正实在参数
params->values_Id = new vector<int>;
auto *func_rParams = params->values_Id;//FIXME:values_address解决了有些值可能不是直接imm显示的
FuncRParams(func_ident_line,func_rParams);
if (WORD_TYPE != RPARENT){
//Error 缺少右括号)
errorHandler.Insert_Error(RPARENT_MISSING);
}else {
//有参数的函数调用 src1函数定义头 src2函数参数IEntry 放在valueId
//TODO:明确传的是啥
//FParams->push_back(exp_iEntry->Id);//后端去拷贝assign
if (func->kind == FUNC_INT){
intermediateCode.addICode(FuncCall,IEntries.at(func->id), params, iEntry);//FIXME:又返回值的函数 把值给到这个新建的iEntry 需要自己新建iEntry
}else{
intermediateCode.addICode(FuncCall,IEntries.at(func->id), params, nullptr);
}
PRINT_WORD;//PRINT )
GET_A_WORD;//point to next WORD
}
}else{
//函数无参 且缺失 ‘)’
errorHandler.Insert_Error(RPARENT_MISSING);
}
/**
* 调用函数时的func
*/
if (func){
if(func->kind == FUNC_INT)
Exp_type = 0;
else if(func->kind == FUNC_VOID)//void 或者根本没有定义的函数 且已经报错未定义
Exp_type = -5;
}else{
Exp_type = -4;
}
}else if(lexer.ch == '['){
PrimaryExp(iEntry,value,InOtherFunc);
}else{
//Error or PrimaryExp 's LVal
PrimaryExp(iEntry,value,InOtherFunc);//下放错误
}
}else{
Exp_type = 0;
int op;
UnaryOp(op);
UnaryExp(iEntry,value,InOtherFunc);
if (op == 0){
;//无事
}else if (op == 1){
if (iEntry->canGetValue){
value = 0-value;
}else{
intermediateCode.addICode(Sub,0,iEntry,iEntry);
}
}else if(op ==2 ){
//FIXME:仅出现在条件表达式?TODO
}
}
if (!isLValInStmt)
Print_Grammar_Output("<UnaryExp>");
}
void Parser::PrimaryExp(IEntry * iEntry,int & value,bool InOtherFunc) {
if (WORD_TYPE == LPARENT){
PRINT_WORD;//PRINT (
GET_A_WORD;
Exp(iEntry, value, InOtherFunc);
if (WORD_TYPE != RPARENT){
//Error
errorHandler.Insert_Error(RPARENT_MISSING);
}else{
PRINT_WORD;//PRINT )
GET_A_WORD;
}
}else if(WORD_TYPE == INTCON){
Exp_type = 0;
Number(iEntry, value, InOtherFunc);
}else{ // 指向ident LVal->GetInt
auto *lVal = new IEntry;
LVal(&lVal, value, InOtherFunc);//不在这一层报错? 放到下一层LVal = getint() | Exp &是为了改变iEntry指向
if (WORD_TYPE == ASSIGN){//FIXME:从Stmt-> LVal = ...来的 如果LVal为全局 或者非全局的赋值呢 标签? lw?
//TODO:使用全局变量 直接读值 编译时存好 0 或者具体值 这点在语法分析时没做好 需要MIPS code 进行进一步
//TODO: 写入全局变量 如果写入值编译时确定 则直接更新编译时的IEntry|否则
//赋值语句 需要找对真正的写地址!!!
PRINT_WORD;//PRINT =
GET_A_WORD;
if (WORD_TYPE == GETINTTK){
PRINT_WORD;//PRITN GETINT
GET_A_WORD;
PRINT_WORD;//PRINT (
GET_A_WORD;
if(WORD_TYPE == RPARENT){
PRINT_WORD;
GET_A_WORD;
}else{
errorHandler.Insert_Error(RPARENT_MISSING);
}
intermediateCode.addICode(GetInt, nullptr, nullptr,lVal);
lVal->canGetValue = false;
} else {
auto*exp = new IEntry;
Exp(exp, value, InOtherFunc);//FIXME:直接将LVal的IEntry赋值到Exp中 表示Exp的最终结果就是LVal的内存所在区域的值! 如果不是直接求出值 那么
intermediateCode.addICode(Assign,exp, nullptr,lVal);//一般的传递
lVal->canGetValue = false;
}
//FIXME:这里是用来表示LVal是真正的左值 也就是语法树中不被算作Exp的 也就是本来LVal = getint() | Exp这些是在Stmt中的 我的写法会让它在Stmt-》Exp中进行推导完成 无伤大雅 在此告诉自己
isLValInStmt = true;
}else{
//拷贝
iEntry->imm = lVal->imm;
iEntry->canGetValue = lVal->canGetValue;
iEntry->startAddress = lVal->startAddress;
iEntry->type = lVal->type;
iEntry->offset_IEntry = lVal->offset_IEntry;
iEntry->original_Name = lVal->original_Name;
iEntry->values_Id = lVal->values_Id;
iEntry->dim1_length = lVal->dim1_length;
iEntry->total_length = lVal->total_length;
iEntry->has_return = lVal->has_return;
iEntry->isGlobal = lVal->isGlobal;
}
//不是赋值语句 需要将LVal找到的IEntry 传回上面 我现在不想用二级指针
}
if (!isLValInStmt)
Print_Grammar_Output("<PrimaryExp>");
}
//TODO:LVal说明是引用曾经定义过的变量(源程序) 需要二级指针进行重定向
//TODO: 值 地址 地址是需要拷贝原来数组的一切东西 只是type == 1 && offset is valid valueId 指向的IEntry就恒定为这个数组默认的值了 查询 如果canGet 就Get 不能 就lw sw 相对于这个IEntry的startAddress || 写入值 置canGet为false sw startAddress
void Parser::
LVal(IEntry ** iEntry,int & value,bool inOtherFunc) { // 这里面中的容易错的地方 ident line已经指向下一个字符前所在的行
if (WORD_TYPE != IDENFR){
//Error
}
PRINT_WORD;//PRINT IDENT
string ident = WORD_DISPLAY;
int error_const_line = lexer.line;
int error_semicolon_missing_line = lexer.line_lastWord;
Kind kind = VAR;
int op =0;
Entry * temp = tableManager.cur;
//无论是否报错 都继续 报了错就是正常的
GET_A_WORD;
IEntry * array_exps[3];
int values[3];
while(WORD_TYPE == LBRACK){
op++;
PRINT_WORD;//PRINT [
GET_A_WORD;
array_exps[op] = new IEntry;
Exp(array_exps[op], values[op], inOtherFunc);
if (WORD_TYPE != RBRACK){
//Error 缺少有中括号]
errorHandler.Insert_Error(RBRACK_MISSING);
}else{
PRINT_WORD;//PRINT ]
GET_A_WORD;//POINT TO NEXT WORD
}
}
/**
* 数组在定义时长度肯定已经确定 同时值会存储在tableManager的符号表系统中
* 所有由中间代码小组件的value(编译时确定)都会拷贝到符号表的Entry中---暂不清楚 反正IEntry是主要的 Entry存在id映射到IEntry
*/
//引用LVal 搜寻之前定义时的类型,从而得出当前引用LVal时的类型 ------实际上LVal必须引用元素 即得到的一定是值---并不是 可以参数LVal是地址 一维或者二维都行
temp = tableManager.cur;
Entry *find;
Exp_type = -3;
while (temp!= nullptr){
if(temp->entries->find(ident) != temp->entries->end()){
Kind kind1 = (find = (temp->entries->at(ident)))->kind;
if(kind1 == ARRAY_1_VAR || kind1 == ARRAY_1_CONST){
Exp_type = 1-op;
}else if(kind1 == ARRAY_2_VAR || kind1 == ARRAY_2_CONST){
Exp_type = 2-op;
}else if (kind1 == VAR || kind1 == CONST){
Exp_type = 0-op;
}else{
//实际上是函数赋值 是未定义的
}
break;
}
temp = temp->Father_Entry;
}
int dim1_length = IEntries.at(find->id)->dim1_length;
int index = 0;
auto * index_entry = new IEntry;
if (Exp_type == -3){
//没找到 未定义
// errorHandler.Insert_Error(NOT_DEFINE);
}else if(Exp_type < 0){
//超出维数的引用 不出现
}else if(Exp_type == 0){
//address for writing
//
IEntry *_val;
if (IEntries.at(find->id)->type == 0){
_val = IEntries.at(find->id);
}else{
_val = IEntries.at(IEntries.at(find->id)->values_Id->at(0));
}
if (op == 2){
if (WORD_TYPE == Type::ASSIGN){
(*iEntry)->type =2;
}else{
(*iEntry)->type =0;
}
if(array_exps[2]->canGetValue && array_exps[1]->canGetValue){
index = array_exps[1]->imm*dim1_length + array_exps[2]->imm;
intermediateCode.addICode(GetArrayElement,index,_val,*iEntry);
}else{
if (array_exps[1]->canGetValue){
int t = array_exps[1]->imm*dim1_length;
intermediateCode.addICode(IntermediateCodeType::Add,t,array_exps[2],index_entry);
intermediateCode.addICode(GetArrayElement,index_entry,_val,*iEntry);//此时iEntry在getArrayElement中会储存对应的address 方便之后的lw
}
else if(array_exps[2]->canGetValue){
auto *t = new IEntry;
intermediateCode.addICode(IntermediateCodeType::Mult,dim1_length,array_exps[1],t);
intermediateCode.addICode(IntermediateCodeType::Add,array_exps[2],t,index_entry);
intermediateCode.addICode(GetArrayElement,index_entry,_val,*iEntry);
}else{
auto *t = new IEntry;
intermediateCode.addICode(IntermediateCodeType::Mult,dim1_length,array_exps[1],t);
intermediateCode.addICode(IntermediateCodeType::Add,array_exps[2],t,index_entry);
intermediateCode.addICode(GetArrayElement,index_entry,_val,*iEntry);
}
}//FIXME:数组定义时的IEntry (src2) 偏移index(不乘4)index_entry-》能get就get 不能就lw address
}else if(op == 1){//FIXME:可能you缺漏
if (WORD_TYPE == Type::ASSIGN){
(*iEntry)->type =2;
}else{
(*iEntry)->type =0;
}
intermediateCode.addICode(GetArrayElement,array_exps[1],_val,*iEntry);
}else if(op == 0){//TODO:统一都在values_Id
*iEntry = IEntries.at(IEntries.at(find->id)->values_Id->at(0));
}
}else if(Exp_type == 1){ //find就是对应的曾经定义过的Entry iEntry标识直接传递地址 非值的地址变量 只出现在函数形参中
//一维地址
/**
* 只可能是传给别人做地址
* 重新生成一个IEntry 用来表示内存位置
* TODO:先不考虑烦人的array找不到对应的值的情况---需要进一步生成index的中间代码
*/
(*iEntry)->type =1;
if (op == 0){
//没有其他需要加的offset
intermediateCode.addICode(GetAddress, nullptr,IEntries.at(find->id),*iEntry);
}else{
//有一个数字需要加
intermediateCode.addICode(GetAddress, array_exps[1],IEntries.at(find->id),*iEntry);
};
}else{ // 二级地址要小心 TODO: 形参的ConstExp是有用的 const不能作为数组参数!!! 所以只用伪造valuesID
//2维地址 伪造iEntry数组 认为是type = 1!!!! 取元素才不会取到你、空
(*iEntry)->type =1;
intermediateCode.addICode(GetAddress, nullptr,IEntries.at(find->id),*iEntry);
}
/**
* 此时array_exps[]为索引Exp的临时变量IEntry
* values[]为值(如果可以算出来)
* 注意value并没有存到IEntry中 因为IEntry的存在就是为了生成中间代码的四元式时不得不生产出来的临时变量来代表中间结果的变量 也有可能是编译时无法直接求出value的 所以需要中间临时变量进行代替 这一部分是会在生成MIPS时通过IEntry-》内存位置从而消除
*/
/**
* 二维地址
*/
/**
* index_entry index
*
*
*
* 要理解IEntry---在中间代码的层次 -不要太底层了 ---要做的是把一些有用的信息放进这里面---IEntry是要编号的 ICode的作用
*/
//错误的先后顺序 先检查方括号匹配 ---判断具体类型和未定义 再判断是否是左值定义常量 isLeft参数为true表示检测左值的
if(WORD_TYPE == ASSIGN ){
Entry *t = tableManager.cur;
Entry * _const = nullptr;
while(t != nullptr){
if(t->entries->find(ident) != t->entries->end()){
_const = t->entries->at(ident);
if (_const->kind == CONST || _const->kind == ARRAY_1_CONST || _const->kind == ARRAY_2_CONST){
errorHandler.error_line = error_const_line;
errorHandler.Insert_Error(CONST_LEFT);
}
}
t = t->Father_Entry;
}
}else if (WORD_TYPE == IDENFR || WORD_TYPE == RBRACE
|| WORD_TYPE == CONSTTK || WORD_TYPE == RETURNTK
|| WORD_TYPE == IFTK || WORD_TYPE == ELSETK
|| WORD_TYPE == CONTINUETK || WORD_TYPE == BREAKTK
||WORD_TYPE == PRINTFTK|| WORD_TYPE == FORTK
|| WORD_TYPE == VOIDTK || WORD_TYPE == LBRACE
||WORD_TYPE == INTTK){
//引用值结尾 却漏了分号 不在这里报错 但是要修改last_line