mark.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. var TokenType = require('../token-types');
  2. /**
  3. * Mark whitespaces and comments
  4. * @param {Array} tokens
  5. */
  6. function markSpacesAndComments(tokens) {
  7. var tokensLength = tokens.length;
  8. var lastSpaceIndex = -1;
  9. var lastSpaceOrCommentIndex = -1;
  10. var spaces = [-1, -1];
  11. var token; // current token
  12. var type; // current token's type
  13. // For every token in the token list, mark spaces and line breaks
  14. // as spaces (set both `ws` and `sc` flags). Mark multiline comments
  15. // with `sc` flag.
  16. // If there are several spaces or tabs or line breaks or multiline
  17. // comments in a row, group them: take the last one's index number
  18. // and save it to the first token in the group as a reference
  19. // (e.g., `ws_last = 7` for a group of whitespaces or `sc_last = 9`
  20. // for a group of whitespaces and comments):
  21. for (var i = 0; i < tokensLength; i++) {
  22. type = tokens[i].type;
  23. if (type === TokenType.Space ||
  24. type === TokenType.Tab ||
  25. type === TokenType.Newline) {
  26. markSpace(tokens, i, spaces);
  27. } else if (type === TokenType.CommentML) {
  28. markComment(tokens, i, spaces);
  29. } else {
  30. markEndOfSpacesAndComments(tokens, i, spaces);
  31. }
  32. }
  33. markEndOfSpacesAndComments(tokens, i, spaces);
  34. }
  35. function markSpace(tokens, i, spaces) {
  36. var token = tokens[i];
  37. token.ws = true;
  38. token.sc = true;
  39. if (spaces[0] === -1) spaces[0] = i;
  40. if (spaces[1] === -1) spaces[1] = i;
  41. }
  42. function markComment(tokens, i, spaces) {
  43. var ws = spaces[0];
  44. tokens[i].sc = true;
  45. if (ws !== -1) {
  46. tokens[ws].ws_last = i - 1;
  47. spaces[0] = -1;
  48. }
  49. }
  50. function markEndOfSpacesAndComments(tokens, i, spaces) {
  51. var ws = spaces[0];
  52. var sc = spaces[1];
  53. if (ws !== -1) {
  54. tokens[ws].ws_last = i - 1;
  55. spaces[0] = -1;
  56. }
  57. if (sc !== -1) {
  58. tokens[sc].sc_last = i - 1;
  59. spaces[1] = -1;
  60. }
  61. }
  62. /**
  63. * Pair brackets
  64. * @param {Array} tokens
  65. */
  66. function markBrackets(tokens) {
  67. var tokensLength = tokens.length;
  68. var ps = [], // parenthesis
  69. sbs = [], // square brackets
  70. cbs = [], // curly brackets
  71. t; // current token
  72. // For every token in the token list, if we meet an opening (left)
  73. // bracket, push its index number to a corresponding array.
  74. // If we then meet a closing (right) bracket, look at the corresponding
  75. // array. If there are any elements (records about previously met
  76. // left brackets), take a token of the last left bracket (take
  77. // the last index number from the array and find a token with
  78. // this index number) and save right bracket's index as a reference:
  79. for (var i = 0; i < tokens.length; i++) {
  80. t = tokens[i];
  81. var type = t.type;
  82. if (type === TokenType.LeftParenthesis) {
  83. ps.push(i);
  84. } else if (type === TokenType.RightParenthesis) {
  85. if (ps.length) {
  86. t.left = ps.pop();
  87. tokens[t.left].right = i;
  88. }
  89. } else if (type === TokenType.LeftSquareBracket) {
  90. sbs.push(i);
  91. } else if (type === TokenType.RightSquareBracket) {
  92. if (sbs.length) {
  93. t.left = sbs.pop();
  94. tokens[t.left].right = i;
  95. }
  96. } else if (type === TokenType.LeftCurlyBracket) {
  97. cbs.push(i);
  98. } else if (type === TokenType.RightCurlyBracket) {
  99. if (cbs.length) {
  100. t.left = cbs.pop();
  101. tokens[t.left].right = i;
  102. }
  103. }
  104. }
  105. }
  106. /**
  107. * @param {Array} tokens
  108. */
  109. function markTokens(tokens) {
  110. // Mark paired brackets:
  111. markBrackets(tokens);
  112. // Mark whitespaces and comments:
  113. markSpacesAndComments(tokens);
  114. }
  115. module.exports = markTokens;