1 package org.simantics.scl.compiler.parser.regexp;
3 import gnu.trove.set.hash.THashSet;
5 import java.util.Arrays;
6 import java.util.Iterator;
8 import org.simantics.scl.compiler.parser.regexp.automata.NFA;
10 public class ROr extends Regexp {
11 public final Regexp[] exps;
18 protected void buildAutomaton(NFA aut, int inState, int outState) {
19 for(Regexp exp : exps)
20 exp.buildAutomaton(aut, inState, outState);
24 protected void toString(StringBuilder b, int prec) {
28 for(Regexp exp : exps) {
40 public void toString(StringBuilder b, Namer grammar, int prec) {
44 for(Regexp exp : exps) {
49 exp.toString(b, grammar, 1);
56 protected int getTypeId() {
61 public boolean equals(Object obj) {
64 if(obj == null || obj.getClass() != getClass())
67 return Arrays.equals(exps, other.exps);
71 public int hashCode() {
73 for(Regexp exp : exps) {
81 public boolean isNullable() {
82 for(Regexp exp : exps)
88 private Regexp simplify(THashSet<Regexp> set) {
89 boolean qm = set.remove(ONE);
95 Iterator<Regexp> it = set.iterator();
96 Regexp common = front(it.next());
98 Regexp temp = front(it.next());
99 if(!temp.equals(common))
103 THashSet<Regexp> set2 = new THashSet<Regexp>();
105 set2.add(removeFront(e));
107 exp = seq(common, simplify(set2));
112 Iterator<Regexp> it = set.iterator();
113 Regexp common = back(it.next());
114 while(it.hasNext()) {
115 Regexp temp = back(it.next());
116 if(!temp.equals(common))
120 THashSet<Regexp> set2 = new THashSet<Regexp>();
122 set2.add(removeBack(e));
124 exp = seq(simplify(set2), common);
132 if(qm && !exp.isNullable())
133 exp = new ROp(exp, '?');
138 public Regexp simplify() {
141 THashSet<Regexp> set = new THashSet<Regexp>();
142 for(Regexp exp : exps) {
143 exp = exp.simplify();
146 return simplify(set);
149 private static Regexp front(Regexp exp) {
150 if(exp instanceof RSeq) {
151 Regexp[] exps = ((RSeq)exp).exps;
160 private static Regexp removeFront(Regexp exp) {
161 if(exp instanceof RSeq) {
162 Regexp[] exps = ((RSeq)exp).exps;
163 return seq_(Arrays.asList(exps).subList(1, exps.length));
169 private static Regexp back(Regexp exp) {
170 if(exp instanceof RSeq) {
171 Regexp[] exps = ((RSeq)exp).exps;
174 return exps[exps.length-1];
180 private static Regexp removeBack(Regexp exp) {
181 if(exp instanceof RSeq) {
182 Regexp[] exps = ((RSeq)exp).exps;
183 return seq_(Arrays.asList(exps).subList(0, exps.length-1));