/* Generated By:JavaCC: Do not edit this line. SQL.java */
package org.lared.desinventar.dbase;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.sql.SQLException;


public class SQL implements SQLConstants {
        SQLStatement sqlStatement = new SQLStatement();

        // Where tracking data:
        Where where = null;             // The current where comparison section.

        InputStream stream = System.in; // Default stream.

         public static void main(String args[])
         {
                int i;
                String sql = args[0];
                System.out.println("SQL = [" + sql + "]");

                final int MAX_COLUMN = 79;
                for (i = 1; i < MAX_COLUMN; i++)
                        System.out.print(i % 10);
                System.out.println();
                for (i = 1; i < MAX_COLUMN; i++)
                        if (i % 10 == 0 || i ==1)
                                System.out.print(i / 10);
                        else System.out.print(" ");
                System.out.println();

                SQL parser = new SQL(sql);
                try {
                        parser.Statement();
                        SQLStatement st = parser.getStatement();
                        st.complete();
                        System.out.println(st);
                } catch (ParseException pe) {
                        System.out.println(pe.getMessage());
                        System.out.println("SQL Parser:  Encountered errors during parse.");
                } catch (SQLException se) {
                        System.out.println(se.getMessage());
                        System.out.println("SQL Parser:  Encountered errors during parse.");
                }
        }

        /**
	* Constructor for a string.
	*
	* @param sql String SQL statement.
	*/
        public SQL(String s)
        {
                this(new ByteArrayInputStream(s.getBytes()));
                sqlStatement.sqlSource = s;
        }

        public SQLStatement getStatement()
        {
                return sqlStatement;
        }

        /**
	* Return the value of a literal as an object.
	*
	* @param literal String literal.
	* @return Object of the type representing this literal.
	*/
        public Object getLiteralType(String literal)
        {
//System.out.println("getLiteralType: [" + literal + "]");
                Object o = null;

                if (literal.startsWith("'"))
                {
                        literal = literal.substring(1);
                        literal = literal.substring(0, literal.length() - 1);

                        // Replace the remaining escaped quotes with single quotes.
                        literal = Text.replace(literal, "''", "'");

                        return literal;
                }

                // It's either a number (double) or a string (field name).
                try {
                        o = new Double( Double.parseDouble(literal));
                } catch (NumberFormatException nfe1) {
                        try {
                                if (literal.startsWith("0X") || literal.startsWith("0x"))
                                {
                                        String n = literal.substring(2);
                                        o = new Integer( Integer.parseInt(n, 16));
                                        o = new Double( ((Integer)o).intValue());
                                }
                        } catch (NumberFormatException nfe2) {
                                // It's a string.
//System.out.println("getLiteralType: Nothing interesting apparently: [" + literal + "]");
                        }
                }

                return o;
        }

// All the statements we know.
  final public void Statement() throws ParseException {
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case INSERT:
      Insert();
      break;
    case UPDATE:
      Update();
      break;
    case SELECT:
      Select();
      break;
    case DELETE:
      Delete();
      jj_consume_token(0);
      break;
    default:
      jj_la1[0] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

// The SELECT statement.
  final public void Select() throws ParseException {
//System.out.println("Select found");
        sqlStatement.type = SQLStatement.STATEMENT_SELECT;
    jj_consume_token(SELECT);
    FieldOrStar();
    jj_consume_token(FROM);
    Table();
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case WHERE:
      Where();
      break;
    default:
      jj_la1[1] = jj_gen;
      ;
    }
  }

// The UPDATE statement.
  final public void Update() throws ParseException {
//System.out.println("Update found");
        sqlStatement.type = SQLStatement.STATEMENT_UPDATE;
    jj_consume_token(UPDATE);
    Table();
    jj_consume_token(SET);
    Field();
    jj_consume_token(EQ);
    Value();
    label_1:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case COMMA:
        ;
        break;
      default:
        jj_la1[2] = jj_gen;
        break label_1;
      }
      jj_consume_token(COMMA);
      Field();
      jj_consume_token(EQ);
      Value();
    }
    Where();
  }

// The INSERT statement.
  final public void Insert() throws ParseException {
//System.out.println("Insert found");
        sqlStatement.type = SQLStatement.STATEMENT_INSERT;
    jj_consume_token(INSERT);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case INTO:
      jj_consume_token(INTO);
      break;
    default:
      jj_la1[3] = jj_gen;
      ;
    }
    Table();
    jj_consume_token(LPAREN);
    Field();
    label_2:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case COMMA:
        ;
        break;
      default:
        jj_la1[4] = jj_gen;
        break label_2;
      }
      jj_consume_token(COMMA);
      Field();
    }
    jj_consume_token(RPAREN);
    jj_consume_token(VALUES);
    jj_consume_token(LPAREN);
    Value();
    label_3:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case COMMA:
        ;
        break;
      default:
        jj_la1[5] = jj_gen;
        break label_3;
      }
      jj_consume_token(COMMA);
      Value();
    }
    jj_consume_token(RPAREN);
  }

// The DELETE statement.
  final public void Delete() throws ParseException {
        sqlStatement.type = SQLStatement.STATEMENT_DELETE;
    jj_consume_token(DELETE);
    jj_consume_token(FROM);
    Table();
    Where();
  }

  final public void Table() throws ParseException {
        Token t;
    t = jj_consume_token(IDENTIFIER);
    sqlStatement.tableName.add(t.image);
//System.out.println("Table found: " + t.image);

  }

// Accept a field list or a '*'.
  final public void FieldOrStar() throws ParseException {
        Token star;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case IDENTIFIER:
      Field();
      label_4:
      while (true) {
        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
        case COMMA:
          ;
          break;
        default:
          jj_la1[6] = jj_gen;
          break label_4;
        }
        jj_consume_token(COMMA);
        Field();
      }
      break;
    case STAR:
      star = jj_consume_token(STAR);
                sqlStatement.fields.add(star.image);
      break;
    default:
      jj_la1[7] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  final public void Field() throws ParseException {
        Token f;
    f = jj_consume_token(IDENTIFIER);
//System.out.println("Field found: " + f);
                sqlStatement.fields.add(f.image);
  }

  final public void Where() throws ParseException {
    jj_consume_token(WHERE);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case NOT:
      WhereNot();
      break;
    default:
      jj_la1[8] = jj_gen;
      ;
    }
    WhereField();
    WhereCompare();
    WhereValue();
    label_5:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case AND:
      case OR:
        ;
        break;
      default:
        jj_la1[9] = jj_gen;
        break label_5;
      }
      WhereConj();
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case NOT:
        WhereNot();
        break;
      default:
        jj_la1[10] = jj_gen;
        ;
      }
      WhereField();
      WhereCompare();
      WhereValue();
    }

  }

  final public void WhereField() throws ParseException {
        Token wf;

        // This is a likely place to start a new Where.
        if (where == null)
                where = new Where();
    wf = jj_consume_token(IDENTIFIER);
//System.out.println("WhereField found: " + wf);
                where.field = wf.image;
  }

  final public void WhereValue() throws ParseException {
        Token wv;
        FieldValue fv = new FieldValue();
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case IDENTIFIER:
      wv = jj_consume_token(IDENTIFIER);
                // This is the last part of a where section found, add the where to the sqlStatment where list.
                fv.type = FieldValue.FIELD;
                fv.value = wv.image;
                where.fValue = fv;

                // Save this Where and start a new Where, since this is the last token to be picked up in a Where comparison.
                sqlStatement.whereList.add(where);
                where = null;
      break;
    case LITERAL:
      wv = jj_consume_token(LITERAL);
                fv.type = FieldValue.LITERAL;
                fv.value = getLiteralType(wv.image);    // Replace two quotes (an escaped quote)  with a single one.
                where.fValue = fv;

                // Save this Where and start a new Where, since this is the last token to be picked up in a Where comparison.
                sqlStatement.whereList.add(where);
                where = null;
      break;
    default:
      jj_la1[11] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  final public void WhereCompare() throws ParseException {
        Token op;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case NE:
      op = jj_consume_token(NE);
                where.operator = Where.COMPARITOR_NOTEQUAL;
      break;
    case GT:
      op = jj_consume_token(GT);
                where.operator = Where.COMPARITOR_GT;
      break;
    case LT:
      op = jj_consume_token(LT);
                where.operator = Where.COMPARITOR_LT;
      break;
    case LE:
      op = jj_consume_token(LE);
                where.operator = Where.COMPARITOR_LTEQ;
      break;
    case GE:
      op = jj_consume_token(GE);
                where.operator = Where.COMPARITOR_GTEQ;
      break;
    case EQ:
      op = jj_consume_token(EQ);
                where.operator = Where.COMPARITOR_EQUAL;
      break;
    default:
      jj_la1[12] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  final public void WhereNot() throws ParseException {
        // This is a likely place to start a new Where.
        if (where == null)
                where = new Where();
    jj_consume_token(NOT);
//System.out.println("WhereNot: operator = true");
                where.notOperator = true;
  }

  final public void WhereConj() throws ParseException {
        Token conj;

        // This is a likely place to start a new Where.
        if (where == null)
                where = new Where();
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case AND:
      conj = jj_consume_token(AND);
                where.conjunction = Where.CONJ_AND;
      break;
    case OR:
      conj = jj_consume_token(OR);
                where.conjunction = Where.CONJ_OR;
//System.out.println("SQL Parser: Conjunction: " + conj.image);

      break;
    default:
      jj_la1[13] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  final public void Value() throws ParseException {
        Token val;
        FieldValue fv = new FieldValue();
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case IDENTIFIER:
      val = jj_consume_token(IDENTIFIER);
//System.out.println("Val found: (field)" + val);
                fv = new FieldValue();
                fv.type = FieldValue.FIELD;
                fv.value = val.image;
                sqlStatement.values.add(fv);
      break;
    case LITERAL:
      val = jj_consume_token(LITERAL);
//System.out.println("Val found: (literal)" + val);
                fv = new FieldValue();
                fv.type = FieldValue.LITERAL;
                fv.value = getLiteralType(val.image);   // Replace two quotes (an escaped quote)  with a single one.
                sqlStatement.values.add(fv);
      break;
    default:
      jj_la1[14] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
  }

  public SQLTokenManager token_source;
  JavaCharStream jj_input_stream;
  public Token token, jj_nt;
  private int jj_ntk;
  private int jj_gen;
  final private int[] jj_la1 = new int[15];
  final private int[] jj_la1_0 = {0xe0,0x100,0x0,0x400,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
  final private int[] jj_la1_1 = {0x8,0x0,0x100000,0x0,0x100000,0x100000,0x100000,0x28000000,0x8000,0x30000,0x8000,0x30000000,0x7e00000,0x30000,0x30000000,};

  public SQL(java.io.InputStream stream) {
    jj_input_stream = new JavaCharStream(stream, 1, 1);
    token_source = new SQLTokenManager(jj_input_stream);
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 15; i++) jj_la1[i] = -1;
  }

  public void ReInit(java.io.InputStream 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 < 15; i++) jj_la1[i] = -1;
  }

  public SQL(java.io.Reader stream) {
    jj_input_stream = new JavaCharStream(stream, 1, 1);
    token_source = new SQLTokenManager(jj_input_stream);
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 15; i++) jj_la1[i] = -1;
  }

  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 < 15; i++) jj_la1[i] = -1;
  }

  public SQL(SQLTokenManager tm) {
    token_source = tm;
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 15; i++) jj_la1[i] = -1;
  }

  public void ReInit(SQLTokenManager tm) {
    token_source = tm;
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 15; i++) jj_la1[i] = -1;
  }

  final 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();
  }

  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;
  }

  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;
  }

  final 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);
  }

  private java.util.Vector jj_expentries = new java.util.Vector();
  private int[] jj_expentry;
  private int jj_kind = -1;

  final public ParseException generateParseException() {
    jj_expentries.removeAllElements();
    boolean[] la1tokens = new boolean[64];
    for (int i = 0; i < 64; i++) {
      la1tokens[i] = false;
    }
    if (jj_kind >= 0) {
      la1tokens[jj_kind] = true;
      jj_kind = -1;
    }
    for (int i = 0; i < 15; 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 < 64; i++) {
      if (la1tokens[i]) {
        jj_expentry = new int[1];
        jj_expentry[0] = i;
        jj_expentries.addElement(jj_expentry);
      }
    }
    int[][] exptokseq = new int[jj_expentries.size()][];
    for (int i = 0; i < jj_expentries.size(); i++) {
      exptokseq[i] = (int[])jj_expentries.elementAt(i);
    }
    return new ParseException(token, exptokseq, tokenImage);
  }

  final public void enable_tracing() {
  }

  final public void disable_tracing() {
  }

}
