1 package de.fhdw.wtf.parser;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Iterator;
6
7 import de.fhdw.wtf.common.ast.Operation;
8 import de.fhdw.wtf.common.ast.OperationModifier;
9 import de.fhdw.wtf.common.ast.OperationModifierAbstract;
10 import de.fhdw.wtf.common.ast.visitor.OperationModifierVisitor;
11 import de.fhdw.wtf.common.exception.parser.AbstractParserException;
12 import de.fhdw.wtf.common.exception.parser.NoSemicolonException;
13 import de.fhdw.wtf.common.exception.parser.OperationModifierAlreadyAddedException;
14 import de.fhdw.wtf.common.stream.TokenStream;
15 import de.fhdw.wtf.common.token.Token;
16
17
18
19
20 public final class OperationModifierParser {
21
22
23
24
25 private final TokenStream stream;
26
27
28
29
30 private final Collection<AbstractParserException> exceptions;
31
32
33
34
35
36
37
38
39
40 private OperationModifierParser(final TokenStream stream, final Collection<AbstractParserException> exceptions) {
41 this.stream = stream;
42 this.exceptions = exceptions;
43 }
44
45
46
47
48
49
50
51
52
53
54 static OperationModifierParser create(final TokenStream stream, final Collection<AbstractParserException> exceptions) {
55 return new OperationModifierParser(stream, exceptions);
56 }
57
58
59
60
61
62
63
64
65
66
67
68
69 Collection<OperationModifier> parse(final Operation currentOperation) throws AbstractParserException {
70 final Collection<OperationModifier> result = new ArrayList<>();
71 while (this.stream.hasNext()) {
72 if (this.stream.peek().isSemicolonToken()) {
73 this.stream.next();
74 currentOperation.setLastToken(this.stream.peek());
75 break;
76 } else {
77 try {
78 result.add(this.parseOperationModifier(result));
79 } catch (final OperationModifierAlreadyAddedException e) {
80 this.exceptions.add(e);
81 ParserUtils.skipToSemicolonToken(this.stream);
82 break;
83 }
84 }
85 }
86 return result;
87 }
88
89
90
91
92
93
94
95
96
97
98
99 private OperationModifier parseOperationModifier(final Collection<OperationModifier> modifiers)
100 throws AbstractParserException {
101 final Token nextToken = this.stream.peek();
102 if (nextToken.isOperationModifierToken()) {
103 if (this.containsOperationModifier(modifiers, nextToken)) {
104 throw OperationModifierAlreadyAddedException.create(nextToken);
105 }
106 if (nextToken.isAbstractOperationToken()) {
107 this.stream.removeFirst();
108 return OperationModifierAbstract.create(nextToken, this.stream.peek());
109 }
110 }
111 throw NoSemicolonException.create(nextToken);
112 }
113
114
115
116
117
118
119
120
121
122
123 private boolean containsOperationModifier(final Collection<OperationModifier> modifiers, final Token modifier) {
124 final Iterator<OperationModifier> i = modifiers.iterator();
125 while (i.hasNext()) {
126 final OperationModifier current = i.next();
127 if (current.accept(new OperationModifierVisitor() {
128
129 @Override
130 public boolean handle(final OperationModifier abstract1) {
131 return modifier.isAbstractOperationToken();
132 }
133
134 })) {
135 return true;
136 }
137 }
138 return false;
139 }
140 }