-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprogram.cpp
178 lines (166 loc) · 5.49 KB
/
program.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
#include<string>
#include"LexicalAnalyzer.class.h"
#include"SyntacticAnalyzer.class.h"
#include"keywordlist.h"
#include"operatorlist.h"
#include"wordlist.h"
SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::analyze(LexicalAnalyzer& lexical_analyzer)
{
if(!subprogram(lexical_analyzer)) return ERROR;
if(lexical_analyzer.peeksymtype()!=PERIODTYPE)
{
if(lexical_analyzer.peeksymtype()==0) this->errorinfo="程序有错,这个程序到这里看上去应该已经结束了,但其实不是。是不是少了运算符或漏了左括号?";
else this->errorinfo="必须在程序结尾加一个句号,不要问我为神马,这就是语法!";
return ERROR;
}
else
{
this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(SyntacticAnalyzer::IntermediateCodeNode(HALT));
}
return RIGHT;
}
SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::subprogram(LexicalAnalyzer& lexical_analyzer)
{
int type=lexical_analyzer.peeksymtype();
if(type==CONSTTYPE)
{
if(!constsym(lexical_analyzer)) return ERROR;
type=lexical_analyzer.peeksymtype();
}
if(type==VARTYPE)
{
if(!varsym(lexical_analyzer)) return ERROR;
type=lexical_analyzer.peeksymtype();
}
if(type==PROCTYPE)
{
do
{
if(!procsym(lexical_analyzer)) return ERROR;
}while((type=lexical_analyzer.peeksymtype())==PROCTYPE);
}
return statement(lexical_analyzer);
}
SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::constsym(LexicalAnalyzer& lexical_analyzer)
{
int type;
SyntacticAnalyzer::IdentStackNode newnode(CONST);
if(lexical_analyzer.getsymtype()!=CONSTTYPE)
{
this->errorinfo="这里应该是一个const语句";
return ERROR;
}
do
{
if(lexical_analyzer.getsymtype()!=IDENTTYPE)
{
this->errorinfo="这里应该是一个标识符,例如:CONST X=6,Y=4;";
return ERROR;
}
else if(this->ident_stack_find(lexical_analyzer.getprevsymword().c_str(),QUERY_CUR_PROC)!=this->ident_stack.end())
{
this->errorinfo="我说,常量名好像有重复啊,你检查下,看看本级的,上一级的常量或者变量有没有叫这名儿的";
return ERROR;
}
else newnode.ident=lexical_analyzer.getprevsymword();
if(lexical_analyzer.getsymtype()!=EQLTYPE)
{
this->errorinfo="这里应该是一个等于符号,例如:CONST X=6,Y=4;";
return ERROR;
}
if(lexical_analyzer.getsymtype()!=NUMBERTYPE)
{
this->errorinfo="这里应该是一个数字,例如:CONST X=6,Y=4;";
return ERROR;
}
else
{
sscanf(lexical_analyzer.getprevsymword().c_str(),"%d",&newnode.value);
this->ident_stack.push_back(newnode);
}
}while((type=lexical_analyzer.getsymtype())==COMMATYPE);
if(type==SEMICOLONTYPE) return RIGHT;
else
{
this->errorinfo="const语句必须以分号结尾,例如:CONST X=6,Y=4; 请留意末尾的分号";
return ERROR;
}
}
SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::varsym(LexicalAnalyzer& lexical_analyzer)
{
int type;
SyntacticAnalyzer::IdentStackNode newnode(VAR);
if(lexical_analyzer.getsymtype()!=VARTYPE)
{
this->errorinfo="这里应该是一个var语句";
return ERROR;
}
do
{
if(lexical_analyzer.getsymtype()!=IDENTTYPE)
{
this->errorinfo="这里应该是一个标识符,例如:VAR X,Y,Z;";
return ERROR;
}
else if(this->ident_stack_find(lexical_analyzer.getprevsymword().c_str(),QUERY_CUR_PROC)!=this->ident_stack.end())
{
this->errorinfo="我说,变量名好像有重复啊,你检查下,看看本级的,上一级的变量或者常量有没有叫这名儿的";
return ERROR;
}
else
{
newnode.ident=lexical_analyzer.getprevsymword();
this->ident_stack.push_back(newnode);
this->declare_new_var(newnode.ident);
}
}while((type=lexical_analyzer.getsymtype())==COMMATYPE);
if(type==SEMICOLONTYPE) return RIGHT;
else
{
this->errorinfo="var语句必须以分号结尾,例如:VAR X,Y,Z; 请留意末尾的分号";
return ERROR;
}
}
SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::procsym(LexicalAnalyzer& lexical_analyzer)
{
std::string word;
if(lexical_analyzer.getsymtype()!=PROCTYPE)
{
this->errorinfo="这里应该是一个procedure语句";
return ERROR;
}
if(lexical_analyzer.getsymtype()!=IDENTTYPE)
{
this->errorinfo="这里应该有一个标识符,作为procedure的名字,例如:PROCEDURE PROC;";
return ERROR;
}
else if(this->procedure_find(word=lexical_analyzer.getprevsymword()))
{
this->errorinfo="过程名好像重复了耶!要记住哦,PL/0不能出现重复的过程名哦!一定不能重复哦!乖!";
return ERROR;
}
else
{
this->ident_stack.push_back(SyntacticAnalyzer::IdentStackNode(BOUND,this->cur_procedure_name,this->cur_procedure_index));
this->cur_procedure_name=word;
this->cur_procedure_index=intermediate_code_deque_vector.size();
this->intermediate_code_deque_vector.push_back(std::deque<IntermediateCodeNode>());
this->procedure_vector.push_back(word);
}
if(lexical_analyzer.getsymtype()!=SEMICOLONTYPE)
{
this->errorinfo="这里应该有一个分号,作为procedure声明和内容的分隔符,例如:PROCEDURE PROC; 请留意末尾的分号";
return ERROR;
}
if(!subprogram(lexical_analyzer)) return ERROR;
else
{
this->ident_stack_clear();
}
if(lexical_analyzer.getsymtype()!=SEMICOLONTYPE)
{
this->errorinfo="这里应该有一个分号,作为一个procedure结束,我知道加一个分号很无聊也不能促进减肥,但是这是语法,是规定,只要你爸不是李刚,就必需遵守这个规定";
return ERROR;
}
return RIGHT;
}