private static DieRoll parseDiceInner(StringStream ss) {
   /*
    * if(checkAndEat("FA(")) { DieRoll d=parseFA(ss); if(d==null) return
    * null; return parseDTail(d,ss); }
    */
   Integer num = ss.getInt();
   int dsides;
   int ndice;
   if (num == null) {
     ndice = 1;
   } else {
     ndice = num;
   }
   if (ss.checkAndEat("d")) {
     num = ss.getInt();
     if (num == null) return null;
     dsides = num;
   } else {
     return null;
   }
   num = ss.readSgnInt();
   int bonus;
   if (num == null) bonus = 0;
   else bonus = num;
   return new DieRoll(ndice, dsides, bonus);
 }
 private static DieRoll parseDTail(DieRoll r1, StringStream ss) {
   if (r1 == null) return null;
   if (ss.checkAndEat("&")) {
     DieRoll d2 = parseDice(ss);
     return parseDTail(new DiceSum(r1, d2), ss);
   } else {
     return r1;
   }
 }
 private static Vector<DieRoll> parseRollInner(StringStream ss, Vector<DieRoll> v) {
   Vector<DieRoll> r = parseXDice(ss);
   if (r == null) {
     return null;
   }
   v.addAll(r);
   if (ss.checkAndEat(";")) {
     return parseRollInner(ss, v);
   }
   return v;
 }
 private static Vector<DieRoll> parseXDice(StringStream ss) {
   StringStream saved = ss.save();
   Integer x = ss.getInt();
   int num;
   if (x == null) {
     num = 1;
   } else {
     if (ss.checkAndEat("x")) {
       num = x;
     } else {
       num = 1;
       ss.restore(saved);
     }
   }
   DieRoll dr = parseDice(ss);
   if (dr == null) {
     return null;
   }
   Vector<DieRoll> ans = new Vector<DieRoll>();
   for (int i = 0; i < num; i++) {
     ans.add(dr);
   }
   return ans;
 }