|
1 using System; |
|
2 using System.Collections.Generic; |
|
3 using System.Text; |
|
4 //Added |
|
5 using System.IO; |
|
6 |
|
7 public sealed class Lexer |
|
8 { |
|
9 private readonly IList<object> listLexemes; |
|
10 |
|
11 public Lexer(TextReader inputFile) |
|
12 { |
|
13 listLexemes = new List<object>(); |
|
14 ReadProgramFile(inputFile); |
|
15 } |
|
16 |
|
17 public IList<object> GetLexemes |
|
18 { |
|
19 get |
|
20 { |
|
21 return listLexemes; |
|
22 } |
|
23 } |
|
24 |
|
25 public enum Tokens |
|
26 { |
|
27 Add, |
|
28 Subtract, |
|
29 Multiply, |
|
30 Divide, |
|
31 Terminator, |
|
32 EqualTo, |
|
33 LessThan, |
|
34 GreaterThan, |
|
35 Comma, |
|
36 OpenParen, |
|
37 CloseParen, |
|
38 OpenBrac, |
|
39 CloseBrac |
|
40 } |
|
41 |
|
42 private void ReadProgramFile(System.IO.TextReader programFile) |
|
43 { |
|
44 while (programFile.Peek() != -1) |
|
45 { |
|
46 char symbol = (char)programFile.Peek(); |
|
47 |
|
48 if (char.IsWhiteSpace(symbol)) |
|
49 { |
|
50 // if the symbol is whitespace then move to next symbol |
|
51 programFile.Read(); |
|
52 } |
|
53 else if (char.IsLetter(symbol) || symbol == '_') |
|
54 { |
|
55 //identify the tokens |
|
56 |
|
57 StringBuilder token = new StringBuilder(); |
|
58 |
|
59 while (char.IsLetter(symbol) || symbol == '_') |
|
60 { |
|
61 token.Append(symbol); |
|
62 programFile.Read(); |
|
63 |
|
64 if (programFile.Peek() == -1) |
|
65 { |
|
66 break; |
|
67 } |
|
68 else |
|
69 { |
|
70 symbol = (char)programFile.Peek(); |
|
71 } |
|
72 } |
|
73 |
|
74 listLexemes.Add(token.ToString()); |
|
75 } |
|
76 else if (symbol == '"') |
|
77 { |
|
78 // string literal |
|
79 StringBuilder stringLiteral = new StringBuilder(); |
|
80 |
|
81 programFile.Read(); // skip the '"' |
|
82 |
|
83 if (programFile.Peek() == -1) |
|
84 { |
|
85 throw new Exception("String literal is not terminated"); |
|
86 } |
|
87 |
|
88 while ((symbol = (char)programFile.Peek()) != '"') |
|
89 { |
|
90 stringLiteral.Append(symbol); |
|
91 programFile.Read(); |
|
92 |
|
93 if (programFile.Peek() == -1) |
|
94 { |
|
95 throw new Exception("String literal is not terminated"); |
|
96 } |
|
97 } |
|
98 |
|
99 // skip the terminating " |
|
100 programFile.Read(); |
|
101 listLexemes.Add(stringLiteral); |
|
102 } |
|
103 else if (char.IsDigit(symbol)) |
|
104 { |
|
105 // numeric literal |
|
106 |
|
107 StringBuilder numericLiteral = new StringBuilder(); |
|
108 |
|
109 while (char.IsDigit(symbol)) |
|
110 { |
|
111 numericLiteral.Append(symbol); |
|
112 programFile.Read(); |
|
113 |
|
114 if (programFile.Peek() == -1) |
|
115 { |
|
116 break; |
|
117 } |
|
118 else |
|
119 { |
|
120 symbol = (char)programFile.Peek(); |
|
121 } |
|
122 } |
|
123 |
|
124 listLexemes.Add(int.Parse(numericLiteral.ToString())); |
|
125 } |
|
126 else switch (symbol) |
|
127 { |
|
128 case '(': |
|
129 programFile.Read(); |
|
130 listLexemes.Add(Tokens.OpenParen); |
|
131 break; |
|
132 |
|
133 case ')': |
|
134 programFile.Read(); |
|
135 listLexemes.Add(Tokens.CloseParen); |
|
136 break; |
|
137 |
|
138 case '=': |
|
139 programFile.Read(); |
|
140 listLexemes.Add(Tokens.EqualTo); |
|
141 break; |
|
142 |
|
143 case ';': |
|
144 programFile.Read(); |
|
145 listLexemes.Add(Tokens.Terminator); |
|
146 break; |
|
147 |
|
148 case '<': |
|
149 programFile.Read(); |
|
150 listLexemes.Add(Tokens.LessThan); |
|
151 break; |
|
152 |
|
153 case '>': |
|
154 programFile.Read(); |
|
155 listLexemes.Add(Tokens.GreaterThan); |
|
156 break; |
|
157 |
|
158 case ',': |
|
159 programFile.Read(); |
|
160 listLexemes.Add(Tokens.Comma); |
|
161 break; |
|
162 |
|
163 case '/': |
|
164 programFile.Read(); |
|
165 listLexemes.Add(Tokens.Divide); |
|
166 break; |
|
167 |
|
168 case '*': |
|
169 programFile.Read(); |
|
170 listLexemes.Add(Tokens.Multiply); |
|
171 break; |
|
172 |
|
173 case '-': |
|
174 programFile.Read(); |
|
175 listLexemes.Add(Tokens.Subtract); |
|
176 break; |
|
177 |
|
178 case '+': |
|
179 programFile.Read(); |
|
180 listLexemes.Add(Tokens.Add); |
|
181 break; |
|
182 |
|
183 case '{': |
|
184 programFile.Read(); |
|
185 listLexemes.Add(Tokens.OpenBrac); |
|
186 break; |
|
187 |
|
188 case '}': |
|
189 programFile.Read(); |
|
190 listLexemes.Add(Tokens.CloseBrac); |
|
191 break; |
|
192 |
|
193 default: |
|
194 ExceptionHandler("unidentified symbol '" + symbol + "'"); |
|
195 break; |
|
196 } |
|
197 } |
|
198 } |
|
199 |
|
200 public void ExceptionHandler(string strException) |
|
201 { |
|
202 throw new Exception(strException); |
|
203 } |
|
204 } |