/* Generated By:JavaCC: Do not edit this line. FridgeParser.java */
package javakurs.musterloesung.uebung07;

/**
 * {@link FridgeParser} is the natural language interface to the FCM (fridge
 * content management) system in class {@link Fridge}.
 * 
 * @author Ulrich Schaefer, DFKI
 * @version $Id: FridgeParser.jj,v 1.1 2010/12/13 13:15:55 steffen Exp $
 */
public class FridgeParser implements FridgeParserConstants {

  /**
   * Contains the FCM object.
   */
  private static FridgeEx2 fridge = null;

  /**
   * Contains flag to indicate end of program.
   */
  private static boolean quit = false;


  /**
   * Start method for running the natural language I/O to and from the
   * fridge via stdin/stdout. The for loop is executed forever; exit through
   * the 'Ende' command calling fridge.finish() -> System.exit()
   *
   * @param args not used
   */
  public static void main(String[] args) {

    FridgeParser parser = new FridgeParser(System.in);
    fridge = new FridgeEx2();
    while (true) {
      // loop forever - until break is executed  
      try {
        // start symbol/rule
        Input();
        if (quit) {
          break;
        }
      } catch (ParseException pe) {
        String tstring = pe.currentToken.image;
        // in the ParserException context, Token is always set,
        // but its image may be null
        if (tstring == null) {
          tstring = "";
        }
        else {
          tstring = tstring + " ";
        }
        String parserMessage =
        "Ich habe Deine Eingabe nur bis zu '" + tstring + "' verstanden.";
        fridge.message(parserMessage);
        // needed by JavaCC-generated static code:
        ReInit(System.in);
      }
    }
    // shutdown fridge
    fridge.finish();
  }

  static final public void Input() throws ParseException {
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case BERECHNE:
    case BESTAND:
    case EINKAUFSLISTE:
    case IST:
    case WIE:
    case WIEVIEL:
    case BESTANDSLISTE:
    case HABEN:
    case HIER:
    case ICH:
    case SIND:
    case WAS:
    case ZEIGE:
    case WOVON:
      label_1:
      while (true) {
        Command_or_Question();
        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
        case DOT:
        case QM:
          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
          case DOT:
            jj_consume_token(DOT);
            break;
          case QM:
            jj_consume_token(QM);
            break;
          default:
            jj_la1[0] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
          }
          break;
        default:
          jj_la1[1] = jj_gen;
          ;
        }
        jj_consume_token(LF);
        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
        case BERECHNE:
        case BESTAND:
        case EINKAUFSLISTE:
        case IST:
        case WIE:
        case WIEVIEL:
        case BESTANDSLISTE:
        case HABEN:
        case HIER:
        case ICH:
        case SIND:
        case WAS:
        case ZEIGE:
        case WOVON:
          ;
          break;
        default:
          jj_la1[2] = jj_gen;
          break label_1;
        }
      }
      break;
    case 0:
    case AUF:
    case ENDE:
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case ENDE:
        jj_consume_token(ENDE);
        break;
      case AUF:
        jj_consume_token(AUF);
        jj_consume_token(WIEDERSEHEN);
        break;
      case 0:
        jj_consume_token(0);
        break;
      default:
        jj_la1[3] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      quit = true;
      break;
    default:
      jj_la1[4] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    // post action 
    if (quit) {
      {if (true) return;}
    }
  }

  static final public void Command_or_Question() throws ParseException {
  // variable initialization
  Token prod = null;
  Token numb = null;
  int sign = 1;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case BERECHNE:
      jj_consume_token(BERECHNE);
      Expr();

      break;
    case IST:
    case HABEN:
    case SIND:
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case HABEN:
        jj_consume_token(HABEN);
        jj_consume_token(WIR);
        break;
      case IST:
      case SIND:
        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
        case IST:
          jj_consume_token(IST);
          break;
        case SIND:
          jj_consume_token(SIND);
          break;
        default:
          jj_la1[5] = jj_gen;
          jj_consume_token(-1);
          throw new ParseException();
        }
        break;
      default:
        jj_la1[6] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case NOCH:
        jj_consume_token(NOCH);
        break;
      default:
        jj_la1[7] = jj_gen;
        ;
      }
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case NUM:
        numb = jj_consume_token(NUM);
        break;
      default:
        jj_la1[8] = jj_gen;
        ;
      }
      prod = jj_consume_token(PRODUKT_OR_CITY);
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case DA:
        jj_consume_token(DA);
        break;
      default:
        jj_la1[9] = jj_gen;
        ;
      }
      fridge.checkStock(numb, prod);
      break;
    case HIER:
      jj_consume_token(HIER);
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case IST:
        jj_consume_token(IST);
        break;
      case SIND:
        jj_consume_token(SIND);
        break;
      default:
        jj_la1[10] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case NUM:
        numb = jj_consume_token(NUM);
        break;
      default:
        jj_la1[11] = jj_gen;
        ;
      }
      prod = jj_consume_token(PRODUKT_OR_CITY);
      fridge.modifyStock(numb, prod, sign);
      break;
    case ICH:
      jj_consume_token(ICH);
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case GEBE:
        jj_consume_token(GEBE);
        jj_consume_token(DIR);
        break;
      case ENTNEHME:
        jj_consume_token(ENTNEHME);
          sign = - 1;
        break;
      default:
        jj_la1[12] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case NUM:
        numb = jj_consume_token(NUM);
        break;
      default:
        jj_la1[13] = jj_gen;
        ;
      }
      prod = jj_consume_token(PRODUKT_OR_CITY);
      fridge.modifyStock(numb, prod, sign);
      break;
    case BESTAND:
    case BESTANDSLISTE:
    case ZEIGE:
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case ZEIGE:
        jj_consume_token(ZEIGE);
        break;
      default:
        jj_la1[14] = jj_gen;
        ;
      }
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case BESTAND:
        jj_consume_token(BESTAND);
        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
        case PRODUKT_OR_CITY:
          prod = jj_consume_token(PRODUKT_OR_CITY);
          break;
        default:
          jj_la1[15] = jj_gen;
          ;
        }
        break;
      case BESTANDSLISTE:
        jj_consume_token(BESTANDSLISTE);
        break;
      default:
        jj_la1[16] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      fridge.listStock(prod);
      break;
    case EINKAUFSLISTE:
      jj_consume_token(EINKAUFSLISTE);
      fridge.buyList();
      break;
    case WIEVIEL:
      jj_consume_token(WIEVIEL);
      Wieviel_Regel();
      break;
    case WAS:
      jj_consume_token(WAS);
      Was_Regel();
      break;
    case WIE:
      jj_consume_token(WIE);
      Wie_Regel();
      break;
    case WOVON:
      jj_consume_token(WOVON);
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case IST:
        jj_consume_token(IST);
        break;
      case SIND:
        jj_consume_token(SIND);
        break;
      default:
        jj_la1[17] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case NOCH:
        jj_consume_token(NOCH);
        break;
      default:
        jj_la1[18] = jj_gen;
        ;
      }
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case MEHR:
      case WENIGER:
        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
        case WENIGER:
          jj_consume_token(WENIGER);
            sign = - 1;
          break;
        case MEHR:
          jj_consume_token(MEHR);
            sign = 0;
          break;
        default:
          jj_la1[19] = jj_gen;
          jj_consume_token(-1);
          throw new ParseException();
        }
        jj_consume_token(ALS);
        break;
      default:
        jj_la1[20] = jj_gen;
        ;
      }
      numb = jj_consume_token(NUM);
      jj_consume_token(DA);
    fridge.filterStock(sign, numb.image);
      break;
    default:
      jj_la1[21] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  static final public void Was_Regel() throws ParseException {
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case MUSS:
    case SOLL:
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case MUSS:
        jj_consume_token(MUSS);
        break;
      case SOLL:
        jj_consume_token(SOLL);
        break;
      default:
        jj_la1[22] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      jj_consume_token(ICH);
      jj_consume_token(EINKAUFEN);
      fridge.buyList();
      break;
    case IST:
      jj_consume_token(IST);
      Expr();
      break;
    default:
      jj_la1[23] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  static final public void Wieviel_Regel() throws ParseException {
  // variable initialization
  Token prod;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case UHR:
      jj_consume_token(UHR);
      jj_consume_token(IST);
      jj_consume_token(ES);
      fridge.printTime();
      break;
    case PRODUKT_OR_CITY:
      prod = jj_consume_token(PRODUKT_OR_CITY);
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case IST:
        jj_consume_token(IST);
        break;
      case SIND:
        jj_consume_token(SIND);
        break;
      default:
        jj_la1[24] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case NOCH:
        jj_consume_token(NOCH);
        break;
      default:
        jj_la1[25] = jj_gen;
        ;
      }
      jj_consume_token(DA);
      fridge.askStock(prod.image);
      break;
    case IST:
      jj_consume_token(IST);
      Expr();
      break;
    default:
      jj_la1[26] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

// Uebung 5 Start
  static final public void Wie_Regel() throws ParseException {
  // variable initialization
  Token city = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case SPAET:
      jj_consume_token(SPAET);
      jj_consume_token(IST);
      jj_consume_token(ES);
      fridge.printTime();
      break;
    case IST:
    case WIRD:
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case IST:
        jj_consume_token(IST);
        break;
      case WIRD:
        jj_consume_token(WIRD);
        break;
      default:
        jj_la1[27] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
      jj_consume_token(DAS);
      jj_consume_token(WETTER);
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case HEUTE:
        jj_consume_token(HEUTE);
        break;
      default:
        jj_la1[28] = jj_gen;
        ;
      }
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case IN:
        jj_consume_token(IN);
        city = jj_consume_token(PRODUKT_OR_CITY);
        break;
      default:
        jj_la1[29] = jj_gen;
        ;
      }
      fridge.printWeather(city);
      break;
    default:
      jj_la1[30] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

// Uebung 5 End
  static final public void Expr() throws ParseException {
  // varible initialization
  Token tnumber;
  double result;
  double dnum;
  StringBuilder verbatim = new StringBuilder();
    // RHS
      tnumber = jj_consume_token(NUM);
    result = fridge.parseNumber(tnumber.image);
    verbatim.append(fridge.formatNumber(result));
    label_2:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case MINUS:
      case PLUS:
        ;
        break;
      default:
        jj_la1[31] = jj_gen;
        break label_2;
      }
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case PLUS:
        jj_consume_token(PLUS);
        tnumber = jj_consume_token(NUM);
      dnum = fridge.parseNumber(tnumber.image);
      result += dnum;
      verbatim.append(" plus " + fridge.formatNumber(dnum));
        break;
      case MINUS:
        jj_consume_token(MINUS);
        tnumber = jj_consume_token(NUM);
      dnum = fridge.parseNumber(tnumber.image);
      result -= dnum;
      verbatim.append(" minus " + fridge.formatNumber(dnum));
        break;
      default:
        jj_la1[32] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
    }
    // post action
    fridge.message(verbatim.toString() + " ist " + fridge.formatNumber(result));
  }

  static private boolean jj_initialized_once = false;
  /** Generated Token Manager. */
  static public FridgeParserTokenManager token_source;
  static SimpleCharStream jj_input_stream;
  /** Current token. */
  static public Token token;
  /** Next token. */
  static public Token jj_nt;
  static private int jj_ntk;
  static private int jj_gen;
  static final private int[] jj_la1 = new int[33];
  static private int[] jj_la1_0;
  static private int[] jj_la1_1;
  static {
      jj_la1_init_0();
      jj_la1_init_1();
   }
   private static void jj_la1_init_0() {
      jj_la1_0 = new int[] {0x8080,0x8080,0x9c1a0960,0x211,0x9c1a0b71,0x80000800,0x84000800,0x40000000,0x0,0x200000,0x80000800,0x0,0x3000000,0x0,0x0,0x0,0x100040,0x80000800,0x40000000,0x0,0x0,0x9c1a0960,0x20000000,0x20000800,0x80000800,0x40000000,0x800,0x800,0x0,0x0,0x10800,0x6000,0x6000,};
   }
   private static void jj_la1_init_1() {
      jj_la1_1 = new int[] {0x0,0x0,0x2014,0x0,0x2014,0x0,0x0,0x0,0x8000,0x0,0x0,0x8000,0x0,0x8000,0x10,0x4000,0x0,0x0,0x0,0x500,0x500,0x2014,0x1,0x1,0x0,0x0,0x4002,0x1000,0x200,0x80,0x1000,0x0,0x0,};
   }

  /** Constructor with InputStream. */
  public FridgeParser(java.io.InputStream stream) {
     this(stream, null);
  }
  /** Constructor with InputStream and supplied encoding */
  public FridgeParser(java.io.InputStream stream, String encoding) {
    if (jj_initialized_once) {
      System.out.println("ERROR: Second call to constructor of static parser.  ");
      System.out.println("       You must either use ReInit() or set the JavaCC option STATIC to false");
      System.out.println("       during parser generation.");
      throw new Error();
    }
    jj_initialized_once = true;
    try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
    token_source = new FridgeParserTokenManager(jj_input_stream);
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 33; i++) jj_la1[i] = -1;
  }

  /** Reinitialise. */
  static public void ReInit(java.io.InputStream stream) {
     ReInit(stream, null);
  }
  /** Reinitialise. */
  static public void ReInit(java.io.InputStream stream, String encoding) {
    try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
    token_source.ReInit(jj_input_stream);
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 33; i++) jj_la1[i] = -1;
  }

  /** Constructor. */
  public FridgeParser(java.io.Reader stream) {
    if (jj_initialized_once) {
      System.out.println("ERROR: Second call to constructor of static parser. ");
      System.out.println("       You must either use ReInit() or set the JavaCC option STATIC to false");
      System.out.println("       during parser generation.");
      throw new Error();
    }
    jj_initialized_once = true;
    jj_input_stream = new SimpleCharStream(stream, 1, 1);
    token_source = new FridgeParserTokenManager(jj_input_stream);
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 33; i++) jj_la1[i] = -1;
  }

  /** Reinitialise. */
  static public void ReInit(java.io.Reader stream) {
    jj_input_stream.ReInit(stream, 1, 1);
    token_source.ReInit(jj_input_stream);
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 33; i++) jj_la1[i] = -1;
  }

  /** Constructor with generated Token Manager. */
  public FridgeParser(FridgeParserTokenManager tm) {
    if (jj_initialized_once) {
      System.out.println("ERROR: Second call to constructor of static parser. ");
      System.out.println("       You must either use ReInit() or set the JavaCC option STATIC to false");
      System.out.println("       during parser generation.");
      throw new Error();
    }
    jj_initialized_once = true;
    token_source = tm;
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 33; i++) jj_la1[i] = -1;
  }

  /** Reinitialise. */
  public void ReInit(FridgeParserTokenManager tm) {
    token_source = tm;
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 33; i++) jj_la1[i] = -1;
  }

  static private Token jj_consume_token(int kind) throws ParseException {
    Token oldToken;
    if ((oldToken = token).next != null) token = token.next;
    else token = token.next = token_source.getNextToken();
    jj_ntk = -1;
    if (token.kind == kind) {
      jj_gen++;
      return token;
    }
    token = oldToken;
    jj_kind = kind;
    throw generateParseException();
  }


/** Get the next Token. */
  static final public Token getNextToken() {
    if (token.next != null) token = token.next;
    else token = token.next = token_source.getNextToken();
    jj_ntk = -1;
    jj_gen++;
    return token;
  }

/** Get the specific Token. */
  static final public Token getToken(int index) {
    Token t = token;
    for (int i = 0; i < index; i++) {
      if (t.next != null) t = t.next;
      else t = t.next = token_source.getNextToken();
    }
    return t;
  }

  static private int jj_ntk() {
    if ((jj_nt=token.next) == null)
      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
    else
      return (jj_ntk = jj_nt.kind);
  }

  static private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
  static private int[] jj_expentry;
  static private int jj_kind = -1;

  /** Generate ParseException. */
  static public ParseException generateParseException() {
    jj_expentries.clear();
    boolean[] la1tokens = new boolean[50];
    if (jj_kind >= 0) {
      la1tokens[jj_kind] = true;
      jj_kind = -1;
    }
    for (int i = 0; i < 33; i++) {
      if (jj_la1[i] == jj_gen) {
        for (int j = 0; j < 32; j++) {
          if ((jj_la1_0[i] & (1<<j)) != 0) {
            la1tokens[j] = true;
          }
          if ((jj_la1_1[i] & (1<<j)) != 0) {
            la1tokens[32+j] = true;
          }
        }
      }
    }
    for (int i = 0; i < 50; i++) {
      if (la1tokens[i]) {
        jj_expentry = new int[1];
        jj_expentry[0] = i;
        jj_expentries.add(jj_expentry);
      }
    }
    int[][] exptokseq = new int[jj_expentries.size()][];
    for (int i = 0; i < jj_expentries.size(); i++) {
      exptokseq[i] = jj_expentries.get(i);
    }
    return new ParseException(token, exptokseq, tokenImage);
  }

  /** Enable tracing. */
  static final public void enable_tracing() {
  }

  /** Disable tracing. */
  static final public void disable_tracing() {
  }

}
