Lexer.cs 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Text;
  6. using System.Text.RegularExpressions;
  7. namespace Larkdown.Parser.Lexer
  8. {
  9. public class Lexer
  10. {
  11. private readonly string _source;
  12. private readonly Queue<Token> _buffer;
  13. private int _position = 0;
  14. public Lexer(string source)
  15. {
  16. _source = Regex.Replace(source, @"\r\n|\n\r|\n|\r", "\n");
  17. _buffer = new Queue<Token>();
  18. }
  19. public IEnumerable<Token> Tokens()
  20. {
  21. State state = new LineStartState();
  22. while (state != null)
  23. {
  24. state = state.Next(this);
  25. while (_buffer.Count > 0)
  26. {
  27. yield return _buffer.Dequeue();
  28. }
  29. }
  30. yield break;
  31. }
  32. public Lexer Emit(Token token)
  33. {
  34. _buffer.Enqueue(token);
  35. return this;
  36. }
  37. public char Read()
  38. {
  39. return _source[_position++];
  40. }
  41. public string Read(Regex exp)
  42. {
  43. var match = exp.Match(_source, _position);
  44. _position += match.Length;
  45. return match.Success ? match.Captures[0].Value : String.Empty;
  46. }
  47. public char Peek()
  48. {
  49. return _source[_position];
  50. }
  51. public bool IsEof()
  52. {
  53. return _position == _source.Length;
  54. }
  55. }
  56. }