1
+ /**************************************************************************
2
+ * Created by Christian Meter on 13th December 2012 *
3
+ * *
4
+ * Typechecking all the identifiers and their operations *
5
+ **************************************************************************
6
+ * Usage: > java StupsCompiler -compile <Filename.pas> *
7
+ **************************************************************************/
8
+
1
9
import analysis .DepthFirstAdapter ;
2
10
import node .*;
3
11
4
12
import java .util .HashMap ;
5
13
6
- public class ASTTypeChecker extends DepthFirstAdapter {
14
+ public class TypeChecker extends DepthFirstAdapter {
7
15
8
16
private HashMap <String , String > symbolTable = new HashMap <String , String >();
9
17
private String result ;
@@ -24,16 +32,15 @@ public void caseABreakExpr(ABreakExpr node) {
24
32
} while (!parentName .equals ("AStartExpr" ));
25
33
26
34
if (parentName .equals ("AStartExpr" )) {
27
- System .out .println ("# Error: User 'break' only in a 'while' context!" );
35
+ System .out .println ("# Error: User 'break' only in a 'while' context!\n " );
28
36
System .exit (1 );
29
- } else {
30
- printValidOperation ("break" );
31
37
}
32
38
}
33
39
34
40
/**
35
41
* Look up all the declarations and put it into the HashMap
36
42
*/
43
+ @ Override
37
44
public void caseADeclarationExpr (ADeclarationExpr node ) {
38
45
String type = node .getRight ().toString ().toLowerCase ().replaceAll (" " ,"" );
39
46
String [] var = node .getLeft ().toString ().toLowerCase ().split (" " );
@@ -42,12 +49,15 @@ public void caseADeclarationExpr(ADeclarationExpr node) {
42
49
if (!symbolTable .containsKey (aVar )) {
43
50
symbolTable .put (aVar , type );
44
51
} else {
45
- System .out .println ("# Error: Already specified '" + aVar + "' as '" + symbolTable .get (aVar ) + "'. Terminating..." );
52
+ System .out .println ("# Error: Already specified '" + aVar + "' as '" + symbolTable .get (aVar ) + "'. Terminating...\n " );
46
53
System .exit (1 );
47
54
}
48
55
}
49
56
}
50
57
58
+ /**
59
+ * Look up the := operator and it's correct syntax...
60
+ */
51
61
@ Override
52
62
public void caseAAssignmentExpr (AAssignmentExpr node ) {
53
63
String identifier = node .getIdentifier ().toString ().toLowerCase ().replaceAll (" " ,"" );
@@ -57,31 +67,42 @@ public void caseAAssignmentExpr(AAssignmentExpr node) {
57
67
58
68
node .getExpr ().apply (this ); // Going through the AST
59
69
60
- /**
61
- * If on the right side of := is only a number, check the type of the identifier
62
- */
70
+ // Check if arithmetic expressions are
71
+ if (expr .equals ("APlusExpr" ) || expr .equals ("AMinusExpr" ) || expr .equals ("AMultExpr" ) || expr .equals ("ADivExpr" ) || expr .equals ("AModExpr" ) || expr .equals ("AUnaryMinusExpr" ) || expr .equals ("AUnaryPlusExpr" )) {
72
+ if (!type .equals ("integer" )) {
73
+ System .out .println ("# Error: Wrong types. Expected 'integer'.\n " );
74
+ System .exit (1 );
75
+ }
76
+ }
77
+ // Check if those comparisons and boolean arithmetic are assigned to booleans
78
+ if (expr .equals ("AOrExpr" ) || expr .equals ("AXorExpr" ) || expr .equals ("AAndExpr" ) || expr .equals ("ANotExpr" ) || expr .equals ("AComparisonExpr" ) ) {
79
+ if (!type .equals ("boolean" )) {
80
+ System .out .println ("# Error: Wrong types. Expected 'boolean'.\n " );
81
+ System .exit (1 );
82
+ }
83
+ }
84
+ // If on the right side of := is only a number, check the type of the identifier
63
85
if (expr .equals ("ANumberExpr" )) {
64
86
if (!type .equals ("integer" )) {
65
- System .out .println ("# Error: Syntax of a simple assignment is 'integer' ':=' 'integer'. " );
87
+ System .out .println ("# Error: Syntax of a simple assignment is: 'integer' ':=' 'integer'; \n " );
66
88
System .exit (1 );
67
- } else {
68
- printValidOperation ("assignment" );
69
89
}
70
90
}
71
-
72
- /**
73
- * If on the right side of := is only an identifier, check both types
74
- */
91
+ // If there was only true or false found
92
+ if (expr .equals ("ATrueExpr" ) || expr .equals ("AFalseExpr" )) {
93
+ if (!type .equals ("boolean" )) {
94
+ System .out .println ("# Error: Can't assign a boolean to an integer.\n " );
95
+ System .exit (1 );
96
+ }
97
+ }
98
+ // If on the right side of := is only an identifier, check both types
75
99
if (expr .equals ("AIdentifierExpr" )) {
76
100
String matchIdentifier = node .getIdentifier ().toString ().toLowerCase ().replaceAll (" " ,"" );
77
101
checkDeclared (matchIdentifier );
78
102
if (!symbolTable .get (identifier ).equals (symbolTable .get (identifier ))) {
79
- System .out .println ("# Error: Wrong types. '" +identifier +"' is '" +symbolTable .get (identifier )+"' and '" +matchIdentifier +"' is type '" +symbolTable .get (matchIdentifier )+"'." );
80
- } else {
81
- printValidOperation ("assignment" );
103
+ System .out .println ("# Error: Wrong types. '" +identifier +"' is '" +symbolTable .get (identifier )+"' and '" +matchIdentifier +"' is type '" +symbolTable .get (matchIdentifier )+"'.\n " );
82
104
}
83
105
}
84
-
85
106
}
86
107
87
108
@@ -98,8 +119,6 @@ public void caseAComparisonExpr(AComparisonExpr node) {
98
119
99
120
if (!left .equals (right ))
100
121
printErrorBooleanOperation (operation );
101
- else
102
- printValidOperation (operation );
103
122
}
104
123
@ Override
105
124
public void caseAOrExpr (AOrExpr node ) {
@@ -110,8 +129,6 @@ public void caseAOrExpr(AOrExpr node) {
110
129
111
130
if (!left .equals (right ))
112
131
printErrorBooleanOperation (operation );
113
- else
114
- printValidOperation (operation );
115
132
}
116
133
@ Override
117
134
public void caseAXorExpr (AXorExpr node ) {
@@ -123,8 +140,6 @@ public void caseAXorExpr(AXorExpr node) {
123
140
124
141
if (!left .equals (right ))
125
142
printErrorBooleanOperation (operation );
126
- else
127
- printValidOperation (operation );
128
143
}
129
144
@ Override
130
145
public void caseAAndExpr (AAndExpr node ) {
@@ -136,19 +151,16 @@ public void caseAAndExpr(AAndExpr node) {
136
151
137
152
if (!left .equals (right ))
138
153
printErrorBooleanOperation (operation );
139
- else
140
- printValidOperation (operation );
141
154
}
142
155
@ Override
143
156
public void caseANotExpr (ANotExpr node ) {
144
157
String operation = "not" ;
145
158
node .getExpr ().apply (this );
146
159
147
160
if (!result .equals ("boolean" )) {
148
- System .out .println ("# Error: Syntax of '" + operation + "' is 'not' ' boolean' = 'boolean'. " );
161
+ System .out .println ("# Error: Syntax of '" + operation + "' is: ' boolean' : = '" + operation + "' ' boolean'; \n " );
149
162
System .exit (1 );
150
- } else
151
- printValidOperation (operation );
163
+ }
152
164
}
153
165
154
166
/**************************************************************************************************
@@ -164,8 +176,6 @@ public void caseAPlusExpr(APlusExpr node) {
164
176
165
177
if (!left .equals (right ))
166
178
printErrorArithmeticOperation (operation );
167
- else
168
- printValidOperation (operation );
169
179
}
170
180
@ Override
171
181
public void caseAMinusExpr (AMinusExpr node ) {
@@ -177,30 +187,26 @@ public void caseAMinusExpr(AMinusExpr node) {
177
187
178
188
if (!left .equals (right ))
179
189
printErrorArithmeticOperation (operation );
180
- else
181
- printValidOperation (operation );
182
190
}
183
191
@ Override
184
192
public void caseAUnaryMinusExpr (AUnaryMinusExpr node ) {
185
193
String operation = "unary -" ;
186
194
node .getExpr ().apply (this );
187
195
188
196
if (!result .equals ("integer" ) && !node .getExpr ().getClass ().getSimpleName ().equals ("AIdentifierExpr" ) && !node .getExpr ().getClass ().getSimpleName ().equals ("ANumberExpr" )) {
189
- System .out .println ("# Error: Syntax of '" +operation +"' is ' " +operation +"' 'integer' = 'integer'. " );
197
+ System .out .println ("# Error: Syntax of '" +operation +"' is: 'integer' := ' " +operation +"' 'integer'; \n " );
190
198
System .exit (1 );
191
- } else
192
- printValidOperation (operation );
199
+ }
193
200
}
194
201
@ Override
195
202
public void caseAUnaryPlusExpr (AUnaryPlusExpr node ) {
196
203
String operation = "unary +" ;
197
204
node .getExpr ().apply (this );
198
205
199
206
if (!result .equals ("integer" ) && !node .getExpr ().getClass ().getSimpleName ().equals ("AIdentifierExpr" ) && !node .getExpr ().getClass ().getSimpleName ().equals ("ANumberExpr" )) {
200
- System .out .println ("# Error: Syntax of '" +operation +"' is ' " +operation +"' 'integer' = 'integer'. " );
207
+ System .out .println ("# Error: Syntax of '" +operation +"' is: 'integer' := ' " +operation +"' 'integer'; \n " );
201
208
System .exit (1 );
202
- } else
203
- printValidOperation (operation );
209
+ }
204
210
}
205
211
@ Override
206
212
public void caseAModExpr (AModExpr node ) {
@@ -212,8 +218,6 @@ public void caseAModExpr(AModExpr node) {
212
218
213
219
if (!left .equals (right ))
214
220
printErrorArithmeticOperation (operation );
215
- else
216
- printValidOperation (operation );
217
221
}
218
222
@ Override
219
223
public void caseAMultExpr (AMultExpr node ) {
@@ -225,8 +229,6 @@ public void caseAMultExpr(AMultExpr node) {
225
229
226
230
if (!left .equals (right ))
227
231
printErrorArithmeticOperation (operation );
228
- else
229
- printValidOperation (operation );
230
232
}
231
233
@ Override
232
234
public void caseADivExpr (ADivExpr node ) {
@@ -238,8 +240,6 @@ public void caseADivExpr(ADivExpr node) {
238
240
239
241
if (!left .equals (right ))
240
242
printErrorArithmeticOperation (operation );
241
- else
242
- printValidOperation (operation );
243
243
}
244
244
245
245
/**
@@ -281,7 +281,7 @@ public void caseAIdentifierExpr(AIdentifierExpr node) {
281
281
*/
282
282
private void checkDeclared (String identifier ) {
283
283
if (!symbolTable .containsKey (identifier )) {
284
- System .out .println ("# Error: Undeclared variable '" +identifier +"' found. Terminating." );
284
+ System .out .println ("# Error: Undeclared variable '" +identifier +"' found. Terminating.\n " );
285
285
System .exit (1 );
286
286
}
287
287
}
@@ -290,17 +290,14 @@ private void checkDeclared(String identifier) {
290
290
* Prepare output for arithmetic operations
291
291
*/
292
292
private void printErrorArithmeticOperation (String operation ) {
293
- System .out .println ("# Error: Syntax of '" +operation +"' is 'integer' ' " +operation +"' 'integer' = 'integer'. " );
293
+ System .out .println ("# Error: Syntax of '" +operation +"' is: 'integer' := 'integer' ' " +operation +"' 'integer'; \n " );
294
294
System .exit (1 );
295
295
}
296
- private void printValidOperation (String operation ) {
297
- System .out .println ("\t # Found: Valid '" +operation +"' Operation." );
298
- }
299
296
/**
300
297
* The same for boolean expressions
301
298
*/
302
299
private void printErrorBooleanOperation (String operation ) {
303
- System .out .println ("# Error: Syntax of '" +operation +"' is 'boolean' ' " +operation +"' 'boolean' = 'boolean'. " );
300
+ System .out .println ("# Error: Syntax of '" +operation +"' is: 'boolean' := 'boolean' ' " +operation +"' 'boolean'; \n " );
304
301
System .exit (1 );
305
302
}
306
303
}
0 commit comments