parse-tokens.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import { parseAffixToken } from './affix-tokens.js';
  2. import { parseNumberToken } from './number-tokens.js';
  3. function parseSubpattern(src, pos, onError) {
  4. let State;
  5. (function (State) {
  6. State[State["Prefix"] = 0] = "Prefix";
  7. State[State["Number"] = 1] = "Number";
  8. State[State["Suffix"] = 2] = "Suffix";
  9. })(State || (State = {}));
  10. const prefix = [];
  11. const number = [];
  12. const suffix = [];
  13. let state = State.Prefix;
  14. let str = '';
  15. while (pos < src.length) {
  16. const char = src[pos];
  17. if (char === ';') {
  18. pos += 1;
  19. break;
  20. }
  21. switch (state) {
  22. case State.Prefix: {
  23. const token = parseAffixToken(src, pos, onError);
  24. if (token) {
  25. if (str) {
  26. prefix.push({ char: "'", str, width: str.length });
  27. str = '';
  28. }
  29. prefix.push(token);
  30. pos += token.width;
  31. }
  32. else {
  33. const token = parseNumberToken(src, pos);
  34. if (token) {
  35. if (str) {
  36. prefix.push({ char: "'", str, width: str.length });
  37. str = '';
  38. }
  39. state = State.Number;
  40. number.push(token);
  41. pos += token.width;
  42. }
  43. else {
  44. str += char;
  45. pos += 1;
  46. }
  47. }
  48. break;
  49. }
  50. case State.Number: {
  51. const token = parseNumberToken(src, pos);
  52. if (token) {
  53. number.push(token);
  54. pos += token.width;
  55. }
  56. else {
  57. state = State.Suffix;
  58. }
  59. break;
  60. }
  61. case State.Suffix: {
  62. const token = parseAffixToken(src, pos, onError);
  63. if (token) {
  64. if (str) {
  65. suffix.push({ char: "'", str, width: str.length });
  66. str = '';
  67. }
  68. suffix.push(token);
  69. pos += token.width;
  70. }
  71. else {
  72. str += char;
  73. pos += 1;
  74. }
  75. break;
  76. }
  77. }
  78. }
  79. if (str)
  80. suffix.push({ char: "'", str, width: str.length });
  81. return { pattern: { prefix, number, suffix }, pos };
  82. }
  83. export function parseTokens(src, onError) {
  84. const { pattern, pos } = parseSubpattern(src, 0, onError);
  85. if (pos < src.length) {
  86. const { pattern: negative } = parseSubpattern(src, pos, onError);
  87. return { tokens: pattern, negative };
  88. }
  89. return { tokens: pattern };
  90. }