/** Parse sig/set. */
private Sig parseSig(String id, int depth) throws IOException, Err {
Sig ans = id2sig.get(id);
if (ans!=null) return ans;
XMLNode node = nmap.get(id);
if (node==null) throw new IOException("Unknown SigID "+id+" encountered.");
if (!node.is("sig")) throw new IOException("ID "+id+" is not a sig.");
String label = label(node);
Attr isAbstract = yes(node,"abstract") ? Attr.ABSTRACT : null;
Attr isOne = yes(node,"one") ? Attr.ONE : null;
Attr isLone = yes(node,"lone") ? Attr.LONE : null;
Attr isSome = yes(node,"some") ? Attr.SOME : null;
Attr isPrivate = yes(node,"private") ? Attr.PRIVATE : null;
Attr isMeta = yes(node,"meta") ? Attr.META : null;
Attr isEnum = yes(node,"enum") ? Attr.ENUM : null;
Attr isExact = yes(node,"exact") ? Attr.EXACT : null;
if (yes(node,"builtin")) {
if (label.equals(UNIV.label)) { id2sig.put(id, UNIV); return UNIV; }
if (label.equals(SIGINT.label)) { id2sig.put(id, SIGINT); return SIGINT; }
if (label.equals(SEQIDX.label)) { id2sig.put(id, SEQIDX); return SEQIDX; }
if (label.equals(STRING.label)) { id2sig.put(id, STRING); return STRING; }
throw new IOException("Unknown builtin sig: "+label+" (id="+id+")");
}
if (depth > nmap.size()) throw new IOException("Sig "+label+" (id="+id+") is in a cyclic inheritance relationship.");
List<Sig> parents = null;
TupleSet ts = factory.noneOf(1);
for(XMLNode sub:node) {
if (sub.is("atom")) { ts.add(factory.tuple(sub.getAttribute("label"))); continue; }
if (!sub.is("type")) continue;
Sig parent = parseSig(sub.getAttribute("ID"), depth+1);
if (parents==null) parents = new ArrayList<Sig>();
parents.add(parent);
}
if (parents==null) {
String parentID = node.getAttribute("parentID");
Sig parent = parseSig(parentID, depth+1);
if (!(parent instanceof PrimSig)) throw new IOException("Parent of sig "+label+" (id="+id+") must not be a subset sig.");
for(Expr choice: choices)
if (choice instanceof PrimSig && parent==((PrimSig)choice).parent && ((Sig)choice).label.equals(label))
{ ans=(Sig)choice; choices.remove(choice); break; }