diff --git a/plugins/org.eclipse.xtext.util/src/org/eclipse/xtext/util/formallang/NfaUtil.java b/plugins/org.eclipse.xtext.util/src/org/eclipse/xtext/util/formallang/NfaUtil.java index 910e44daf..5b556649c 100644 --- a/plugins/org.eclipse.xtext.util/src/org/eclipse/xtext/util/formallang/NfaUtil.java +++ b/plugins/org.eclipse.xtext.util/src/org/eclipse/xtext/util/formallang/NfaUtil.java @@ -18,6 +18,7 @@ import java.util.Set; import java.util.Stack; import com.google.common.base.Function; +import com.google.common.base.Functions; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; @@ -51,6 +52,26 @@ public class NfaUtil { this.result = result; this.followers = followers.iterator(); } + + @Override + public String toString() { + return result == null ? "null" : result.toString(); + } + } + + protected static class GetToken implements Function { + + protected Production production; + + public GetToken(Production production) { + super(); + this.production = production; + } + + public T apply(E from) { + return production.getToken(from); + } + } public static class MappedComparator> implements Comparator { @@ -71,6 +92,21 @@ public class NfaUtil { } } + public static class NFAFactory implements NfaFactory, S, S> { + + public Nfa create(S start, S stop) { + return new NFAImpl(start, stop, Maps.> newHashMap()); + } + + public S createState(Nfa nfa, S token) { + return token; + } + + public void setFollowers(Nfa nfa, S owner, Iterable followers) { + ((NFAImpl) nfa).followers.put(owner, Lists.newArrayList(followers)); + } + } + public static class NFAImpl implements Nfa { protected final Map> followers; @@ -209,25 +245,35 @@ public class NfaUtil { return result; } + public Nfa create(Production production, FollowerFunction ff, E start, E stop) { + return create(production, ff, Functions. identity(), new NFAFactory(), start, stop); + } + public > NFA create(Production production, FollowerFunction ff, NfaFactory factory) { + return create(production, ff, new GetToken(production), factory, null, null); + } + + public > NFA create(Production production, FollowerFunction ff, + Function tokenFunc, NfaFactory factory, T2 start, T2 stop) { Map states = Maps.newHashMap(); - NFA nfa = factory.create(null, null); + NFA nfa = factory.create(start, stop); states.put(null, nfa.getStop()); - create(production, nfa, nfa.getStart(), ff.getStarts(production.getRoot()), ff, factory, states); + create(production, nfa, nfa.getStart(), ff.getStarts(production.getRoot()), ff, tokenFunc, factory, states); return nfa; } - protected > void create(Production production, NFA nfa, S state, - Iterable followerElements, FollowerFunction followerFunc, NfaFactory factory, - Map ele2state) { + protected > void create(Production production, NFA nfa, S state, + Iterable followerElements, FollowerFunction followerFunc, Function tokenFunc, + NfaFactory factory, Map ele2state) { List sfollower = Lists.newArrayList(); for (E follower : followerElements) { S fs = ele2state.get(follower); if (fs == null) { - fs = factory.createState(nfa, production.getToken(follower)); + fs = factory.createState(nfa, tokenFunc.apply(follower)); ele2state.put(follower, fs); - create(production, nfa, fs, followerFunc.getFollowers(follower), followerFunc, factory, ele2state); + create(production, nfa, fs, followerFunc.getFollowers(follower), followerFunc, tokenFunc, factory, + ele2state); } sfollower.add(fs); } @@ -249,16 +295,6 @@ public class NfaUtil { }); } - public void removeOrphans(Nfa nfa) { - Map distances = distanceToFinalStateMap(nfa); - for (S s : collect(nfa)) { - Iterator i = nfa.getFollowers(s).iterator(); - while (i.hasNext()) - if (!distances.containsKey(i.next())) - i.remove(); - } - } - public Map distanceToStateMap(Nfa nfa, Predicate matches) { return distanceFromStateMap(inverse(nfa), matches); } @@ -323,6 +359,13 @@ public class NfaUtil { }; } + public Set filterFollowers(Nfa nfa, Iterable followers, Predicate filter) { + Set result = Sets.newHashSet(); + for (S follower : followers) + collectFollowers(nfa, follower, result, Sets. newHashSet(), filter); + return result; + } + // protected void collectFinalStates(INfaAdapter nfa, S owner, S last, Set result, // Set visited, Set ends, Predicate filter) { // if (!visited.add(owner)) @@ -335,13 +378,6 @@ public class NfaUtil { // collectFinalStates(nfa, follower, last, result, visited, ends, filter); // } - public Set filterFollowers(Nfa nfa, Iterable followers, Predicate filter) { - Set result = Sets.newHashSet(); - for (S follower : followers) - collectFollowers(nfa, follower, result, Sets. newHashSet(), filter); - return result; - } - public > S find(Nfa nfa, Iterable starts, Predicate matcher) { Set visited = Sets.newHashSet(); for (S s : starts) { @@ -352,6 +388,11 @@ public class NfaUtil { return null; } + public S find(Nfa nfa, Predicate matcher) { + Set visited = Sets.newHashSet(); + return find(nfa, nfa.getStart(), matcher, visited); + } + // public ITokenNfaAdapter filter(final ITokenNfaAdapter nfa, final Predicate filter) { // return new ITokenNfaAdapter() { // @@ -384,11 +425,6 @@ public class NfaUtil { // return result; // } - public S find(Nfa nfa, Predicate matcher) { - Set visited = Sets.newHashSet(); - return find(nfa, nfa.getStart(), matcher, visited); - } - protected > S find(Nfa nfa, S state, Predicate matcher, Set visited) { if (!visited.add(state)) @@ -430,6 +466,16 @@ public class NfaUtil { return new NFAImpl(nfa.getStop(), nfa.getStart(), inverseMap); } + public void removeOrphans(Nfa nfa) { + Map distances = distanceToFinalStateMap(nfa); + for (S s : collect(nfa)) { + Iterator i = nfa.getFollowers(s).iterator(); + while (i.hasNext()) + if (!distances.containsKey(i.next())) + i.remove(); + } + } + public > Nfa sort(Nfa nfa) { Map> followerMap = Maps.newHashMap(); for (S state : new NfaUtil().collect(nfa)) { diff --git a/plugins/org.eclipse.xtext.util/src/org/eclipse/xtext/util/formallang/StringProduction.java b/plugins/org.eclipse.xtext.util/src/org/eclipse/xtext/util/formallang/StringProduction.java index f489c2d39..3157f8840 100644 --- a/plugins/org.eclipse.xtext.util/src/org/eclipse/xtext/util/formallang/StringProduction.java +++ b/plugins/org.eclipse.xtext.util/src/org/eclipse/xtext/util/formallang/StringProduction.java @@ -40,13 +40,17 @@ public class StringProduction implements Production { protected String value; - protected ProdElement(ElementType type) { + public ProdElement(ElementType type) { super(); this.type = type; if (type != ElementType.TOKEN) this.children = Lists.newArrayList(); } + public void setValue(String value) { + this.value = value; + } + protected void addChild(ProdElement ele) { children.add(ele); ele.parent = this; @@ -56,6 +60,18 @@ public class StringProduction implements Production { return children; } + public void setMany(boolean many) { + this.many = many; + } + + public void setName(String name) { + this.name = name; + } + + public void setOptional(boolean optional) { + this.optional = optional; + } + public String getName() { return name; } @@ -67,6 +83,7 @@ public class StringProduction implements Production { public ElementType getType() { return type; } + public String getValue() { return value; } @@ -92,6 +109,7 @@ public class StringProduction implements Production { protected enum Token { AND("&"), // COLON(":"), // + EQ("="), // ID("[a-zA-Z][a-zA-Z0-9]*"), // PIPE("\\|"), // PL("\\("), //