mirror of
https://github.com/DanilaFe/abacus
synced 2026-01-28 01:25:19 +00:00
Add a lot of comments. More to come.
This commit is contained in:
@@ -5,13 +5,33 @@ import java.util.HashMap;
|
||||
import java.util.Stack;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* A pattern that can be compiled from a string and used in lexing.
|
||||
* @param <T> the type that is used to identify and sort this pattern.
|
||||
*/
|
||||
public class Pattern<T> {
|
||||
|
||||
/**
|
||||
* The ID of this pattern.
|
||||
*/
|
||||
private T id;
|
||||
/**
|
||||
* The head of this pattern.
|
||||
*/
|
||||
private PatternNode<T> head;
|
||||
/**
|
||||
* The source string of this pattern.
|
||||
*/
|
||||
private String source;
|
||||
/**
|
||||
* The index at which the compilation has stopped.
|
||||
*/
|
||||
private int index;
|
||||
|
||||
/**
|
||||
* A map of regex operator to functions that modify a PatternChain
|
||||
* with the appropriate operation.
|
||||
*/
|
||||
private HashMap<Character, Function<PatternChain<T>, PatternChain<T>>> operations =
|
||||
new HashMap<Character, Function<PatternChain<T>, PatternChain<T>>>() {{
|
||||
put('+', Pattern.this::transformPlus);
|
||||
@@ -19,11 +39,23 @@ public class Pattern<T> {
|
||||
put('?', Pattern.this::transformQuestion);
|
||||
}};
|
||||
|
||||
/**
|
||||
* A regex operator function that turns the chain
|
||||
* into a one-or-more chain.
|
||||
* @param chain the chain to transform.
|
||||
* @return the modified chain.
|
||||
*/
|
||||
private PatternChain<T> transformPlus(PatternChain<T> chain){
|
||||
chain.tail.outputStates.add(chain.head);
|
||||
return chain;
|
||||
}
|
||||
|
||||
/**
|
||||
* A regex operator function that turns the chain
|
||||
* into a zero-or-more chain.
|
||||
* @param chain the chain to transform.
|
||||
* @return the modified chain.
|
||||
*/
|
||||
private PatternChain<T> transformStar(PatternChain<T> chain){
|
||||
LinkNode<T> newTail = new LinkNode<>();
|
||||
LinkNode<T> newHead = new LinkNode<>();
|
||||
@@ -36,6 +68,12 @@ public class Pattern<T> {
|
||||
return chain;
|
||||
}
|
||||
|
||||
/**
|
||||
* A regex operator function that turns the chain
|
||||
* into a zero-or-one chain.
|
||||
* @param chain the chain to transform.
|
||||
* @return the modified chain.
|
||||
*/
|
||||
private PatternChain<T> transformQuestion(PatternChain<T> chain){
|
||||
LinkNode<T> newTail = new LinkNode<>();
|
||||
LinkNode<T> newHead = new LinkNode<>();
|
||||
@@ -47,6 +85,11 @@ public class Pattern<T> {
|
||||
return chain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines a collection of chains into one OR chain.
|
||||
* @param collection the collection of chains to combine.
|
||||
* @return the resulting OR chain.
|
||||
*/
|
||||
private PatternChain<T> combineChains(Collection<PatternChain<T>> collection){
|
||||
LinkNode<T> head = new LinkNode<>();
|
||||
LinkNode<T> tail = new LinkNode<>();
|
||||
@@ -58,6 +101,10 @@ public class Pattern<T> {
|
||||
return newChain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a single value from the input into a chain.
|
||||
* @return the resulting chain, or null on error.
|
||||
*/
|
||||
private PatternChain<T> parseValue(){
|
||||
if(index >= source.length()) return null;
|
||||
if(source.charAt(index) == '\\'){
|
||||
@@ -66,6 +113,10 @@ public class Pattern<T> {
|
||||
return new PatternChain<>(new ValueNode<>(source.charAt(index++)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a [] range from the input into a chain.
|
||||
* @return the resulting chain, or null on error.
|
||||
*/
|
||||
private PatternChain<T> parseOr(){
|
||||
Stack<PatternChain<T>> orStack = new Stack<>();
|
||||
index++;
|
||||
@@ -88,6 +139,12 @@ public class Pattern<T> {
|
||||
return (orStack.size() == 1) ? orStack.pop() : combineChains(orStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a repeatable segment from the input into a chain
|
||||
* @param isSubsegment whether the segment is a sub-expression "()", and therefore
|
||||
* whether to expect a closing brace.
|
||||
* @return the resulting chain, or null on error.
|
||||
*/
|
||||
private PatternChain<T> parseSegment(boolean isSubsegment){
|
||||
if(index >= source.length() || ((source.charAt(index) != '(') && isSubsegment)) return null;
|
||||
if(isSubsegment) index++;
|
||||
@@ -152,6 +209,11 @@ public class Pattern<T> {
|
||||
return fullChain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates / compiles a new pattern with the given id from the given string.
|
||||
* @param from the string to compile a pattern from.
|
||||
* @param id the ID to use.
|
||||
*/
|
||||
public Pattern(String from, T id){
|
||||
this.id = id;
|
||||
index = 0;
|
||||
@@ -166,6 +228,10 @@ public class Pattern<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the head PatternNode, for use in matching
|
||||
* @return the pattern node.
|
||||
*/
|
||||
public PatternNode<T> getHead() {
|
||||
return head;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user