-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCompilerError.cs
More file actions
214 lines (157 loc) · 6.79 KB
/
CompilerError.cs
File metadata and controls
214 lines (157 loc) · 6.79 KB
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
/*
File: CompilerError.cs
Purpose: Representation of an error instance within a compiler.
Author: Allan C. Milne.
Version: 2.2
Date: 9th March 2011.
Namespace: AllanMilne.Ardkit
Uses: ICompilerError, IToken, ISymbol, LanguageType.
Exposes: CompilerError, IoError, LexicalError, SyntaxError, NotDeclaredError, AlreadyDeclaredError, TypeConflictError.
Description:
A class hierarchy that represents the errors that may occur during compilation.
The CompilerError class is the abstract base class for all error types with
the different actual error type instances represented by the specific subclasses.
The overridden ToString() method provides an appropriate error message;
the base class version provides the message prefix including the error position.
The base class also implements the IComparable interface allowing a collection of error objects to be sorted by line/column.
Also defined are subclasses that represent typical errors that may occur in the scanning, parsing and semantic analysis phases.
Use with a specific compiler/language:
Semantic errors are specific to the language being processed;
while the classes defined in the toolkit may reflect those required for a language it may be that additional semantic error classes will be required.
1. For each kind of semantic error not supported by the toolkit, define a subclass from CompilerError.
2. Include any attributes required to specify the error.
3. define a constructor that takes at least the error token and calls the base constructor with this token.
4. override the ToString method to provide an appropriate error message;
this should call base.ToString() to provide the message prefix.
*/
using System;
using System.Text;
using System.IO;
namespace AllanMilne.PALCompiler
{
//=== Representation of a compiler error.
public abstract class CompilerError : ICompilerError, IComparable {
private static ComponentInfo info = new ComponentInfo (
"CompilerError", "2.2", "March 2011", "Allan C. Milne", "Class hierarchy representing compiler errors");
public static ComponentInfo Info
{ get { return info; } }
protected IToken token; // the token causing the error.
public IToken ErrorToken
{ get { return token; } }
//--- constructor method.
public CompilerError (IToken where) {
token = where;
}
//--- Implements the Icomparable interface.
public int CompareTo (Object obj) {
IToken thisToken = this.ErrorToken;
IToken thatToken = ((CompilerError)obj).ErrorToken;
if (thisToken.Line < thatToken.Line) return -1; // this < obj
else if (thisToken.Line > thatToken.Line) return 1; // this > obj
else if (thisToken.Column < thatToken.Column) return -1; // this < obj
else if (thisToken.Column > thatToken.Column) return 1; // this > obj
else return 0; // this = obj
} // end CompareTo method.
//--- Provides a message prefix with the ine/column number of the error.
public override String ToString () {
return String.Format ("({0:d},{1:d}) : ", token.Line, token.Column);
}
} // end CompilerError abstract class.
//=== Represent an input/output error detected while reading the soruce program stream.
public class IoError : CompilerError {
private IOException cause;
public IOException Cause
{ get { return cause; } }
public IoError (IToken where, IOException e)
: base (where)
{
cause = e;
}
public override String ToString () {
return String.Format ("{0:s}I/O error reading from source.\n{1:s}", base.ToString(), cause.ToString());
}
} // end IoError class.
//=== Represent an error in constructing a token as detected in the scanning process.
public class LexicalError : CompilerError {
public LexicalError (IToken where)
: base (where)
{}
public override String ToString () {
return String.Format ("{0:s} Lexical error {1:s} found.", base.ToString(), token.ToString());
}
} // end LexicalError class.
//=== Represent a syntax error as detected during the RD parsing phase.
public class SyntaxError : CompilerError {
private String expected;
public String Expected
{ get { return expected; } }
public SyntaxError (IToken where, String shouldBe)
: base (where)
{
expected = shouldBe;
}
public override String ToString () {
return String.Format ("{0:s}'{1:s}' found where '{2:s}' expected.", base.ToString(), token.ToString(), expected);
}
} // end SyntaxError class.
public class SyntaxError2 : CompilerError
{
private String expected;
public String Expected
{ get { return expected; } }
public SyntaxError2(IToken where, String shouldBe)
: base(where)
{
expected = shouldBe;
}
public override String ToString()
{
return String.Format("{0:s}{1:s} - '{2:s}' found.", base.ToString(), expected, token.ToString());
}
} // end SyntaxError class.
//=== Represent an undecalred identifier as detected in semantic analysis.
public class NotDeclaredError : CompilerError {
public NotDeclaredError (IToken id)
: base (id)
{}
public override String ToString () {
return String.Format ("{0:s} Identifier '{1:s}' is not declared.",
base.ToString(), token.TokenValue);
}// end ToString method.
} // end NotDeclaredError class.
//=== Represent an identifier that has already been declared as detected in semantic analysis.
public class AlreadyDeclaredError : CompilerError {
private ISymbol original;
public ISymbol OriginalDeclaration
{ get { return original; } }
public AlreadyDeclaredError (IToken id, ISymbol orig)
: base (id)
{
original = orig;
}
public override String ToString () {
int line = original.Source.Line;
return String.Format ("{0:s} Identifier '{1:s}' is already declared at line {2:d}.",
base.ToString(), token.TokenValue, line);
}// end ToString method.
} // end AlreadyDeclaredError class.
//=== Represent a type conflict error as detected in semantic analysis.
public class TypeConflictError : CompilerError {
private int typeFound;
public int TypeFound
{ get { return typeFound; } }
private int typeExpected;
public int TypeExpected
{ get { return typeExpected; } }
public TypeConflictError (IToken id, int found, int expected)
: base (id)
{
typeFound = found;
typeExpected = expected;
}
public override String ToString () {
return String.Format ("{0:s} Type conflict: '{1:s}' is of type {2:s} where {3:s} is expected.",
base.ToString(), token.ToString(), LanguageType.ToString(typeFound), LanguageType.ToString(typeExpected));
}// end ToString method.
} // end TypeConflictError class.
} // end namespace.