peer-at-code-parser-java/src/be/jeffcheasey88/peeratcode/parser/state/StateTree.java
2023-07-05 10:31:14 +02:00

78 lines
2 KiB
Java

package be.jeffcheasey88.peeratcode.parser.state;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
import be.jeffcheasey88.peeratcode.parser.Token;
import be.jeffcheasey88.peeratcode.parser.TokenValidator;
import be.jeffcheasey88.peeratcode.parser.Tokenizer;
public class StateTree<E>{
private List<StateTree<E>> childs;
Function<TokenValidator, Boolean> checker;
private BuilderStateTree<E, ?> builder;
public StateTree(){
this.childs = new ArrayList<>();
}
public void seed(Tokenizer tokenizer, E container){
TokenValidator validator = new TokenValidator(tokenizer.getTokens().toArray(new Token[0]));
while(validator.hasNext()) {
System.out.println("seed");
E build = internalSeed(validator, container);
if(build == null) break;
}
}
<B> B internalSeed(TokenValidator validator, E element){
for(StateTree<E> child : this.childs){
TokenValidator branch = validator.branch();
if(child.checker == null){
E builded = child.internalSeed(branch, element);
if(builded != null){
validator.merge(branch);
return (B) builded;
}
continue;
}
if(child.checker.apply(branch)){
E builded = child.internalSeed(branch, element);
if(builded != null){
validator.merge(branch);
return (B) builded;
}
}
}
if(this.builder != null) return (B) this.builder.build(validator, element);
return null;
}
public <T extends StateTree<E>> StateTree<E> then(StateTree<E> child){
childs.add(child);
return child;
}
public <T extends StateTree<E>> StateTree<E> then(Function<TokenValidator, Boolean> checker){
StateTree<E> state = new StateTree<>();
state.checker = checker;
this.childs.add(state);
return state;
}
public <T extends StateTree<E>> StateTree<E> loop(){
this.childs.add(this);
return this;
}
public <B> StateTree<B> end(BiFunction<E, TokenValidator, B> builder){
BuilderStateTree<E, B> builderState = new BuilderStateTree<>(builder);
this.builder = builderState;
return builderState;
}
}