/trunk/jsdoc-toolkit/app/lib/JSDOC/TokenStream.js

http://jsdoc-toolkit.googlecode.com/ · JavaScript · 141 lines · 102 code · 23 blank · 16 comment · 47 complexity · 7acfe062315da55f4ae021ea4f0d156b MD5 · raw file

  1. if (typeof JSDOC == "undefined") JSDOC = {};
  2. /**
  3. @constructor
  4. */
  5. JSDOC.TokenStream = function(tokens) {
  6. this.tokens = (tokens || []);
  7. this.rewind();
  8. }
  9. /**
  10. @constructor
  11. @private
  12. */
  13. function VoidToken(/**String*/type) {
  14. this.toString = function() {return "<VOID type=\""+type+"\">"};
  15. this.is = function(){return false;}
  16. }
  17. JSDOC.TokenStream.prototype.rewind = function() {
  18. this.cursor = -1;
  19. }
  20. /**
  21. @type JSDOC.Token
  22. */
  23. JSDOC.TokenStream.prototype.look = function(/**Number*/n, /**Boolean*/considerWhitespace) {
  24. if (typeof n == "undefined") n = 0;
  25. if (considerWhitespace == true) {
  26. if (this.cursor+n < 0 || this.cursor+n > this.tokens.length) return {};
  27. return this.tokens[this.cursor+n];
  28. }
  29. else {
  30. var count = 0;
  31. var i = this.cursor;
  32. while (true) {
  33. if (i < 0) return new JSDOC.Token("", "VOID", "START_OF_STREAM");
  34. else if (i > this.tokens.length) return new JSDOC.Token("", "VOID", "END_OF_STREAM");
  35. if (i != this.cursor && (this.tokens[i] === undefined || this.tokens[i].is("WHIT"))) {
  36. if (n < 0) i--; else i++;
  37. continue;
  38. }
  39. if (count == Math.abs(n)) {
  40. return this.tokens[i];
  41. }
  42. count++;
  43. (n < 0)? i-- : i++;
  44. }
  45. return new JSDOC.Token("", "VOID", "STREAM_ERROR"); // because null isn't an object and caller always expects an object
  46. }
  47. }
  48. /**
  49. @type JSDOC.Token|JSDOC.Token[]
  50. */
  51. JSDOC.TokenStream.prototype.next = function(/**Number*/howMany) {
  52. if (typeof howMany == "undefined") howMany = 1;
  53. if (howMany < 1) return null;
  54. var got = [];
  55. for (var i = 1; i <= howMany; i++) {
  56. if (this.cursor+i >= this.tokens.length) {
  57. return null;
  58. }
  59. got.push(this.tokens[this.cursor+i]);
  60. }
  61. this.cursor += howMany;
  62. if (howMany == 1) {
  63. return got[0];
  64. }
  65. else return got;
  66. }
  67. /**
  68. @type JSDOC.Token[]
  69. */
  70. JSDOC.TokenStream.prototype.balance = function(/**String*/start, /**String*/stop) {
  71. if (!stop) stop = JSDOC.Lang.matching(start);
  72. var depth = 0;
  73. var got = [];
  74. var started = false;
  75. while ((token = this.look())) {
  76. if (token.is(start)) {
  77. depth++;
  78. started = true;
  79. }
  80. if (started) {
  81. got.push(token);
  82. }
  83. if (token.is(stop)) {
  84. depth--;
  85. if (depth == 0) return got;
  86. }
  87. if (!this.next()) break;
  88. }
  89. }
  90. JSDOC.TokenStream.prototype.getMatchingToken = function(/**String*/start, /**String*/stop) {
  91. var depth = 0;
  92. var cursor = this.cursor;
  93. if (!start) {
  94. start = JSDOC.Lang.matching(stop);
  95. depth = 1;
  96. }
  97. if (!stop) stop = JSDOC.Lang.matching(start);
  98. while ((token = this.tokens[cursor])) {
  99. if (token.is(start)) {
  100. depth++;
  101. }
  102. if (token.is(stop) && cursor) {
  103. depth--;
  104. if (depth == 0) return this.tokens[cursor];
  105. }
  106. cursor++;
  107. }
  108. }
  109. JSDOC.TokenStream.prototype.insertAhead = function(/**JSDOC.Token*/token) {
  110. this.tokens.splice(this.cursor+1, 0, token);
  111. }
  112. JSDOC.TokenStream.tokensToString = function(tokens) {
  113. var str = [];
  114. for (var i = 0, leni = tokens.length; i < leni; i++) {
  115. str.push(tokens[i].data);
  116. }
  117. return str.join('');
  118. }