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

org.unlaxer.parser.combinator.NonOrdered Maven / Gradle / Ivy

package org.unlaxer.parser.combinator;

import java.util.List;

import org.unlaxer.Name;
import org.unlaxer.Parsed;
import org.unlaxer.TokenKind;
import org.unlaxer.context.ParseContext;
import org.unlaxer.context.Transaction.AdditionalPreCommitAction;
import org.unlaxer.parser.HasChildrenParser;
import org.unlaxer.parser.Parser;
import org.unlaxer.parser.Parsers;

/**
 * aka interleave in RelaxNG
 */
public class NonOrdered extends ConstructedCombinatorParser {

	private static final long serialVersionUID = 5425945419472077891L;

	public NonOrdered(Name name, Parsers parsers) {
		super(name, parsers);
	}

	public NonOrdered(Parsers parsers) {
		super(parsers);
	}

	@SafeVarargs
	public NonOrdered(Name name, Parser... parsers) {
		super(name, parsers);
	}

	@SafeVarargs
	public NonOrdered(Parser... parsers) {
		super(parsers);
	}
	
	 @SafeVarargs
	 public NonOrdered(Class... parsers) {
	    super(parsers);
	  }


	public NonOrdered() {
		super(new Parser[] {});
	}

	public NonOrdered(Name name) {
		super(name);
	}

	@Override
	public Parsed parse(ParseContext parseContext, TokenKind tokenKind, boolean invertMatch) {

		parseContext.startParse(this, parseContext, tokenKind, invertMatch);

		parseContext.begin(this);

		List children = getChildren();
		
		Parsers determineds = new Parsers();

		int size = children.size();
		int remain = size;
		boolean[] comsumeds = new boolean[size];

		while (remain != 0) {

			int start = remain;

			for (int i = 0; i < size; i++) {
				if (comsumeds[i]) {
					continue;
				}
				Parsed parsed = children.get(i).parse(parseContext, tokenKind, invertMatch);
				if (parsed.isSucceeded()) {
					remain--;
					comsumeds[i] = true;
					determineds.add(children.get(i));
					break;
				}
			}
			if (start == remain) {
				parseContext.rollback(this);
				parseContext.endParse(this, Parsed.FAILED , parseContext, tokenKind, invertMatch);

				return Parsed.FAILED;
			}
		}

		Parsed committed = new Parsed(
				parseContext.commit(this, tokenKind , new NonOrderedCommitAction(determineds)));
		
		parseContext.endParse(this, committed, parseContext, tokenKind, invertMatch);
		return committed;
	}
	
	public static class NonOrderedCommitAction implements AdditionalPreCommitAction{

		Parsers determineds;

		public NonOrderedCommitAction(Parsers determineds) {
			super();
			this.determineds = determineds;
		}

		@Override
		public void effect(Parser parser, ParseContext parseContext) {

			if (false == determineds.isEmpty() && parser instanceof NonOrdered) {
				parseContext.orderedParsersByNonOrdered.put((NonOrdered)parser, determineds);
			}
		}
	}

	@Override
	public HasChildrenParser createWith(Parsers children) {
		return new NonOrdered(children);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy