All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.amygdalum.util.text.doublearraytrie.DoubleArrayCharFallbackTrieCompiler Maven / Gradle / Ivy

The newest version!
package net.amygdalum.util.text.doublearraytrie;

import static net.amygdalum.util.text.doublearraytrie.Arrays.expand;

import java.util.IdentityHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;

import net.amygdalum.util.text.CharFallbackAdaptor;
import net.amygdalum.util.text.CharNode;
import net.amygdalum.util.text.CharTrie;
import net.amygdalum.util.text.CharWordGraphCompiler;
import net.amygdalum.util.text.NodeResolver;
import net.amygdalum.util.text.linkeddawg.CharGenericFallbackNode;

public class DoubleArrayCharFallbackTrieCompiler implements CharWordGraphCompiler> {

	@Override
	public CharNode create() {
		return new CharGenericFallbackNode<>();
	}

	@Override
	public CharTrie build(CharNode node) {
		DoubleArrayCharFallbackTrie.Builder builder = new DoubleArrayCharFallbackTrie.Builder();
		boolean[] visited = new boolean[1024];
		Map, Integer> assignments = new IdentityHashMap<>();
		Queue> todo = new LinkedList<>();
		todo.add(new Assignment<>(builder.root(), node));
		while (!todo.isEmpty()) {
			Assignment current = todo.remove();
			int currentState = current.state;
			CharNode currentNode = current.node;
			if (currentState >= visited.length) {
				visited = expand(visited, currentState);
			}
			if (visited[currentState]) {
				continue;
			}
			visited[currentState] = true;
			assignments.put(currentNode, currentState);
			
			int alternatives = currentNode.getAlternativesSize();
			if (alternatives >= 1) {
				branch(builder, currentState, currentNode, todo);
			} else {
				terminate(builder, currentState, currentNode);
			}
		}
		for (Map.Entry, Integer> current : assignments.entrySet()) {
			CharNode currentNode = current.getKey();
			int currentState = current.getValue();
			
			CharNode fallbackNode = CharFallbackAdaptor.getFallback(currentNode);
			if (fallbackNode != null) {
				int fallbackState = assignments.getOrDefault(fallbackNode, 0);
				builder.fallback(currentState, fallbackState);
			}
		}

		return builder.build();
	}

	private void branch(DoubleArrayCharFallbackTrie.Builder builder, int currentState, CharNode currentNode, Queue> todo) {
		char[] alternatives = currentNode.getAlternatives();
		int[] nextStates = builder.insert(currentState, alternatives);
		for (int i = 0; i < nextStates.length; i++) {
			todo.add(new Assignment<>(nextStates[i], currentNode.nextNode(alternatives[i])));
		}
		T currentAttached = currentNode.getAttached();
		if (currentAttached != null) {
			builder.attach(currentState, currentAttached);
		}
	}
	
	private void terminate(DoubleArrayCharFallbackTrie.Builder builder, int currentState, CharNode currentNode) {
		builder.terminate(currentState);
		T currentAttached = currentNode.getAttached();
		if (currentAttached != null) {
			builder.attach(currentState, currentAttached);
		}
	}

	@Override
	public NodeResolver> resolver() {
		return new Resolver();
	}
	
	private static class Assignment {

		public int state;
		public CharNode node;
		
		public Assignment(int state, CharNode node) {
			this.state = state;
			this.node = node;
		}
		
		
	}

	private class Resolver implements NodeResolver> {

		@Override
		public void compile(CharNode node) {
		}

		@Override
		public void link(CharNode node) {
		}

		@Override
		public CharNode resolve(CharNode node) {
			return node;
		}

	}

}