Javacc Parser Generation

Vijendra
2006-03-07
2013-04-29
  • Vijendra
    Vijendra
    2006-03-07

    Hi all, about Java Parser Generators: SqlParser.jj file
    I have to modify this file to do one specific thing.
    My aim is to ignore certain statement:
    i.e. create view (...........after that whole statement)
    If it is possible by modifying this SqlParser.jj file please give me some hint or way to achive the target.
    It generates all 7 files when gets executed by command
    Javacc SqlParser.jj
    so if anyone can do something plase let me know.

    Here is SqlParser.jj file which generates Parsers:-
    command :- JavaCC SqlParser.jj

    /**
    * This is the JavaCC grammar definition file for the DDL dialect used by App.
    */
    // options {
    // DEBUG_PARSER = true;
    // }

    PARSER_BEGIN(SqlParser)

    package App.sqlParser;
    import com.sun.java.util.collections.*;
    import java.io.*;
    import java.util.Enumeration;
    import App.dbSupport.*;
    import App.core.*;

    /**
    * The SqlParser class encapsulates parsing of SQL DDL statements to enable
    * App to construct the schema-related data structures. Most of its
    * implementation is generated using the
    * JavaCC
    * application.
    */
    public class SqlParser {
    public interface ConstraintType {

    public static final int UNIQUE = 1;

    public static final int PRIMARY_KEY = 2;

    }

    public static void main (String args[]) throws Exception {
    Schema dbSchema = buildSchema (new InputStreamReader (System.in));
    System.out.println (dbSchema.toString());
    }

    public static synchronized Schema buildSchema (Reader stream)
    throws ZcException {
    _fkConstraints = new ArrayList();
    _errorList = new Vector();
    _dbSchema = new Schema ("ZeroCodeSchema");
    if (_parser == null)
    _parser = new SqlParser (stream);
    else
    _parser.ReInit (stream);
    try {
    _parser.ddlSequence ();
    } catch (ParseException e) {
    throw new ZcException
    (ErrorCode.INVALID_SCHEMA, "SQL syntax error: " + e.getMessage());
    }
    _dbSchema.setConstraints (_fkConstraints);

    if (_errorList.size() > 0)
    throw new ZcException
    (ErrorCode.INVALID_SCHEMA,
    "Schema errors:\n" + StringUtils.join (_errorList, "\n"));
    return _dbSchema;
    }
    private static void addTable (DbTable table) {
    _dbSchema.addTable (table);
    }

    private static void addSequence (String sequenceName) {
    _dbSchema.addSequence (sequenceName);
    }

    private static int convertToken (String message)
    throws ZcException {
    try {
    int val = Integer.parseInt (token.toString());
    return val;
    } catch (NumberFormatException e) {
    throw new ZcException
    (ErrorCode.INVALID_SCHEMA,
    message + "token '" + token.toString() + "' line " +
    token.beginLine + " column " + token.beginColumn);
    }
    }

    private static void setConstraint (DbTable table, String constraintName,
    int constraintType,
    StringSet columnNameSet) {
    if (constraintType == ConstraintType.PRIMARY_KEY) {
    int nCols = columnNameSet.size();
    if (nCols > 1) {
    // _errorList.add ("Table " + table.name() + ": must have " +
    // "exactly one column as primary key.");
    // We set the pri key anyway, to inhibit the subsequent
    // "No primary key defined" error message.
    table.setPrimaryKey (columnNameSet);
    } else if (nCols <= 0) {
    // _errorList.add ("Table " + table.name() + ": must have " +
    // "a primary key.");
    } else {
    String colName = (String) columnNameSet.asArray()[0];
    DbColumn col = table.columnWithName (colName);
    if (col == null)
    _errorList.add ("Table " + table.name() + ": Column '" +
    colName + "', specified in primary key " +
    "constraint, is not a declared column.");
    else
    table.setPrimaryKey (col.name());
    }
    } else {
    // It should be a UNIQUE constraint
    table.addUniqueConstraint
    (new UniqueConstraint (constraintName, table, columnNameSet));
    }
    }

    private static void addForeignKeyConstraint (String constraintName,
    DbTable table,
    StringSet columnNameSet,
    String toTableName,
    String toColName) {
    if (columnNameSet.size() != 1) {
    // We now silently ignore this problem -- MAS 1/7/2003
    // _errorList.add ("Table " + table.name() + ": must have " +
    // "exactly one column in foreign key.");
    return;
    }
    String fkColName = columnNameSet.asArray()[0];
    DbColumn fkCol = table.columnWithName (fkColName);
    if (fkCol == null) {
    _errorList.add ("Table " + table.name() +
    ": Cannot add foreign key constraint: no " +
    "foreign key column named '" + fkColName + "'");
    return;
    }
    DbTable toTable = _dbSchema.tableWithName (toTableName);
    if (toTable == null) {
    _errorList.add ("Table '" + toTableName + "' not found in schema.");
    return;
    }
    DbColumn toColumn = toTable.columnWithName (toColName);
    if (toColumn == null) {
    _errorList.add ("Attempting to add foreign key from " +
    table.name() + "(" +
    columnNameSet.joinString(",") + ") to table '" +
    toTableName + "': the latter has no column " +
    "named '" + toColName + "'");
    } else {
    String constraintId = constraintName != null
    ? constraintName
    : ("zcFkConstraint" + (++zcFkCount));
    ForeignKeyConstraint constraint = new ForeignKeyConstraint
    (constraintId, fkCol, toColumn, _fkConstraints.size());
    _fkConstraints.add (constraint);
    }
    }

    private static Schema _dbSchema;
    private static Vector _errorList;
    private static List _fkConstraints;
    private static SqlParser _parser;

    private static int zcFkCount = 0;
    }

    PARSER_END(SqlParser)

    SKIP :
    {
    " "
    |
    "\t"
    |
    "\n"
    |
    "\r"
    |
    "--" : IN_LINE_COMMENT
    |
    "/*" : IN_COMMENT

    }

    SKIP:
    {
    "\n" : DEFAULT
    }

    MORE:
    {
    < ~[] >
    }

    SKIP:
    {
    "*/" : DEFAULT
    }

    MORE:
    {
    < ~[] >
    }

    TOKEN [IGNORE_CASE] :
    {
    < ADD: "add" >
    | < ALL: "all" >
    | < ALTER: "alter" >
    | < AND: "and" >
    | < ANY: "any" >
    | < ASC: "asc" >
    | < BY: "by" >
    | < CACHE: "cache" >
    | < CASCADE: "cascade" >
    | < CHECK: "check" >
    | < COLUMN: "column" >
    | < COMMENT: "comment" >
    | < CONSTRAINT: "constraint" >
    | < CONSTRAINTS: "constraints" >
    | < CREATE: "create" >
    | < CYCLE: "cycle" >
    | < DEFAULT_TOK: "default" >
    | < DELETE: "delete" >
    | < DESC: "desc" >
    | < DROP: "drop" >
    | < FOREIGN: "foreign" >
    | < IDENTITY: "identity" >
    | < IN: "in" >
    | < INCREMENT: "increment" >
    | < INDEX: "index" >
    | < IS: "is" >
    | < KEY: "key" >
    | < MAXVALUE: "maxvalue" >
    | < MINVALUE: "minvalue" >
    | < NOCACHE: "nocache" >
    | < NOCYCLE: "nocycle" >
    | < NOMAXVALUE: "nomaxvalue" >
    | < NOMINVALUE: "nominvalue" >
    | < NOORDER: "noorder" >
    | < NOT: "not" >
    | < NULL: "null" >
    | < ON: "on" >
    | < OR: "or" >
    | < ORDER: "order" >
    | < PRIMARY: "primary" >
    | < REFERENCES: "references" >
    | < SEQUENCE: "sequence" >
    | < SOME: "some" >
    | < START: "start" >
    | < TABLE: "table" >
    | < UNIQUE : "unique" >
    | < UPDATE : "update" >
    | < WITH: "with" >

    | < COMMA: "," >
    | < DOT: "." >
    | < IDENTIFIER: ["a"-"z","A"-"Z", "_"] (["a"-"z", "_", "0"-"9", "$", "#"])* >
    | < LPAREN: "(" >
    | < NUMBER: (["0"-"9"])+ >
    | < RPAREN: ")" >
    | < SEMICOLON: ";" >
    | < SLASH: "/" >
    | < STRING_LITERAL:
    (
    "'"
    (~["'","\\&quot;,"\n","\r"])*
    "'"
    )+
    >
    }

    String allowedColumnName () :
    {}
    {
    (
    LOOKAHEAD(2)
    < IDENTIFIER >
    | < ANY >
    | < ASC >
    | < BY >
    | < CACHE >
    | < CASCADE >
    | < CHECK >
    | < COLUMN >
    | < COMMENT >
    | < CONSTRAINTS >
    | < CREATE >
    | < CYCLE >
    | < DEFAULT_TOK >
    | < DELETE >
    | < DESC >
    | < DROP >
    | < FOREIGN >
    | < IDENTITY >
    | < IN >
    | < INCREMENT >
    | < INDEX >
    | < IS >
    | < KEY >
    | < MAXVALUE >
    | < MINVALUE >
    | < NOCACHE >
    | < NOCYCLE >
    | < NOMAXVALUE >
    | < NOMINVALUE >
    | < NOORDER >
    | < NOT >
    | < NULL >
    | < ON >
    | < OR >
    | < ORDER >
    | < PRIMARY >
    | < REFERENCES >
    | < SEQUENCE >
    | < SOME >
    | < START >
    | < TABLE >
    | < UNIQUE >
    | < UPDATE >
    | < WITH >
    ) { return token.toString(); }
    }

    void ddlSequence () throws ZcException :
    {
    DbTable table;
    String sequenceName;
    }

    {
    (
    (
    comment()
    |
    (

    (
    table = tableDefinition () {
    addTable (table);
    }

    |
    indexDefinition ()
    |
    sequenceName = sequenceDefinition ()
    {
    addSequence (sequenceName);
    }
    )
    )
    |
    alterTable ()
    |
    dropTable()

    )
    (

    |

    )+
    )+

    }

    void comment () :
    { }
    {
        <COMMENT>
        <ON>
        (
          (
            <TABLE>
            <IDENTIFIER>
          )
          |
          (
            <COLUMN>
            <IDENTIFIER>
            <DOT>
            <IDENTIFIER>
          )
        )
        <IS>
        <STRING_LITERAL>
    }

    DbTable tableDefinition () throws ZcException  :
    {
        DbTable table;
        DbColumn col;
    }
    {
       <TABLE> <IDENTIFIER>                   {
                                                  table = new DbTable
                                                      (token.toString(), _dbSchema);
                                              }
                                             
       <LPAREN>
       col = columnDefinition (table)
       (
         <COMMA>
         (
           LOOKAHEAD(2)
           col = columnDefinition (table)
         |
           constraint (table)
         )
                                             
       )*
       <RPAREN>

       {return table;}
    }

    DbColumn columnDefinition (DbTable table)
         throws ZcException :
    {
        String columnName, columnType;
        int size = 0, precision = 0;
        boolean nullable = true;
        DbColumn col;
    }
    {
      (
         columnName = allowedColumnName()
         <IDENTIFIER>       {columnType = token.toString();}
         ( <IDENTIFIER>     {
                                columnType += " " + token.toString();
                            }
         )?
         (
           <LPAREN>
           <NUMBER>         {
                                size = convertToken ("Integer size expected");
                            }
                           
           (
             <COMMA>
             <NUMBER>       {
                                precision = convertToken
                                    ("Integer precision expected");
                            }
           )?
           <RPAREN>
         )?                 {
                                col = new DbColumn
                                     (columnName, columnType, size, precision,
                                      table.columnCount(), nullable, table);
                                table.addColumn (col);
                            }
         (
             columnConstraint(col)
         )*               
       )
       {return col;} 
    }

    void columnConstraint (DbColumn col) throws ZcException:
    {
        boolean nullable = true;
        String toTableName, toColumnName, constraintName;
        int constraintType;
        StringSet colNameSet = null;
    }
    {
        (
          <CONSTRAINT>
          <IDENTIFIER>      {
                               constraintName = token.toString();
                            }
          (
            (

              <UNIQUE>      {
                                constraintType = ConstraintType.UNIQUE;
                            }
            )
            |

            (
                <PRIMARY>
                <KEY>       {
                                constraintType = ConstraintType.PRIMARY_KEY;
                                col.table().setPrimaryKey (col.name());
                            }
            )

            |

            (
              (
                <FOREIGN>
                <KEY>
                (
                  <IDENTIFIER>
                )?                {
                                     constraintName = token.toString();
                                  }
              )?
              <REFERENCES>
              <IDENTIFIER>    {
                                  toTableName = token.toString();
                                  DbTable toTable = _dbSchema.tableWithName
                                      (toTableName);
                                  if (toTable == null)
                                      throw new ZcException
                                          (ErrorCode.INTERNAL_ERROR,
                                          "Foreign key reference to nonexistent " +
                                           "table '" + toTableName + "': line " +
                                           token.beginLine + ", column " + token.beginColumn);
                                  toColumnName = toTable.primaryKeyName();
                                  if (toColumnName == null)
                                      throw new ZcException
                                          (ErrorCode.INTERNAL_ERROR,
                                           "Foreign key reference to table '" +
                                           toTableName + "' with no primary key: line " +
                                           token.beginLine + ", column " + token.beginColumn);
                              }
              (
                <LPAREN>
                colNameSet = columnNameList()
                <RPAREN>
              )?              {
                                  DbTable table = col.table();
                                  if (colNameSet != null && colNameSet.size() > 0){
                                      if (colNameSet.size() > 1)
                                          throw new ZcException
                                              (ErrorCode.INVALID_SCHEMA,
                                               "Column " + col + " refers to " +
                                               "more than one column: line " +
                                               token.beginLine + ", column " +
                                               token.beginColumn);
                                      toColumnName = colNameSet.asArray()[0];
                                  }
                                  StringSet colNames = new StringSet();
                                  colNames.add (col.name());
                                  addForeignKeyConstraint
                                      (constraintName, table, colNames, toTableName, toColumnName);
                              }
            )
          )
        )
        |
        (
          <CHECK>
          <LPAREN>
          checkCondition()
          <RPAREN>
        )
        |
        (
          (
            <NOT>           {
                                col.setNullable (false);
                            }
          )?
          <NULL>          
        )
        |
        (
          defaultClause()
        )
        |
        (
          <IDENTITY>
          (
            <LPAREN>
            <NUMBER>
            <COMMA>
            <NUMBER>
            <RPAREN>
          )?
                            {
                                col.setIdentity ();
                            }
        )
    }

    void defaultClause () :
    {}
    {
          <DEFAULT_TOK>
          defaultExpr()
    }

    void constraint (DbTable table) throws ZcException :
    {
        String constraintName = null;
        int constraintType = 0;
        StringSet colNameSet = null, refColNameSet = null;
        String toTableName = null;
        String toColumn = null;
    }
    {

        (
          <CONSTRAINT>
          <IDENTIFIER>      {
                               constraintName = token.toString();
                            }
        )?
        (
          (

            (
              <UNIQUE>      {
                                constraintType = ConstraintType.UNIQUE;
                            }

              |

              (
                <PRIMARY>
                <KEY>       {
                                constraintType = ConstraintType.PRIMARY_KEY;
                            }
              )
            )
            <LPAREN>
            colNameSet = columnNameList ()
            <RPAREN>        {
                                setConstraint (table, constraintName,
                                               constraintType, colNameSet);
                            }
          )

          |

          (
            <FOREIGN>
            <KEY>
            (
              <IDENTIFIER>      {
                                   constraintName = token.toString();
                                }
            )?
            <LPAREN>
            colNameSet = columnNameList()
            <RPAREN>
            <REFERENCES>
            <IDENTIFIER>    {
                                toTableName = token.toString();
                                DbTable toTable = _dbSchema.tableWithName (toTableName);
                                if (toTable == null)
                                    throw new ZcException
                                        (ErrorCode.INTERNAL_ERROR,
                                        "Foreign key reference to nonexistent " +
                                         "table '" + toTableName + "': line " +
                                         token.beginLine + ", column " + token.beginColumn);
                                toColumn = toTable.primaryKeyName();
                            }
            (
              <LPAREN>
              refColNameSet = columnNameList ()
              <RPAREN>
            )?              {
                                if (refColNameSet != null && refColNameSet.size() > 0) {
                                    toColumn = refColNameSet.asArray()[0];
                                }
                                addForeignKeyConstraint
                                    (constraintName, table, colNameSet, toTableName, toColumn);
                            }
          )
          |
          (
            <CHECK>
            <LPAREN>
            checkCondition()
            <RPAREN>
          )
        )
    }

    StringSet columnNameList () :
    {
        StringSet columns = new StringSet();
    }
    {

        <IDENTIFIER>        {
                                columns.add (token.toString());
                            }
        (
          <COMMA>
          <IDENTIFIER>      {
                                columns.add (token.toString());
                            }
        )*

        {return columns;}

    }

    void alterTable () throws ZcException :
    {
        String tableName = null;
        DbTable table = null;
    }
    {
      <ALTER>
      <TABLE>
      <IDENTIFIER>          {
                                tableName = token.toString();
                                table = _dbSchema.tableWithName (tableName);
                                if (table == null)
                                    throw new ZcException
                                        (ErrorCode.INTERNAL_ERROR,
                                         "Invalid ALTER TABLE: " +
                                         "No table with name '" + tableName + "': line " +
                                         token.beginLine + ", column " + token.beginColumn);
                            }
      <ADD>
      (
        constraintClause (table)
        (
          <COMMA>
          constraintClause (table)
        )*
        |
        (
          <LPAREN>
          constraintClause (table)
          <RPAREN>
        )
      )
    }

    void constraintClause (DbTable table) throws ZcException:
    {
    }
    {
      constraint (table)
      (
        <ON>
         ( <DELETE> | <UPDATE> )
        <CASCADE>
      )?
    }

    void dropTable () :
    {}
    {
      <DROP>
      <TABLE>
      <IDENTIFIER>
      (
        <CASCADE>
        <CONSTRAINTS>
      )?
    }

    void indexDefinition () :
    {}
    {
      (
        <UNIQUE>
      )?
      <INDEX>
      <IDENTIFIER>
      <ON>
      <IDENTIFIER>
      <LPAREN>
      <IDENTIFIER>
      (
        <ASC>
        |
        <DESC>
      )?
      (
        <COMMA>
        <IDENTIFIER>
        (
          <ASC>
          |
          <DESC>
        )?
      )* 
      <RPAREN>
    }

    String sequenceDefinition () :
    {
        String name;
    }
    {
      <SEQUENCE>
      <IDENTIFIER> { name = token.toString(); }
      (
        (
          <INCREMENT> <BY> <NUMBER>
        )
        |
        (
          <START> <WITH> <NUMBER>
        )
        |
        (
          <CACHE> <NUMBER>
        )
        |
        <NOCACHE>
        |
        <CYCLE>
        |
        <NOCYCLE>
        |
        <NOMINVALUE>
        |
        (
          <MINVALUE> <NUMBER>
        )
        |
        <NOMAXVALUE>
        |
        (
          <MAXVALUE> <NUMBER>
        )
        |
        <ORDER>
        |
        <NOORDER>
      )*
      {return name;}
    }

    void defaultExpr () :
    {}
    {
      <STRING_LITERAL>
      |
      <NUMBER>
      |
      (
        <IDENTIFIER>
        (
          <LPAREN>
          defaultExpr()
          (
            <COMMA>
            defaultExpr()
          )*
          <RPAREN>
        )?
      )
      |
      (
        <LPAREN>
        defaultExpr()
        <RPAREN>
      )
    }

    void checkCondition() :
    {}
    {
      (
        <LPAREN>
        checkCondition()
        <RPAREN>
      )
      |
      (
        <NOT>
        checkCondition2()
      )
      |
      (
        checkCondition2()
        (
          (   
            <AND>
            |
            <OR>
          )
          checkCondition()
        )?
      )
    }

    void checkCondition2() :
    {}
    {
      expr()
      (
        (
          (
            "="
            |
            "!="
            |
            ">"
            |
            ">="
            |
            "<"
            |
            "<="
          )
          (
            expr()
            |
            (
              <ANY>
              |
              <SOME>
              |
              <ALL>
            )
            exprList()
          )
        )
        |
        (
          <IN>
          exprList()
        )
      )?     
    }

    void expr () :
    {}
    {
       (
         <STRING_LITERAL>
         |
         <NUMBER>
         |
         <IDENTIFIER>
       )
       (
         (
           "+"
           |
           "-"
           |
           "*"
           |
           <SLASH>
         )
         expr()
       )?
    }

    void exprList () :
    {}
    {
      <LPAREN>
      expr()
      (
        <COMMA>
        expr()
      )*
      <RPAREN>
    }