!7

sclass BottomUpParser > DynSCPWithInput {
  start {
    dm_useLocallyCopiedMechLists(); set flag NoFancyMechParsing.
  }
  
  void update(S s) {
    temp enter();
    if (!isShowing()) { inputChooser.forgetInput(); ret; }
    
    final new AI_BottomUpParser1 parser;
    parser.parse(s);
    AI_BottomUpParser1.Word w = parser.fullGroup();
    print("Full group: " + w);
    if (w == null) ret;
    final L<WeightedProduction> productions = ai_buParser_parseWeightedProductions();
    print("Have " + n2(productions, "production"));
    
    class ChooseCategory {
      AI_BottomUpParser1.Word word;
      L<S> categories;
      
      *(AI_BottomUpParser1.Word *word, L<S> *categories) {}

      toString { ret word.text() + " (" + n2(categories, "category", "categories") + ")"; }
    }
    
    class HaveCategory {
      AI_BottomUpParser1.Word word;
      S category;
      
      *(AI_BottomUpParser1.Word *word, S *category) {}
      
      toString { ret quote(word.text()) + " as " + category; }
    }
    
    class ChoosePart {
      ai_Reconstructed reconstruction;
      
      *(ai_Reconstructed *reconstruction) {}
      
      toString { ret reconstruction.a.text() + " + " + reconstruction.b.text(); }
    }
    
    ChooseCategory root = new(w, asList(w.classes));
    
    setComponent(jDynamicTree(root, func(fO e) -> L<O> {
      if (e instanceof ChooseCategory)
        ret map(((ChooseCategory) e).word.classes, func(S cat) { new HaveCategory(((ChooseCategory) e).word, cat) });
      if (e instanceof HaveCategory) {
        HaveCategory h = cast e;
        L<ai_Reconstructed> l = ai_buParser1_reconstructedProductions(parser, productions, h.word, h.category);
        ret map(l, func(ai_Reconstructed r) -> O {
          r.production.b == null
            ? new HaveCategory(r.a, r.production.a)
            : new ChoosePart(r)
        });
      }
      if (e instanceof ChoosePart) {
        ai_Reconstructed r = ((ChoosePart) e).reconstruction;
        ret (L) ll(new HaveCategory(r.a, r.production.a),
          new HaveCategory(r.b, r.production.b));
      }
      null;
    }));
    print("Made tree");
  }
}