fork download
  1. function printTree(t, index, r, delim) {
  2. var out = [],
  3. prefix, res;
  4. r = r || '';
  5. delim = delim || ' ';
  6. index = index || 0;
  7. if (index < t.length) {
  8. t = t.map(function(el) {
  9. return el instanceof Array ? el : [el];
  10. });
  11. prefix = r ? r + delim : '';
  12. for (var i = 0; i < t[index].length; i++) {
  13. if (t[index][i] instanceof Array) {
  14. res = printTree(t[index][i], 0, r, delim);
  15. } else {
  16. res = [prefix + t[index][i]];
  17. }
  18. for (var j = 0; j < res.length; j++) {
  19. out = out.concat(printTree(t, index + 1, res[j], delim));
  20. }
  21. }
  22. } else {
  23. return [r];
  24. }
  25. return out;
  26. }
  27.  
  28. function Token(type, pos, value) {
  29. this.type = type;
  30. this.pos = pos;
  31. this.value = value;
  32. }
  33. Token.END_OF_LINE = 0;
  34. Token.OPERATOR = 1;
  35. Token.TEXT = 2;
  36.  
  37. function Parser(text) {
  38. this._text = text;
  39. this._pos = 0;
  40. this._len = text.length;
  41. }
  42. Parser.prototype = {
  43. operators: {
  44. '{': true,
  45. '}': true,
  46. '|': true
  47. },
  48. nextToken: function() {
  49. if (this._pos >= this._len) return new Token(Token.END_OF_LINE);
  50. if (this._text[this._pos] in this.operators) {
  51. return new Token(Token.OPERATOR, this._pos, this._text[this._pos++]);
  52. }
  53. var text = '',
  54. start = this._pos;
  55. while ((this._pos < this._len) && !(this._text[this._pos] in this.operators)) {
  56. text += this._text[this._pos];
  57. this._pos++;
  58. }
  59. return new Token(Token.TEXT, start, text);
  60. },
  61. getNextToken: function() {
  62. var pos = this._pos,
  63. result = this.nextToken();
  64. this._pos = pos;
  65. return result;
  66. }
  67. };
  68.  
  69. function Interpretter(text) {
  70. this._parser = new Parser(text);
  71. }
  72. Interpretter.prototype = {
  73. value: function() {
  74. var result = [],
  75. token = this._parser.getNextToken();
  76. while (token.type == Token.TEXT || (token.type == Token.OPERATOR && token.value == '{')) {
  77. token = this._parser.nextToken();
  78. if (token.type == Token.OPERATOR) {
  79. if (token.value == '{') {
  80. result.push(this.expression());
  81. } else {
  82. throw 'Syntax error at pos ' + token.pos;
  83. }
  84. } else {
  85. result.push(token.value);
  86. }
  87. token = this._parser.getNextToken();
  88. }
  89. return result;
  90. },
  91. includeValue: function(variants, value) {
  92. var hasNested = false;
  93. for (var i = 0; i < value.length; i++) {
  94. if (value[i] instanceof Array) {
  95. hasNested = true;
  96. break;
  97. }
  98. }
  99. if (hasNested) {
  100. variants.push(value);
  101. } else {
  102. variants = variants.concat(value);
  103. }
  104. return variants;
  105. },
  106. expression: function() {
  107. var variants = [],
  108. value = this.value(),
  109. token = this._parser.nextToken();
  110. variants = this.includeValue(variants, value);
  111. while (token.value == '|') {
  112. value = this.value();
  113. variants = this.includeValue(variants, value);
  114. token = this._parser.nextToken();
  115. }
  116. if (!token.type == '}') throw 'Syntax error at pos ' + token.pos;
  117. return variants;
  118. }
  119. };
  120.  
  121. var text = '{Пожалуйста|Просто} сделайте так, чтобы это ' +
  122. '{удивительное|крутое|простое} тестовое предложение {изменялось {быстро|мгновенно}' +
  123. ' случайным образом|менялось каждый раз}.';
  124. var interpretter = new Interpretter(text);
  125. var v = interpretter.value();
  126. var r = printTree(v);
  127. r.sort();
  128. print(r.join('\n'));
Success #stdin #stdout 0.01s 29720KB
stdin
Standard input is empty
stdout
Пожалуйста  сделайте так, чтобы это  крутое  тестовое предложение  изменялось  быстро  случайным образом .
Пожалуйста  сделайте так, чтобы это  крутое  тестовое предложение  изменялось  мгновенно  случайным образом .
Пожалуйста  сделайте так, чтобы это  крутое  тестовое предложение  менялось каждый раз .
Пожалуйста  сделайте так, чтобы это  простое  тестовое предложение  изменялось  быстро  случайным образом .
Пожалуйста  сделайте так, чтобы это  простое  тестовое предложение  изменялось  мгновенно  случайным образом .
Пожалуйста  сделайте так, чтобы это  простое  тестовое предложение  менялось каждый раз .
Пожалуйста  сделайте так, чтобы это  удивительное  тестовое предложение  изменялось  быстро  случайным образом .
Пожалуйста  сделайте так, чтобы это  удивительное  тестовое предложение  изменялось  мгновенно  случайным образом .
Пожалуйста  сделайте так, чтобы это  удивительное  тестовое предложение  менялось каждый раз .
Просто  сделайте так, чтобы это  крутое  тестовое предложение  изменялось  быстро  случайным образом .
Просто  сделайте так, чтобы это  крутое  тестовое предложение  изменялось  мгновенно  случайным образом .
Просто  сделайте так, чтобы это  крутое  тестовое предложение  менялось каждый раз .
Просто  сделайте так, чтобы это  простое  тестовое предложение  изменялось  быстро  случайным образом .
Просто  сделайте так, чтобы это  простое  тестовое предложение  изменялось  мгновенно  случайным образом .
Просто  сделайте так, чтобы это  простое  тестовое предложение  менялось каждый раз .
Просто  сделайте так, чтобы это  удивительное  тестовое предложение  изменялось  быстро  случайным образом .
Просто  сделайте так, чтобы это  удивительное  тестовое предложение  изменялось  мгновенно  случайным образом .
Просто  сделайте так, чтобы это  удивительное  тестовое предложение  менялось каждый раз .