public static void matchDereference(Tree tree, Consumer<Tree> onSpace, Consumer<Tree> onSize,
			Consumer<Tree> onOffset) {
		switch (tree.getChildCount()) {
			case 3:
				match(tree, SleighParser.OP_DEREFERENCE, onSpace, onSize, onOffset);
				return;
			case 2:
				Tree child0 = tree.getChild(0);
				switch (child0.getType()) {
					case SleighParser.OP_IDENTIFIER:
						match(tree, SleighParser.OP_DEREFERENCE, onSpace, onOffset);
						return;
					case SleighParser.OP_BIN_CONSTANT:
					case SleighParser.OP_DEC_CONSTANT:
					case SleighParser.OP_HEX_CONSTANT:
						match(tree, SleighParser.OP_DEREFERENCE, onSize, onOffset);
						return;
					default:
						matchTree(tree, SleighParser.OP_DEREFERENCE, children -> {
							throw new AssertionError(
								"OP_DEREFERENCE with 2 children where child[0] is " +
									SleighParser.tokenNames[child0.getType()]);
						});
						return;
				}
			case 1:
				match(tree, SleighParser.OP_DEREFERENCE, onOffset);
				return;
			default:
				// Likely, the op is mismatched. Ensure the error message says so.
				match(tree, SleighParser.OP_DEREFERENCE);
				throw new AssertionError(
					"OP_DEREFERENCE with " + tree.getChildCount() + " children");
		}
	}
Match the given tree to a given pattern with per-child actions

@param tree the (sub-)tree to match, actually its root node
@param type the expected type of the given node
@param onChild a list of actions (usually sub-matching) to perform on each corresponding
           child. The matcher will verify the number of children matches the number of
           actions.
Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/exec/SleighUtils.java