view src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverser/DefaultTraverser.java @ 23:3ef2a66a8c5d

commit
author Shoshi TAMAKI
date Thu, 10 Jan 2013 23:22:42 +0900
parents 596a714e6a89
children 075d6418e359
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.IterableConverter;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.IterableConverter.Converter;

public class DefaultTraverser implements Traverser
{
	@Override
	public Iterable<Traversal> traverse(Tree _tree, TraverseEvaluator _evaluator)
	{
		Node root = _tree.getRoot();
		
		List<Node> current = List.nil();
		TraverseEvaluator evaluator = _evaluator;
		
		List<List<Node>> totalResult = _traverse(current,root,evaluator);
		
		Converter<Traversal,List<Node>> converter = new IterableConverter.Converter<Traversal,List<Node>>(){
			@Override
			public Traversal conv(final List<Node> _b)
			{
				Traversal t = new Traversal(){
					@Override
					public Iterator<Node> iterator(){
						return _b.iterator();
					}

					@Override
					public Node destination() {
						return _b.last();
					}
					
				};
				
				return t;
			}
		};
		
		return new IterableConverter<Traversal,List<Node>>(totalResult,converter);
	}
	
	private List<List<Node>> _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);
			Evaluation.Result result = e.result();
			
			if(result == Evaluation.Result.ACCEPT_CONTINUE ||
					result == Evaluation.Result.ACCEPT_BREAK){
				accepted = accepted.snoc(P.p(child,e));
			}
			
			if(result == Evaluation.Result.DENY_BREAK || 
					result == Evaluation.Result.ACCEPT_BREAK){
				break;
			}
		}
		
		List<List<Node>> totalResult = List.nil();
		for(P2<Node,Evaluation> next : accepted){
			Node node = next._1();
			TraverseEvaluator evaluator = next._2().evaluator();
			List<List<Node>> result = _traverse(currentPath,node,evaluator);
			
			
			for(List<Node> list : result){
				totalResult = totalResult.snoc(list.cons(_current));
			}
		}
		
		return totalResult;
	}
}