1 | import Expression from './expression';
|
2 | import RRLoop from '../ui/rrloop';
|
3 | import RRSequence from '../ui/rrsequence';
|
4 | import RuleReference from './rulereference';
|
5 | import Repetition from './repetition';
|
6 | import Literal from './literal';
|
7 | import GrammarToRRDiagram from './grammartorrdiagram';
|
8 | import RRElement from '../ui/rrelement';
|
9 | import GrammarToBNF from './grammartobnf';
|
10 |
|
11 | export default class Sequence extends Expression {
|
12 |
|
13 | |
14 |
|
15 |
|
16 | constructor(expressions) {
|
17 | super();
|
18 | if (arguments.length == 0) {
|
19 | expressions = [];
|
20 | } else if (expressions.constructor !== Array) {
|
21 | expressions = arguments;
|
22 | }
|
23 | this.expressions = expressions;
|
24 | }
|
25 |
|
26 | |
27 |
|
28 |
|
29 | getExpressions() {
|
30 | return this.expressions;
|
31 | }
|
32 |
|
33 | |
34 |
|
35 |
|
36 |
|
37 | toRRElement(grammarToRRDiagram) {
|
38 | const rrElementList = [];
|
39 | for (let i = 0; i < this.expressions.length; i++) {
|
40 | const expression = this.expressions[i];
|
41 | let rrElement = expression.toRRElement(grammarToRRDiagram);
|
42 |
|
43 | if (i < this.expressions.length - 1 && this.expressions[i + 1] instanceof Repetition) {
|
44 | const repetition = this.expressions[i + 1];
|
45 | const repetitionExpression = repetition.getExpression();
|
46 | if (repetitionExpression instanceof Sequence) {
|
47 |
|
48 | const subExpressions = repetitionExpression.getExpressions();
|
49 | if (subExpressions.length == 2 && subExpressions[0] instanceof Literal) {
|
50 | if(expression.equals(subExpressions[1])) {
|
51 | const maxRepetitionCount = repetition.getMaxRepetitionCount();
|
52 | if (maxRepetitionCount == null || maxRepetitionCount > 1) {
|
53 | rrElement = new RRLoop(expression.toRRElement(grammarToRRDiagram), subExpressions[0].toRRElement(grammarToRRDiagram), repetition.getMinRepetitionCount(), (maxRepetitionCount == null ? null : maxRepetitionCount));
|
54 | i++;
|
55 | }
|
56 | }
|
57 | }
|
58 | } else if(expression instanceof RuleReference) {
|
59 | const ruleLink = expression;
|
60 |
|
61 | if (repetitionExpression instanceof RuleReference && repetitionExpression.getRuleName().equals(ruleLink.getRuleName())) {
|
62 | const maxRepetitionCount = repetition.getMaxRepetitionCount();
|
63 | if (maxRepetitionCount == null || maxRepetitionCount > 1) {
|
64 | rrElement = new RRLoop(ruleLink.toRRElement(grammarToRRDiagram), null, repetition.getMinRepetitionCount(), (maxRepetitionCount == null ? null : maxRepetitionCount));
|
65 | i++;
|
66 | }
|
67 | }
|
68 | }
|
69 | }
|
70 | rrElementList.push(rrElement);
|
71 | }
|
72 | return new RRSequence(rrElementList);
|
73 | }
|
74 |
|
75 | |
76 |
|
77 |
|
78 |
|
79 |
|
80 | toBNF(grammarToBNF, sb, isNested) {
|
81 | if (this.expressions.length == 0) {
|
82 | sb.push("( )");
|
83 | return;
|
84 | }
|
85 | if (isNested && this.expressions.length > 1) {
|
86 | sb.push("( ");
|
87 | }
|
88 | const isCommaSeparator = grammarToBNF.isCommaSeparator;
|
89 | for (let i = 0; i < this.expressions.length; i++) {
|
90 | if (i > 0) {
|
91 | if (isCommaSeparator) {
|
92 | sb.push(" ,");
|
93 | }
|
94 | sb.push(" ");
|
95 | }
|
96 | this.expressions[i].toBNF(grammarToBNF, sb, this.expressions.length == 1 && isNested || !isCommaSeparator);
|
97 | }
|
98 | if (isNested && this.expressions.length > 1) {
|
99 | sb.push(" )");
|
100 | }
|
101 | }
|
102 |
|
103 | |
104 |
|
105 |
|
106 |
|
107 | equals(o) {
|
108 | if(!(o instanceof Sequence)) {
|
109 | return false;
|
110 | }
|
111 | if(this.expressions.length != o.expressions.length) {
|
112 | return false;
|
113 | }
|
114 | for (let i = 0; i < this.expressions.length; i++) {
|
115 | if(!this.expressions[i].equals(o.expressions[i])) {
|
116 | return false;
|
117 | }
|
118 | }
|
119 | return true;
|
120 | }
|
121 |
|
122 | }
|