org.snapscript.parse.MatchAllGrammar Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of snap Show documentation
Show all versions of snap Show documentation
Dynamic scripting for the JVM
package org.snapscript.parse;
import java.util.ArrayList;
import java.util.List;
import org.snapscript.common.BitSet;
public class MatchAllGrammar implements Grammar {
private final List grammars;
private final String name;
private final int index;
public MatchAllGrammar(List grammars, String name, int index) {
this.grammars = grammars;
this.index = index;
this.name = name;
}
@Override
public GrammarMatcher create(GrammarCache cache, int length) {
List matchers = new ArrayList();
for(Grammar grammar : grammars) {
GrammarMatcher matcher = grammar.create(cache, length);
matchers.add(matcher);
}
return new MatchAllMatcher(matchers, name, index, length);
}
public static class MatchAllMatcher implements GrammarMatcher {
private final List matchers;
private final BitSet success;
private final BitSet failure;
private final String name;
private final int index;
public MatchAllMatcher(List matchers, String name, int index, int length) {
this.success = new BitSet(length);
this.failure = new BitSet(length);
this.matchers = matchers;
this.index = index;
this.name = name;
}
@Override
public boolean check(SyntaxChecker checker, int depth) {
int position = checker.position();
if(depth == 0) {
for(GrammarMatcher matcher : matchers) {
if(!matcher.check(checker, depth + 1)) {
return false;
}
}
return true;
}
if(!failure.get(position)) {
if(!success.get(position)) {
int mark = checker.mark(index);
int require = matchers.size();
int count = 0;
if(mark != -1) {
for(GrammarMatcher grammar : matchers) {
if(!grammar.check(checker, 0)) {
checker.reset(mark, index);
failure.set(position);
return false;
}
count++;
}
checker.reset(mark, index);
}
if(count == require) {
success.set(position);
}
}
if(success.get(position)) {
for(GrammarMatcher grammar : matchers) {
if(!grammar.check(checker, 0)) {
throw new ParseException("Could not read node in " + name);
}
}
return true;
}
}
return false;
}
@Override
public boolean build(SyntaxBuilder builder, int depth) {
int position = builder.position();
if(depth == 0) {
for(GrammarMatcher matcher : matchers) {
if(!matcher.build(builder, depth + 1)) {
return false;
}
}
return true;
}
if(!failure.get(position)) {
if(!success.get(position)) {
SyntaxBuilder child = builder.mark(index);
int require = matchers.size();
int count = 0;
if(child != null) {
for(GrammarMatcher grammar : matchers) {
if(!grammar.build(child, 0)) {
failure.set(position);
break;
}
count++;
}
child.reset();
}
if(count == require) {
success.set(position);
}
}
if(success.get(position)) {
for(GrammarMatcher grammar : matchers) {
if(!grammar.build(builder, 0)) {
throw new ParseException("Could not read node in " + name);
}
}
return true;
}
}
return false;
}
@Override
public String toString() {
return String.valueOf(matchers);
}
}
}