| 302 | } |
| 303 | |
| 304 | List<Token> TokenizeText(const String & fileName, const String & text, Procedure<TokenizeErrorType, CodePosition> errorHandler) |
| 305 | { |
| 306 | int lastPos = 0, pos = 0; |
| 307 | int line = 1, col = 0; |
| 308 | String file = fileName; |
| 309 | State state = State::Start; |
| 310 | StringBuilder tokenBuilder; |
| 311 | int tokenLine, tokenCol; |
| 312 | List<Token> tokenList; |
| 313 | LexDerivative derivative = LexDerivative::None; |
| 314 | TokenFlags tokenFlags = TokenFlag::AtStartOfLine; |
| 315 | auto InsertToken = [&](TokenType type) |
| 316 | { |
| 317 | derivative = LexDerivative::None; |
| 318 | tokenList.Add(Token(type, tokenBuilder.ToString(), tokenLine, tokenCol, pos, file, tokenFlags)); |
| 319 | tokenFlags = 0; |
| 320 | tokenBuilder.Clear(); |
| 321 | }; |
| 322 | auto ProcessTransferChar = [&](char nextChar) |
| 323 | { |
| 324 | switch (nextChar) |
| 325 | { |
| 326 | case '\\': |
| 327 | case '\"': |
| 328 | case '\'': |
| 329 | tokenBuilder.Append(nextChar); |
| 330 | break; |
| 331 | case 't': |
| 332 | tokenBuilder.Append('\t'); |
| 333 | break; |
| 334 | case 's': |
| 335 | tokenBuilder.Append(' '); |
| 336 | break; |
| 337 | case 'n': |
| 338 | tokenBuilder.Append('\n'); |
| 339 | break; |
| 340 | case 'r': |
| 341 | tokenBuilder.Append('\r'); |
| 342 | break; |
| 343 | case 'b': |
| 344 | tokenBuilder.Append('\b'); |
| 345 | break; |
| 346 | } |
| 347 | }; |
| 348 | while (pos <= text.Length()) |
| 349 | { |
| 350 | char curChar = (pos < text.Length() ? text[pos] : ' '); |
| 351 | char nextChar = (pos < text.Length() - 1) ? text[pos + 1] : '\0'; |
| 352 | if (lastPos != pos) |
| 353 | { |
| 354 | if (curChar == '\n') |
| 355 | { |
| 356 | line++; |
| 357 | col = 0; |
| 358 | } |
| 359 | else |
| 360 | col++; |
| 361 | lastPos = pos; |
no test coverage detected