|
1 /* |
|
2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * Header LEXICAL.CPP |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include "LEXICAL.H" |
|
21 |
|
22 Lexical::Lexical() |
|
23 : iType(ELexNL), iNumber(0) |
|
24 { |
|
25 iText[0] = '\0'; |
|
26 } |
|
27 |
|
28 Lexical::Lexical(const Lexical& aLex) |
|
29 { |
|
30 iType = aLex.iType; |
|
31 iNumber = aLex.iNumber; |
|
32 strcpy(iText, aLex.iText); |
|
33 } |
|
34 |
|
35 Lexical& Lexical::operator = (const Lexical& aLex) |
|
36 { |
|
37 iType = aLex.iType; |
|
38 iNumber = aLex.iNumber; |
|
39 strcpy(iText, aLex.iText); |
|
40 return *this; |
|
41 } |
|
42 |
|
43 int Lexical::CovertStringToHex() |
|
44 { |
|
45 char* curPtr = iText; // Position of current lexical in line |
|
46 int hexDigit; |
|
47 int number = 0; |
|
48 |
|
49 while (HexDigit(*curPtr, hexDigit)) |
|
50 { |
|
51 number = (16 * number) + hexDigit; |
|
52 curPtr++; |
|
53 } |
|
54 return number; |
|
55 } |
|
56 |
|
57 int Lexical::HexDigit(char aDigit, int& decimalEquivalent) |
|
58 { |
|
59 boolean validDigit = efalse; |
|
60 if ((aDigit >= '0') && (aDigit <= '9')) |
|
61 { |
|
62 decimalEquivalent = (aDigit - '0'); |
|
63 validDigit = etrue; |
|
64 } |
|
65 else if ((aDigit >= 'a') && (aDigit <= 'f')) |
|
66 { |
|
67 decimalEquivalent = 10 + (aDigit - 'a'); |
|
68 validDigit = etrue; |
|
69 } |
|
70 else if ((aDigit >= 'A') && (aDigit <= 'F')) |
|
71 { |
|
72 decimalEquivalent = 10 + (aDigit - 'A'); |
|
73 validDigit = etrue; |
|
74 } |
|
75 return validDigit; |
|
76 } |
|
77 |
|
78 ostream& operator << (ostream& out, const Lexical& aLex) |
|
79 { |
|
80 switch (aLex.iType) |
|
81 { |
|
82 case ELexEOF: |
|
83 { |
|
84 out << "EOF"; |
|
85 break; |
|
86 } |
|
87 case ELexNL: |
|
88 { |
|
89 out << "NL"; |
|
90 break; |
|
91 } |
|
92 case ELexNumber: |
|
93 { |
|
94 out << aLex.iNumber; |
|
95 break; |
|
96 } |
|
97 case ELexOperator: |
|
98 { |
|
99 out << aLex.iText[0]; |
|
100 break; |
|
101 } |
|
102 default: |
|
103 { |
|
104 out << aLex.iText; |
|
105 } |
|
106 } |
|
107 return out; |
|
108 } |
|
109 |
|
110 LexAnal::LexAnal(const char* aFilename) |
|
111 : iFilename(aFilename) |
|
112 { |
|
113 iFin.open(aFilename); |
|
114 iLex.iType = ELexNL; |
|
115 iLineNo = 0; |
|
116 } |
|
117 |
|
118 Lexical LexAnal::Read() // read next lexical into iLex |
|
119 { |
|
120 if (iLex.iType == ELexNL) |
|
121 { |
|
122 do |
|
123 { |
|
124 GetNextLex(); |
|
125 } |
|
126 while (iLex.iType == ELexNL); |
|
127 } |
|
128 else |
|
129 GetNextLex(); |
|
130 return iLex; |
|
131 } |
|
132 |
|
133 Lexical LexAnal::ReadNextLine() // read first lex on next line |
|
134 { |
|
135 GetNextLine(); |
|
136 return iLex; |
|
137 } |
|
138 |
|
139 void LexAnal::Report() |
|
140 { |
|
141 cerr << iFilename.Text() << '(' << iLineNo << "): \n"; |
|
142 cerr << iLine << '\n'; |
|
143 for (char* p = iLine; p < iLexPtr; p++) |
|
144 cerr << ' '; |
|
145 cerr << "^\n"; |
|
146 } |
|
147 |
|
148 LexAnal::~LexAnal() |
|
149 { |
|
150 iFin.close(); |
|
151 } |
|
152 |
|
153 void LexAnal::GetNextLex() |
|
154 { |
|
155 char ch; |
|
156 if (iLex.iType == ELexNL) |
|
157 { |
|
158 iFin.getline(iLine, MaxLineLen); |
|
159 // Remove any CR character that appear at the end when |
|
160 // reading a dos file on unix. |
|
161 PurgeLastCR(iLine); |
|
162 iCurPtr = iLine; |
|
163 iLineNo++; |
|
164 } |
|
165 |
|
166 while ((*iCurPtr == ' ') || (*iCurPtr == '\t')) |
|
167 iCurPtr++; |
|
168 ch = *iCurPtr; |
|
169 iLexPtr = iCurPtr; |
|
170 |
|
171 if ((ch == '\0') && (iFin.eof())) // finds lexical type |
|
172 iLex = ReadEOF(); |
|
173 else if ((ch == '\0') || (ch == '!')) // ! is a comment |
|
174 iLex = ReadNewLine(); |
|
175 else if ((ch == '-') || ((ch >= '0') && (ch <= '9'))) |
|
176 iLex = ReadNumber(); |
|
177 else if (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || (ch == '_')) |
|
178 iLex = ReadIdent(); |
|
179 else if (ch == '"') |
|
180 iLex = ReadString(); |
|
181 else |
|
182 iLex = ReadOperator(); |
|
183 } |
|
184 |
|
185 void LexAnal::GetNextLine() |
|
186 { |
|
187 iFin.getline(iLine, MaxLineLen); |
|
188 // Remove any CR character that appear at the end when |
|
189 // reading a dos file on unix. |
|
190 PurgeLastCR(iLine); |
|
191 iCurPtr = iLine; |
|
192 iLineNo++; |
|
193 |
|
194 char ch; |
|
195 while ((*iCurPtr == ' ') || (*iCurPtr == '\t')) |
|
196 iCurPtr++; |
|
197 ch = *iCurPtr; |
|
198 iLexPtr = iCurPtr; |
|
199 |
|
200 if ((ch == '\0') && (iFin.eof())) // finds lexical type |
|
201 iLex = ReadEOF(); |
|
202 else if ((ch == '\0') || (ch == '!')) |
|
203 iLex = ReadNewLine(); |
|
204 else if ((ch == '-') || ((ch >= '0') && (ch <= '9'))) |
|
205 iLex=ReadNumber(); |
|
206 else if (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || (ch == '_')) |
|
207 iLex = ReadIdent(); |
|
208 else if (ch == '"') |
|
209 iLex = ReadString(); |
|
210 else |
|
211 iLex = ReadOperator(); |
|
212 } |
|
213 |
|
214 void LexAnal::PurgeLastCR(char *aLine) |
|
215 { |
|
216 int len = strlen(aLine) - 1; |
|
217 if (len >= 0 && aLine[len] == '\r') |
|
218 { |
|
219 aLine[len] = '\0'; |
|
220 } |
|
221 } |
|
222 |
|
223 Lexical LexAnal::ReadEOF() |
|
224 { |
|
225 Lexical lex; |
|
226 lex.iType = ELexEOF; |
|
227 return lex; |
|
228 } |
|
229 |
|
230 Lexical LexAnal::ReadNewLine() |
|
231 { |
|
232 Lexical lex; |
|
233 lex.iType = ELexNL; |
|
234 while (*iCurPtr != '\0') |
|
235 iCurPtr++; |
|
236 return lex; |
|
237 } |
|
238 |
|
239 Lexical LexAnal::ReadNumber() |
|
240 { |
|
241 Lexical lex; |
|
242 char ch; |
|
243 boolean negative = efalse; |
|
244 lex.iType = ELexNumber; |
|
245 if (*iCurPtr == '-') |
|
246 { |
|
247 negative = etrue; |
|
248 iCurPtr++; |
|
249 } |
|
250 ch = *iCurPtr; |
|
251 while ((ch >= '0') && (ch <= '9')) |
|
252 { |
|
253 if (negative) |
|
254 lex.iNumber = (10 * lex.iNumber) - (*iCurPtr - '0'); |
|
255 else |
|
256 lex.iNumber=(10 * lex.iNumber) + (*iCurPtr - '0'); |
|
257 iCurPtr++; |
|
258 ch = *iCurPtr; |
|
259 } |
|
260 return lex; |
|
261 } |
|
262 |
|
263 |
|
264 Lexical LexAnal::ReadIdent() |
|
265 { |
|
266 Lexical lex; |
|
267 char ch; |
|
268 lex.iType = ELexIdent; |
|
269 do |
|
270 { |
|
271 iCurPtr++; |
|
272 ch = *iCurPtr; |
|
273 } |
|
274 while (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || (ch == '_') || ((ch >= '0') && (ch <= '9'))); |
|
275 strncpy(lex.iText, iLexPtr, iCurPtr - iLexPtr); |
|
276 lex.iText[iCurPtr - iLexPtr] = '\0'; |
|
277 return lex; |
|
278 } |
|
279 |
|
280 Lexical LexAnal::ReadString() |
|
281 { |
|
282 Lexical lex; |
|
283 char ch; |
|
284 lex.iType = ELexString; |
|
285 iCurPtr++; |
|
286 ch = *iCurPtr; |
|
287 while ((ch != '"') && (*iCurPtr != '\0')) |
|
288 { |
|
289 iCurPtr++; |
|
290 ch = *iCurPtr; |
|
291 } |
|
292 strncpy(lex.iText, iLexPtr + 1, iCurPtr - (iLexPtr + 1)); |
|
293 lex.iText[iCurPtr - (iLexPtr + 1)] = '\0'; |
|
294 if (ch == '"') |
|
295 iCurPtr++; // finds position after last double quotes |
|
296 else |
|
297 { |
|
298 cerr << "Warning: missing quotes\n"; |
|
299 Report(); |
|
300 } |
|
301 return lex; |
|
302 } |
|
303 |
|
304 Lexical LexAnal::ReadOperator() |
|
305 { |
|
306 Lexical lex; |
|
307 lex.iType = ELexOperator; |
|
308 lex.iText[0] = *iCurPtr; |
|
309 iCurPtr++; |
|
310 return lex; |
|
311 } |