static L> ai_matchParseTrees_v2(PTElement a, PTElement b) { new L> out; ai_matchParseTrees_v2_collect(a, b, out); ret out; } svoid ai_matchParseTrees_v2_collect(PTElement a, PTElement b, L> out) { PTElement a2 = ai_parseTree_descendToComposite(a); PTElement b2 = ai_parseTree_descendToComposite(b); PTElement aa = or(a2, a), bb = or(b2, b); if (a2 != null && b2 != null) { // The actual match is between the productions. // We add the tree nodes too for reference. addPair(out, pairWithToStringFromA(a2/ChoosePart.reconstruction.production, a2), pairWithToStringFromA(b2/ChoosePart.reconstruction.production, b2)); ai_matchParseTrees_v2_collect(first(a2.children), first(b2.children), out); ai_matchParseTrees_v2_collect(second(a2.children), second(b2.children), out); } else addPair(out, aa, bb); }