TokenPattern buildPattern(PrintStream s) {
		if (pattern != null) {
			return pattern; // Already built
		}

		pattern = new TokenPattern(location);
		VectorSTL<TokenPattern> oppattern = new VectorSTL<>();
		boolean recursion = false;
		// Generate pattern for each operand, store in oppattern
		for (int i = 0; i < operands.size(); ++i) {
			OperandSymbol sym = operands.get(i);
			TripleSymbol triple = sym.getDefiningSymbol();
			PatternExpression defexp = sym.getDefiningExpression();
			if (triple != null) {
				if (triple instanceof SubtableSymbol) {
					SubtableSymbol subsym = (SubtableSymbol) triple;
					if (subsym.isBeingBuilt()) { // Detected recursion
						if (recursion) {
							throw new SleighError("Illegal recursion", location);
						}
						// We should also check that recursion is rightmost
						// extreme
						recursion = true;
						oppattern.push_back(new TokenPattern(location));
					}
					else {
						oppattern.push_back(subsym.buildPattern(s));
					}
				}
				else {
					oppattern.push_back(triple.getPatternExpression().genMinPattern(oppattern));
				}
			}
			else if (defexp != null) {
				TokenPattern tmppat = defexp.genMinPattern(oppattern);
				if (null == tmppat) {
					throw new SleighError("operand " + sym.getName() + " has an issue", location);
				}
				oppattern.push_back(tmppat);
			}
			else {
				throw new SleighError("operand " + sym.getName() + " is undefined", location);
			}
			TokenPattern sympat = oppattern.back();
			sym.minimumlength = sympat.getMinimumLength();
			if (sympat.getLeftEllipsis() || sympat.getRightEllipsis()) {
				sym.setVariableLength();
			}
		}

		if (pateq == null) {
			throw new SleighError("Missing equation", location);
		}
		// Build the entire pattern
		pateq.genPattern(oppattern);
		pattern = new TokenPattern(location, pateq.getTokenPattern());
		if (pattern.alwaysFalse()) {
			throw new SleighError("Impossible pattern--always false", location);
		}
		if (recursion) {
			pattern.setRightEllipsis(true);
		}
		minimumlength = pattern.getMinimumLength(); // Get length of the pattern
		// in bytes

		OperandResolve resolve = new OperandResolve(operands);
		if (!pateq.resolveOperandLeft(resolve)) {
			throw new SleighError("Unable to resolve operand offsets", location);
		}

		// Unravel relative offsets to absolute (if possible)
		for (int i = 0; i < operands.size(); ++i) {
			int base, offset;
			OperandSymbol sym = operands.get(i);
			if (sym.isOffsetIrrelevant()) {
				sym.offsetbase = -1;
				sym.reloffset = 0;
				continue;
			}
			base = sym.offsetbase;
			offset = sym.reloffset;
			while (base >= 0) {
				sym = operands.get(base);
				if (sym.isVariableLength()) {
					// Cannot resolve to absolute
					break;
				}
				base = sym.offsetbase;
				offset += sym.getMinimumLength();
				offset += sym.reloffset;
				if (base < 0) {
					operands.get(i).offsetbase = base;
					operands.get(i).reloffset = offset;
				}
			}
		}

		// Make sure context expressions are valid
		for (int i = 0; i < context.size(); ++i) {
			context.get(i).validate();
		}

		orderOperands(); // Order the operands based on offset dependency
		return pattern;
	}
Return the source file index
@return index
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slghsymbol/Constructor.java