view src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverser/DefaultTraverser.java @ 10:a2c019a77c27

commit
author Shoshi TAMAKI
date Mon, 10 Dec 2012 18:50:53 +0900
parents
children 5f763f32940e
line wrap: on
line source

package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser;

import java.util.Iterator;

import fj.P;
import fj.P2;
import fj.data.List;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Node;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Tree;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.IterableWrapper;

public class DefaultTraverser implements Traverser
{
	@Override
	public Iterable<TraverseResult> traverse(Tree _tree, TraverseEvaluator _evaluator)
	{
		Node root = _tree.getRoot();
		
		List<Node> current = List.nil();
		TraverseEvaluator evaluator = _evaluator;
		
		List<TraverseResultImpl> totalResult = _traverse(current,root,evaluator);
		
		return new IterableWrapper<TraverseResult>(totalResult);
	}
	
	private List<TraverseResultImpl> _traverse(List<Node> _path,Node _current,TraverseEvaluator _evaluator)
	{
		List<Node> currentPath = _path.snoc(_current);
		
		int pos = 0;
		List<P2<Node,Evaluation>> accepted = List.nil();
		
		for(Node child : _current.getChildren()){
			Evaluation e = _evaluator.eval(currentPath,child,pos);
			long result = e.result();
			
			if(result == TraverseEvaluator.ACCEPT_AND_CONTINUE ||
					result == TraverseEvaluator.ACCEPT_AND_BREAK){
				accepted = accepted.snoc(P.p(child,e));
			}
			
			if(result == TraverseEvaluator.DENY_AND_BREAK || 
					result == TraverseEvaluator.ACCEPT_AND_BREAK){
				break;
			}
		}
		
		List<TraverseResultImpl> totalResult = List.nil();
		for(P2<Node,Evaluation> next : accepted){
			Node node = next._1();
			TraverseEvaluator evaluator = next._2().evaluator();
			List<TraverseResultImpl> result = _traverse(currentPath,node,evaluator);
			totalResult = totalResult.append(result);
		}
		
		return totalResult;
	}
	
	public static class TraverseResultImpl implements TraverseResult
	{
		private final List<Node> result;
		
		public TraverseResultImpl(List<Node> _result)
		{
			result = _result;
		}

		@Override
		public Iterator<Node> iterator()
		{
			return result.iterator();
		}
	}
}