UNPKG

5.45 kBJavaScriptView Raw
1import Expression from './expression';
2import RRChoice from '../ui/rrchoice';
3import RRLine from '../ui/rrline';
4import RRLoop from '../ui/rrloop';
5import GrammarToRRDiagram from './grammartorrdiagram';
6import RRElement from '../ui/rrelement';
7import GrammarToBNF from './grammartobnf';
8
9export default class Repetition extends Expression {
10
11 /**
12 * @param {Expression} expression
13 * @param {number} minRepetitionCount
14 * @param {?number} maxRepetitionCount
15 */
16 constructor(expression, minRepetitionCount, maxRepetitionCount) {
17 super();
18 this.expression = expression;
19 this.minRepetitionCount = minRepetitionCount | 0;
20 this.maxRepetitionCount = maxRepetitionCount;
21 }
22
23 /**
24 * @return {Expression}
25 */
26 getExpression() {
27 return this.expression;
28 }
29
30 /**
31 * @return {number}
32 */
33 getMinRepetitionCount() {
34 return this.minRepetitionCount;
35 }
36
37 /**
38 * @return {?number}
39 */
40 getMaxRepetitionCount() {
41 return this.maxRepetitionCount;
42 }
43
44 /**
45 * @param {GrammarToRRDiagram} grammarToRRDiagram
46 * @return {RRElement}
47 */
48 toRRElement(grammarToRRDiagram) {
49 const rrElement = this.expression.toRRElement(grammarToRRDiagram);
50 if (this.minRepetitionCount == 0) {
51 if (this.maxRepetitionCount == null || this.maxRepetitionCount > 1) {
52 return new RRChoice(new RRLoop(rrElement, null, 0, (this.maxRepetitionCount == null ? null : this.maxRepetitionCount - 1)), new RRLine());
53 }
54 return new RRChoice(rrElement, new RRLine());
55 }
56 return new RRLoop(rrElement, null, this.minRepetitionCount - 1, (this.maxRepetitionCount == null ? null : this.maxRepetitionCount - 1));
57 }
58
59 /**
60 * @param {GrammarToBNF} grammarToBNF
61 * @param {string[]} sb
62 * @param {boolean} isNested
63 */
64 toBNF(grammarToBNF, sb, isNested) {
65 const isUsingMultiplicationTokens = grammarToBNF.isUsingMultiplicationTokens;
66 if (this.maxRepetitionCount == null) {
67 if (this.minRepetitionCount > 0) {
68 if (this.minRepetitionCount == 1 && isUsingMultiplicationTokens) {
69 this.expression.toBNF(grammarToBNF, sb, true);
70 sb.push("+");
71 } else {
72 if (isNested) {
73 sb.push("( ");
74 }
75 if (this.minRepetitionCount > 1) {
76 sb.push(this.minRepetitionCount, " * ");
77 }
78 this.expression.toBNF(grammarToBNF, sb, false);
79 if (grammarToBNF.isCommaSeparator) {
80 sb.push(" ,");
81 }
82 sb.push(" ", "{ ");
83 this.expression.toBNF(grammarToBNF, sb, false);
84 sb.push(" }");
85 if (isNested) {
86 sb.push(" )");
87 }
88 }
89 } else {
90 if (isUsingMultiplicationTokens) {
91 this.expression.toBNF(grammarToBNF, sb, true);
92 sb.push("*");
93 } else {
94 sb.push("{ ");
95 this.expression.toBNF(grammarToBNF, sb, false);
96 sb.push(" }");
97 }
98 }
99 } else {
100 if (this.minRepetitionCount == 0) {
101 if (this.maxRepetitionCount == 1 && isUsingMultiplicationTokens) {
102 this.expression.toBNF(grammarToBNF, sb, true);
103 sb.push("?");
104 } else {
105 if (this.maxRepetitionCount > 1) {
106 sb.push(this.maxRepetitionCount, " * ");
107 }
108 sb.push("[ ");
109 this.expression.toBNF(grammarToBNF, sb, false);
110 sb.push(" ]");
111 }
112 } else {
113 if (this.minRepetitionCount == this.maxRepetitionCount) {
114 sb.push(this.minRepetitionCount, " * ");
115 this.expression.toBNF(grammarToBNF, sb, isNested);
116 } else {
117 if (isNested) {
118 sb.push("( ");
119 }
120 sb.push(this.minRepetitionCount, " * ");
121 this.expression.toBNF(grammarToBNF, sb, false);
122 if (grammarToBNF.isCommaSeparator) {
123 sb.push(" ,");
124 }
125 sb.push(" ", this.maxRepetitionCount - this.minRepetitionCount, " * ", "[ ");
126 this.expression.toBNF(grammarToBNF, sb, false);
127 sb.push(" ]");
128 if (isNested) {
129 sb.push(" )");
130 }
131 }
132 }
133 }
134 }
135
136 /**
137 * @param {*} o
138 * @return {boolean}
139 */
140 equals(o) {
141 if(!(o instanceof Repetition)) {
142 return false;
143 }
144 return this.expression.equals(o.expression) && this.minRepetitionCount == o.minRepetitionCount && this.maxRepetitionCount == null? o.maxRepetitionCount == null: this.maxRepetitionCount.equals(o.maxRepetitionCount);
145 }
146
147}