1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
package bjc.utils.parserutils;
import java.util.Deque;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import bjc.utils.data.IHolder;
import bjc.utils.data.IPair;
import bjc.utils.data.Pair;
import bjc.utils.funcdata.ITree;
import bjc.utils.funcdata.Tree;
final class TokenTransformer<T> implements Consumer<T> {
private final class OperatorHandler
implements UnaryOperator<IPair<Deque<ITree<T>>, ITree<T>>> {
private T element;
public OperatorHandler(T element) {
this.element = element;
}
@Override
public IPair<Deque<ITree<T>>, ITree<T>>
apply(IPair<Deque<ITree<T>>, ITree<T>> pair) {
return pair.bind((queuedASTs, currentAST) -> {
return handleOperator(queuedASTs);
});
}
private IPair<Deque<ITree<T>>, ITree<T>>
handleOperator(Deque<ITree<T>> queuedASTs) {
ITree<T> newAST;
if (isSpecialOperator.test(element)) {
newAST = handleSpecialOperator.apply(queuedASTs);
} else {
if (queuedASTs.size() < 2) {
throw new IllegalStateException(
"Attempted to parse binary operator without enough operands.\n"
+ "Problem operator is " + element
+ "\nPossible operand is: \n\t"
+ queuedASTs.peek());
}
ITree<T> rightAST = queuedASTs.pop();
ITree<T> leftAST = queuedASTs.pop();
newAST = new Tree<>(element, leftAST, rightAST);
}
queuedASTs.push(newAST);
return new Pair<>(queuedASTs, newAST);
}
}
private IHolder<IPair<Deque<ITree<T>>, ITree<T>>> initialState;
private Predicate<T> operatorPredicate;
private Predicate<T> isSpecialOperator;
private Function<Deque<ITree<T>>, ITree<T>> handleSpecialOperator;
public TokenTransformer(
IHolder<IPair<Deque<ITree<T>>, ITree<T>>> initialState,
Predicate<T> operatorPredicate, Predicate<T> isSpecialOperator,
Function<Deque<ITree<T>>, ITree<T>> handleSpecialOperator) {
this.initialState = initialState;
this.operatorPredicate = operatorPredicate;
this.isSpecialOperator = isSpecialOperator;
this.handleSpecialOperator = handleSpecialOperator;
}
@Override
public void accept(T element) {
if (operatorPredicate.test(element)) {
initialState.transform(new OperatorHandler(element));
} else {
ITree<T> newAST = new Tree<>(element);
initialState.doWith((pair) -> {
pair.doWith((queue, currentAST) -> {
queue.push(newAST);
});
});
initialState.transform((pair) -> {
return pair.bind((queue, currentAST) -> {
return new Pair<>(queue, newAST);
});
});
}
}
}
|