Skip to content

Commit 197f006

Browse files
committed
Smaller Code, corrected TypeChecker...
1 parent 2d60d4d commit 197f006

24 files changed

+497
-453
lines changed

Pascal.pas

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
1-
program fibonacci;
1+
program fibonacci_test;
22
var a : integer;
3-
var b: integer;
4-
var temp : integer ;
5-
var c : boolean;
3+
var b : integer;
4+
var d : integer;
5+
var c : boolean;
66
begin
7-
8-
if 1<2 then begin writeln(1); end else writeln(2)
9-
10-
// c := true = 1<2;
11-
{a := 1;
7+
a := 1;
128
b := 1;
13-
while True do
14-
begin
15-
writeln(a);
16-
b := a + b;
17-
18-
a := temp;
19-
end}
9+
c := true;
10+
a := a div b;
11+
c := 1 < 2;
12+
2013
end.

StupsCompiler.java

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
/**************************************************************************
2+
* Created by Christian Meter on 13th December 2012 *
3+
* *
4+
* Mainprogram for the StupsCompiler project *
5+
**************************************************************************
6+
* Usage: > java StupsCompiler -compile <Filename.pas> *
7+
**************************************************************************/
8+
19
import lexer.Lexer;
210
import lexer.LexerException;
311
import node.Start;
@@ -9,50 +17,63 @@
917
public class StupsCompiler {
1018

1119
public static void main(String[] args) throws LexerException, IOException, ParserException {
12-
if (args.length < 2) {
13-
System.out.println("# Error: Not enough arguments.\n# Usage: > java StupsCompiler -compile <Filename.pas>");
14-
} else if (args[0].equals("-compile")) {
15-
String input = "";
16-
String zeile;
17-
FileReader fr = new FileReader(args[1]);
18-
BufferedReader br = new BufferedReader(fr);
19-
20-
zeile = br.readLine();
21-
while (zeile != null) {
22-
input += zeile+"\n";
20+
if (args.length < 2) { // catch valid number of arguments
21+
System.out.println("# Error: Not enough arguments.\n# Usage: > java StupsCompiler -argument <Filename.pas>\n# Valid arguments are: compile, liveness.");
22+
System.exit(1);
23+
}
24+
if (!args[1].endsWith(".pas")) { // catch valid file extension
25+
System.out.println("# Error: Valid file extension is only '.pas'.");
26+
System.exit(1);
27+
}
28+
try {
29+
if (args[0].equals("-compile")) { // Compile section
30+
String input = "";
31+
String zeile;
32+
FileReader fr = new FileReader(args[1]);
33+
BufferedReader br = new BufferedReader(fr);
34+
2335
zeile = br.readLine();
36+
while (zeile != null) {
37+
input += zeile+"\n";
38+
zeile = br.readLine();
39+
}
40+
br.close();
41+
42+
// System.out.println("# Input: \n"+input);
43+
44+
parse(input);
45+
} else if (args[0].equals("-liveness")) {
46+
// Write something about liveness...
47+
} else {
48+
System.out.println("# Error: Wrong usage of StupsCompiler.\n# Usage: > java StupsCompiler -compile <Filename.pas>");
2449
}
25-
br.close();
26-
27-
System.out.println("############################################################################");
28-
System.out.println("# Input: \n"+input);
29-
System.out.println("############################################################################");
30-
parse(input);
31-
} else if (args[0].equals("-liveness")) {
32-
// Write something about liveness...
33-
} else {
34-
System.out.println("# Error: Wrong usage of StupsCompiler.\n# Usage: > java StupsCompiler -compile <Filename.pas>");
50+
} catch (FileNotFoundException e) {
51+
System.out.println("# Error: File '"+args[1]+"' not found. Please enter correct filename.");
52+
} catch (ParserException e) {
53+
System.out.println("# Error in: "+e.getMessage()+"\n");
54+
} catch (LexerException e) {
55+
System.out.println("# Error in: "+e.getMessage()+"\n");
3556
}
3657
}
3758

3859
private static void parse(String input) throws ParserException, LexerException, IOException {
3960
StringReader reader = new StringReader(input);
4061
PushbackReader r = new PushbackReader(reader, 100);
41-
System.out.println("# Start Lexing and Parsing...");
62+
// System.out.println("# Start Lexing and Parsing...");
4263
Lexer l = new Lexer(r);
4364
Parser parser = new Parser(l);
4465
Start start = parser.parse();
45-
System.out.println("# Lexing and Parsing: Finished with no errors.\n");
66+
// System.out.println("# Lexer and Parser: Finished with no errors.\n");
4667

47-
System.out.println("# Start printing the AST...");
48-
ASTPrinter printer = new ASTPrinter();
49-
start.apply(printer);
50-
System.out.println("# AST: Finished with no errors.\n");
68+
// System.out.println("# Start printing the AST...");
69+
// ASTPrinter printer = new ASTPrinter();
70+
// start.apply(printer);
71+
// System.out.println("# AST: Finished with no errors.\n");
5172

52-
System.out.println("# Start TypeChecker...");
53-
ASTTypeChecker interpreter = new ASTTypeChecker();
73+
// System.out.println("# Start TypeChecker...");
74+
TypeChecker interpreter = new TypeChecker();
5475
start.apply(interpreter);
55-
System.out.println("# TypeChecker: Finished with no errors.\n");
56-
System.out.println("################################# Success! #################################");
76+
// System.out.println("# TypeChecker: Finished with no errors.\n");
77+
// System.out.println("################################# Success! #################################\n");
5778
}
5879
}

ASTTypechecker.java renamed to TypeChecker.java

Lines changed: 49 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
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+
19
import analysis.DepthFirstAdapter;
210
import node.*;
311

412
import java.util.HashMap;
513

6-
public class ASTTypeChecker extends DepthFirstAdapter {
14+
public class TypeChecker extends DepthFirstAdapter {
715

816
private HashMap<String, String> symbolTable = new HashMap<String, String>();
917
private String result;
@@ -24,16 +32,15 @@ public void caseABreakExpr(ABreakExpr node) {
2432
} while (!parentName.equals("AStartExpr"));
2533

2634
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");
2836
System.exit(1);
29-
} else {
30-
printValidOperation("break");
3137
}
3238
}
3339

3440
/**
3541
* Look up all the declarations and put it into the HashMap
3642
*/
43+
@Override
3744
public void caseADeclarationExpr(ADeclarationExpr node) {
3845
String type = node.getRight().toString().toLowerCase().replaceAll(" ","");
3946
String[] var = node.getLeft().toString().toLowerCase().split(" ");
@@ -42,12 +49,15 @@ public void caseADeclarationExpr(ADeclarationExpr node) {
4249
if (!symbolTable.containsKey(aVar)) {
4350
symbolTable.put(aVar, type);
4451
} 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");
4653
System.exit(1);
4754
}
4855
}
4956
}
5057

58+
/**
59+
* Look up the := operator and it's correct syntax...
60+
*/
5161
@Override
5262
public void caseAAssignmentExpr(AAssignmentExpr node) {
5363
String identifier = node.getIdentifier().toString().toLowerCase().replaceAll(" ","");
@@ -57,31 +67,42 @@ public void caseAAssignmentExpr(AAssignmentExpr node) {
5767

5868
node.getExpr().apply(this); // Going through the AST
5969

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
6385
if (expr.equals("ANumberExpr")) {
6486
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");
6688
System.exit(1);
67-
} else {
68-
printValidOperation("assignment");
6989
}
7090
}
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
7599
if (expr.equals("AIdentifierExpr")) {
76100
String matchIdentifier = node.getIdentifier().toString().toLowerCase().replaceAll(" ","");
77101
checkDeclared(matchIdentifier);
78102
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");
82104
}
83105
}
84-
85106
}
86107

87108

@@ -98,8 +119,6 @@ public void caseAComparisonExpr(AComparisonExpr node) {
98119

99120
if (!left.equals(right))
100121
printErrorBooleanOperation(operation);
101-
else
102-
printValidOperation(operation);
103122
}
104123
@Override
105124
public void caseAOrExpr(AOrExpr node) {
@@ -110,8 +129,6 @@ public void caseAOrExpr(AOrExpr node) {
110129

111130
if (!left.equals(right))
112131
printErrorBooleanOperation(operation);
113-
else
114-
printValidOperation(operation);
115132
}
116133
@Override
117134
public void caseAXorExpr(AXorExpr node) {
@@ -123,8 +140,6 @@ public void caseAXorExpr(AXorExpr node) {
123140

124141
if (!left.equals(right))
125142
printErrorBooleanOperation(operation);
126-
else
127-
printValidOperation(operation);
128143
}
129144
@Override
130145
public void caseAAndExpr(AAndExpr node) {
@@ -136,19 +151,16 @@ public void caseAAndExpr(AAndExpr node) {
136151

137152
if (!left.equals(right))
138153
printErrorBooleanOperation(operation);
139-
else
140-
printValidOperation(operation);
141154
}
142155
@Override
143156
public void caseANotExpr(ANotExpr node) {
144157
String operation = "not";
145158
node.getExpr().apply(this);
146159

147160
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");
149162
System.exit(1);
150-
} else
151-
printValidOperation(operation);
163+
}
152164
}
153165

154166
/**************************************************************************************************
@@ -164,8 +176,6 @@ public void caseAPlusExpr(APlusExpr node) {
164176

165177
if (!left.equals(right))
166178
printErrorArithmeticOperation(operation);
167-
else
168-
printValidOperation(operation);
169179
}
170180
@Override
171181
public void caseAMinusExpr(AMinusExpr node) {
@@ -177,30 +187,26 @@ public void caseAMinusExpr(AMinusExpr node) {
177187

178188
if (!left.equals(right))
179189
printErrorArithmeticOperation(operation);
180-
else
181-
printValidOperation(operation);
182190
}
183191
@Override
184192
public void caseAUnaryMinusExpr(AUnaryMinusExpr node) {
185193
String operation = "unary -";
186194
node.getExpr().apply(this);
187195

188196
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");
190198
System.exit(1);
191-
} else
192-
printValidOperation(operation);
199+
}
193200
}
194201
@Override
195202
public void caseAUnaryPlusExpr(AUnaryPlusExpr node) {
196203
String operation = "unary +";
197204
node.getExpr().apply(this);
198205

199206
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");
201208
System.exit(1);
202-
} else
203-
printValidOperation(operation);
209+
}
204210
}
205211
@Override
206212
public void caseAModExpr(AModExpr node) {
@@ -212,8 +218,6 @@ public void caseAModExpr(AModExpr node) {
212218

213219
if (!left.equals(right))
214220
printErrorArithmeticOperation(operation);
215-
else
216-
printValidOperation(operation);
217221
}
218222
@Override
219223
public void caseAMultExpr(AMultExpr node) {
@@ -225,8 +229,6 @@ public void caseAMultExpr(AMultExpr node) {
225229

226230
if (!left.equals(right))
227231
printErrorArithmeticOperation(operation);
228-
else
229-
printValidOperation(operation);
230232
}
231233
@Override
232234
public void caseADivExpr(ADivExpr node) {
@@ -238,8 +240,6 @@ public void caseADivExpr(ADivExpr node) {
238240

239241
if (!left.equals(right))
240242
printErrorArithmeticOperation(operation);
241-
else
242-
printValidOperation(operation);
243243
}
244244

245245
/**
@@ -281,7 +281,7 @@ public void caseAIdentifierExpr(AIdentifierExpr node) {
281281
*/
282282
private void checkDeclared(String identifier) {
283283
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");
285285
System.exit(1);
286286
}
287287
}
@@ -290,17 +290,14 @@ private void checkDeclared(String identifier) {
290290
* Prepare output for arithmetic operations
291291
*/
292292
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");
294294
System.exit(1);
295295
}
296-
private void printValidOperation(String operation) {
297-
System.out.println("\t# Found: Valid '"+operation+"' Operation.");
298-
}
299296
/**
300297
* The same for boolean expressions
301298
*/
302299
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");
304301
System.exit(1);
305302
}
306303
}

0 commit comments

Comments
 (0)