{@inheritDoc}

@see org.modeshape.sequencer.ddl.StandardDdlParser#parseGrantStatement(org.modeshape.sequencer.ddl.DdlTokenStream,
org.modeshape.sequencer.ddl.node.AstNode)
514917
@Override
    protected AstNode parseGrantStatement( DdlTokenStream tokens,
                                           AstNode parentNode ) throws ParsingException {
        assert tokens != null;
        assert parentNode != null;
        assert tokens.matches(GRANT);

        markStartOfStatement(tokens);

        // NOTE: The first wack at this does not take into account the apparent potential repeating name elements after each type
        // declaration. Example:
        // GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
        // [,...] | ALL [ PRIVILEGES ] }
        // ON [ TABLE ] tablename [, ...]
        // TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]
        //
        // the "ON [ TABLE ] tablename [, ...]" seems to indicate that you can grant privileges on multiple tables at once, which
        // is
        // different thatn the SQL 92 standard. So this pass ONLY allows one and an parsing error will probably occur if multiple.
        //
        // Syntax for tables
        //
        // GRANT <privileges> ON <object name>
        // TO <grantee> [ { <comma> <grantee> }... ]
        // [ WITH GRANT OPTION ]
        //
        // <object name> ::=
        // [ TABLE ] <table name>
        // | SEQUENCE <sequence name>
        // | DATABASE <db name>
        // | FOREIGN DATA WRAPPER <fdw name>
        // | FOREIGN SERVER <server name>
        // | FUNCTION <function name>
        // | LANGUAGE <language name>
        // | SCHEMA <schema name>
        // | TABLESPACE <tablespace name>

        //
        // Syntax for roles
        //
        // GRANT roleName [ {, roleName }* ] TO grantees

        // privilege-types
        //
        // ALL PRIVILEGES | privilege-list
        //
        List<AstNode> grantNodes = new ArrayList<AstNode>();
        boolean allPrivileges = false;

        List<AstNode> privileges = new ArrayList<AstNode>();

        tokens.consume("GRANT");

        if (tokens.canConsume("ALL", "PRIVILEGES")) {
            allPrivileges = true;
        } else {
            parseGrantPrivileges(tokens, privileges);
        }

        if (allPrivileges || !privileges.isEmpty()) {

            tokens.consume("ON");

            if (tokens.canConsume("SCHEMA")) {
                grantNodes = parseMultipleGrantTargets(tokens, parentNode, TYPE_GRANT_ON_SCHEMA_STATEMENT);
            } else if (tokens.canConsume("SEQUENCE")) {
                grantNodes = parseMultipleGrantTargets(tokens, parentNode, TYPE_GRANT_ON_SEQUENCE_STATEMENT);
            } else if (tokens.canConsume("TABLESPACE")) {
                grantNodes = parseMultipleGrantTargets(tokens, parentNode, TYPE_GRANT_ON_TABLESPACE_STATEMENT);
            } else if (tokens.canConsume("DATABASE")) {
                grantNodes = parseMultipleGrantTargets(tokens, parentNode, TYPE_GRANT_ON_DATABASE_STATEMENT);
            } else if (tokens.canConsume("FUNCTION")) {
                grantNodes = parseFunctionAndParameters(tokens, parentNode);
            } else if (tokens.canConsume("LANGUAGE")) {
                grantNodes = parseMultipleGrantTargets(tokens, parentNode, TYPE_GRANT_ON_LANGUAGE_STATEMENT);
            } else if (tokens.canConsume("FOREIGN", "DATA", "WRAPPER")) {
                grantNodes = parseMultipleGrantTargets(tokens, parentNode, TYPE_GRANT_ON_FOREIGN_DATA_WRAPPER_STATEMENT);
            } else if (tokens.canConsume("FOREIGN", "SERVER")) {
                grantNodes = parseMultipleGrantTargets(tokens, parentNode, TYPE_GRANT_ON_FOREIGN_SERVER_STATEMENT);
            } else {
                tokens.canConsume(TABLE); // OPTIONAL
                String name = parseName(tokens);
                AstNode grantNode = nodeFactory().node(name, parentNode, TYPE_GRANT_ON_TABLE_STATEMENT);
                grantNodes.add(grantNode);
                while (tokens.canConsume(COMMA)) {
                    // Assume more names here
                    name = parseName(tokens);
                    grantNode = nodeFactory().node(name, parentNode, TYPE_GRANT_ON_TABLE_STATEMENT);
                    grantNodes.add(grantNode);
                }
            }
        } else {
            // Assume ROLES here
            // role [, ...]
            AstNode grantNode = nodeFactory().node("roles", parentNode, TYPE_GRANT_ROLES_STATEMENT);
            grantNodes.add(grantNode);
            do {
                String role = parseName(tokens);
                nodeFactory().node(role, grantNode, ROLE);
            } while (tokens.canConsume(COMMA));
        }

        tokens.consume("TO");
        List<String> grantees = new ArrayList<String>();

        do {
            String grantee = parseName(tokens);
            grantees.add(grantee);
        } while (tokens.canConsume(COMMA));

        boolean withGrantOption = false;
        if (tokens.canConsume("WITH", "GRANT", "OPTION")) {
            withGrantOption = true;
        }

        // Set all properties and children on Grant Nodes
        for (AstNode grantNode : grantNodes) {
            List<AstNode> copyOfPrivileges = copyOfPrivileges(privileges);
            // Attach privileges to grant node
            for (AstNode node : copyOfPrivileges) {
                node.setParent(grantNode);
            }
            if (allPrivileges) {
                grantNode.setProperty(ALL_PRIVILEGES, allPrivileges);
            }
            for (String grantee : grantees) {
                nodeFactory().node(grantee, grantNode, GRANTEE);
            }

            if (withGrantOption) {
                AstNode optionNode = nodeFactory().node("withGrant", grantNode, TYPE_STATEMENT_OPTION);
                optionNode.setProperty(VALUE, "WITH GRANT OPTION");
            }
        }
        AstNode firstGrantNode = grantNodes.get(0);

        markEndOfStatement(tokens, firstGrantNode);

        // Update additional grant nodes with statement info

        for (int i = 1; i < grantNodes.size(); i++) {
            AstNode grantNode = grantNodes.get(i);
            grantNode.setProperty(DDL_EXPRESSION, firstGrantNode.getProperty(DDL_EXPRESSION));
            grantNode.setProperty(DDL_LENGTH, firstGrantNode.getProperty(DDL_LENGTH));
            grantNode.setProperty(DDL_START_LINE_NUMBER, firstGrantNode.getProperty(DDL_START_LINE_NUMBER));
            grantNode.setProperty(DDL_START_CHAR_INDEX, firstGrantNode.getProperty(DDL_START_CHAR_INDEX));
            grantNode.setProperty(DDL_START_COLUMN_NUMBER, firstGrantNode.getProperty(DDL_START_COLUMN_NUMBER));
        }

        return grantNodes.get(0);
    }
337191
protected Statement parseStatementSettings(XMLStreamReader reader) throws XMLStreamException, ParserException,
      ValidateException
   {

      Long preparedStatementsCacheSize = null;
      Boolean sharePreparedStatements = Defaults.SHARE_PREPARED_STATEMENTS;
      TrackStatementsEnum trackStatements = null;

      Map<String, String> expressions = new HashMap<String, String>();

      while (reader.hasNext())
      {
         switch (reader.nextTag())
         {
            case END_ELEMENT : {
               if (XML.ELEMENT_STATEMENT.equals(reader.getLocalName()))
               {
                  return new StatementImpl(sharePreparedStatements, preparedStatementsCacheSize, trackStatements,
                          !expressions.isEmpty() ? expressions : null);
               }
               else
               {
                  switch (reader.getLocalName())
                  {
                     case XML.ELEMENT_PREPARED_STATEMENT_CACHE_SIZE :
                     case XML.ELEMENT_TRACK_STATEMENTS :
                     case XML.ELEMENT_SHARE_PREPARED_STATEMENTS :
                        break;
                     default :
                        throw new ParserException(bundle.unexpectedEndTag(reader.getLocalName()));
                  }
               }
               break;
            }
            case START_ELEMENT : {
               switch (reader.getLocalName())
               {
                  case XML.ELEMENT_PREPARED_STATEMENT_CACHE_SIZE : {
                     preparedStatementsCacheSize = elementAsLong(reader, XML.ELEMENT_PREPARED_STATEMENT_CACHE_SIZE,
                                                                 expressions);
                     break;
                  }
                  case XML.ELEMENT_TRACK_STATEMENTS : {
                     String elementString = elementAsString(reader, XML.ELEMENT_TRACK_STATEMENTS, expressions);
                     trackStatements = TrackStatementsEnum.valueOf(elementString == null ? "FALSE" : elementString
                        .toUpperCase(Locale.US));
                     break;
                  }
                  case XML.ELEMENT_SHARE_PREPARED_STATEMENTS : {
                     sharePreparedStatements = elementAsBoolean(reader, XML.ELEMENT_SHARE_PREPARED_STATEMENTS,
                                                                expressions);
                     break;
                  }
                  default :
                     throw new ParserException(bundle.unexpectedElement(reader.getLocalName()));
               }
               break;
            }
         }
      }
      throw new ParserException(bundle.unexpectedEndOfDocument());
   }
1118756
private ParseTree parseForStatement() {
    SourcePosition start = getTreeStartLocation();
    eat(TokenType.FOR);
    boolean awaited = peekPredefinedString(AWAIT);
    if (awaited) {
      eatPredefinedString(AWAIT);
    }
    eat(TokenType.OPEN_PAREN);
    if (peekVariableDeclarationList()) {
      VariableDeclarationListTree variables = parseVariableDeclarationListNoIn();
      if (peek(TokenType.IN)) {
        if (awaited) {
          reportError("for-await-of is the only allowed asynchronous iteration");
        }
        // for-in: only one declaration allowed
        if (variables.declarations.size() > 1) {
          reportError("for-in statement may not have more than one variable declaration");
        }
        VariableDeclarationTree declaration = variables.declarations.get(0);
        if (declaration.initializer != null) {
          // An initializer is allowed here in ES5 and below, but not in ES6.
          // Warn about it, to encourage people to eliminate it from their code.
          // http://esdiscuss.org/topic/initializer-expression-on-for-in-syntax-subject
          if (config.atLeast6) {
            reportError("for-in statement may not have initializer");
          } else {
            errorReporter.reportWarning(declaration.location.start,
                "for-in statement should not have initializer");
          }
        }

        return parseForInStatement(start, variables);
      } else if (peekPredefinedString(PredefinedName.OF)) {
        // for-of: only one declaration allowed
        if (variables.declarations.size() > 1) {
          if (awaited) {
            reportError("for-await-of statement may not have more than one variable declaration");
          } else {
            reportError("for-of statement may not have more than one variable declaration");
          }
        }
        // for-of: initializer is illegal
        VariableDeclarationTree declaration = variables.declarations.get(0);
        if (declaration.initializer != null) {
          if (awaited) {
            reportError("for-await-of statement may not have initializer");
          } else {
            reportError("for-of statement may not have initializer");
          }
        }

        if (awaited) {
          return parseForAwaitOfStatement(start, variables);
        } else {
          return parseForOfStatement(start, variables);
        }
      } else {
        // "Vanilla" for statement: const/destructuring must have initializer
        checkVanillaForInitializers(variables);
        return parseForStatement(start, variables);
      }
    }

    if (peek(TokenType.SEMI_COLON)) {
      return parseForStatement(start, null);
    }

    ParseTree initializer = parseExpressionNoIn();
    if (peek(TokenType.IN) || peek(TokenType.EQUAL) || peekPredefinedString(PredefinedName.OF)) {
      initializer = transformLeftHandSideExpression(initializer);
      if (!initializer.isValidAssignmentTarget()) {
        reportError("invalid assignment target");
      }
    }

    if (peek(TokenType.IN) || peekPredefinedString(PredefinedName.OF)) {
      if (initializer.type != ParseTreeType.BINARY_OPERATOR
          && initializer.type != ParseTreeType.COMMA_EXPRESSION) {
        if (peek(TokenType.IN)) {
          return parseForInStatement(start, initializer);
        } else {
          // for {await}? ( _ of _ )
          if (awaited) {
            return parseForAwaitOfStatement(start, initializer);
          } else {
            return parseForOfStatement(start, initializer);
          }
        }
      }
    }

    return parseForStatement(start, initializer);
  }
111173
public static String parseExplainJSONCall(String statement)
    {
        Matcher matcher = ExplainJSONCallPreamble.matcher(statement);
        if ( ! matcher.lookingAt()) {
            return null;
        }
        return statement.substring(matcher.end());
    }
231495
private ParseTree parseContinueStatement() {
    SourcePosition start = getTreeStartLocation();
    eat(TokenType.CONTINUE);
    IdentifierToken name = null;
    if (!peekImplicitSemiColon()) {
      name = eatIdOpt();
    }
    eatPossibleImplicitSemiColon();
    return new ContinueStatementTree(getTreeLocation(start), name);
  }
1319689
@Override
    protected AstNode parseCreateStatement( DdlTokenStream tokens,
                                            AstNode parentNode ) throws ParsingException {
        assert tokens != null;
        assert parentNode != null;

        if (tokens.matches(STMT_CREATE_INDEX)) {
            return parseStatement(tokens, MySqlStatementStartPhrases.STMT_CREATE_INDEX, parentNode, TYPE_CREATE_INDEX_STATEMENT);
        } else if (tokens.matches(STMT_CREATE_UNIQUE_INDEX)) {
            return parseStatement(tokens,
                                  MySqlStatementStartPhrases.STMT_CREATE_UNIQUE_INDEX,
                                  parentNode,
                                  TYPE_CREATE_INDEX_STATEMENT);
        } else if (tokens.matches(STMT_CREATE_FUNCTION)) {
            return parseStatement(tokens,
                                  MySqlStatementStartPhrases.STMT_CREATE_FUNCTION,
                                  parentNode,
                                  TYPE_CREATE_FUNCTION_STATEMENT);
        } else if (tokens.matches(STMT_CREATE_PROCEDURE)) {
            return parseStatement(tokens,
                                  MySqlStatementStartPhrases.STMT_CREATE_PROCEDURE,
                                  parentNode,
                                  TYPE_CREATE_PROCEDURE_STATEMENT);
        } else if (tokens.matches(STMT_CREATE_SERVER)) {
            return parseStatement(tokens, MySqlStatementStartPhrases.STMT_CREATE_SERVER, parentNode, TYPE_CREATE_SERVER_STATEMENT);
        } else if (tokens.matches(STMT_CREATE_TRIGGER)) {
            return parseStatement(tokens,
                                  MySqlStatementStartPhrases.STMT_CREATE_TRIGGER,
                                  parentNode,
                                  TYPE_CREATE_TRIGGER_STATEMENT);
        } else if (tokens.matches(STMT_CREATE_EVENT)) {
            return parseStatement(tokens, MySqlStatementStartPhrases.STMT_CREATE_EVENT, parentNode, TYPE_CREATE_EVENT_STATEMENT);
        } else if (tokens.matches(STMT_CREATE_TABLESPACE)) {
            return parseStatement(tokens,
                                  MySqlStatementStartPhrases.STMT_CREATE_TABLESPACE,
                                  parentNode,
                                  TYPE_CREATE_TABLESPACE_STATEMENT);
        } else if (tokens.matches(STMT_CREATE_DEFINER)) {
            return parseStatement(tokens,
                                  MySqlStatementStartPhrases.STMT_CREATE_DEFINER,
                                  parentNode,
                                  TYPE_CREATE_DEFINER_STATEMENT);
        }

        return super.parseCreateStatement(tokens, parentNode);
    }
916905
function parseReturnStatement(node) {
        var argument = null;

        expectKeyword('return');

        if (!state.inFunctionBody) {
            tolerateError(Messages.IllegalReturn);
        }

        // 'return' followed by a space and an identifier is very common.
        if (source.charCodeAt(lastIndex) === 0x20) {
            if (isIdentifierStart(source.charCodeAt(lastIndex + 1))) {
                argument = parseExpression();
                consumeSemicolon();
                return node.finishReturnStatement(argument);
            }
        }

        if (hasLineTerminator) {
            // HACK
            return node.finishReturnStatement(null);
        }

        if (!match(';')) {
            if (!match('}') && lookahead.type !== Token.EOF) {
                argument = parseExpression();
            }
        }

        consumeSemicolon();

        return node.finishReturnStatement(argument);
    }
9870
void parseImportantComment() {
    state = State.SEARCHING_ANNOTATION;
    skipEOLs();

    JsDocToken token = next();

    ExtractionInfo info = extractMultilineComment(token, WhitespaceOption.PRESERVE, false, true);

    // An extra space is added by the @license annotation
    // so we need to add one here so they will be identical
    String license = " " + info.string;

    if (fileLevelJsDocBuilder != null) {
      fileLevelJsDocBuilder.addLicense(license);
    } else if (jsdocBuilder.shouldParseDocumentation()) {
      jsdocBuilder.recordBlockDescription(license);
    } else {
      jsdocBuilder.recordBlockDescription("");
    }
  }
287014
function parseDoWhileStatement() {
        var body, test, oldInIteration;

        expectKeyword('do');

        oldInIteration = inIteration;
        inIteration = true;

        body = parseStatement();

        inIteration = oldInIteration;

        expectKeyword('while');

        expect('(');

        test = parseExpression();

        expect(')');

        if (match(';')) {
            lex();
        }

        return {
            type: Syntax.DoWhileStatement,
            body: body,
            test: test
        };
    }
489338
def _parse_block(self, block, node):
        '''
        
        '''
        assert block[self.get_key()] == 'Block'

        if self.is_compact_ast:
            statements = block['statements']
        else:
            statements = block[self.get_children('children')]

        for statement in statements:
            node = self._parse_statement(statement, node)
        return node
1267998
private ParseTree parseWhileStatement() {
    SourcePosition start = getTreeStartLocation();
    eat(TokenType.WHILE);
    eat(TokenType.OPEN_PAREN);
    ParseTree condition = parseExpression();
    eat(TokenType.CLOSE_PAREN);
    ParseTree body = parseStatement();
    return new WhileStatementTree(getTreeLocation(start), condition, body);
  }
1154105
public void parse(final SelectStatement selectStatement) {
        Optional<LimitValue> offset = Optional.absent();
        Optional<LimitValue> rowCount = Optional.absent();
        while (true) {
            if (lexerEngine.skipIfEqual(PostgreSQLKeyword.LIMIT)) {
                rowCount = buildRowCount(selectStatement);
            } else if (lexerEngine.skipIfEqual(PostgreSQLKeyword.OFFSET)) {
                offset = buildOffset(selectStatement);
            } else {
                break;
            }
        }
        if (offset.isPresent() || rowCount.isPresent()) {
            setLimit(offset, rowCount, selectStatement);
        }
    }
261379
@Override
    protected AstNode parseAlterTableStatement( DdlTokenStream tokens,
                                                AstNode parentNode ) throws ParsingException {
        assert tokens != null;
        assert parentNode != null;
        // TODO:
        //
        /*
         * 

        ALTER [ONLINE | OFFLINE] [IGNORE] TABLE tbl_name
            alter_specification [, alter_specification] ...

            alter_specification:
                table_options
              | ADD [COLUMN] col_name column_definition
                    [FIRST | AFTER col_name ]
              | ADD [COLUMN] (col_name column_definition,...)
              | ADD {INDEX|KEY} [index_name]
                    [index_type] (index_col_name,...) [index_option] ...
              | ADD [CONSTRAINT [symbol]] PRIMARY KEY
                    [index_type] (index_col_name,...) [index_option] ...
              | ADD [CONSTRAINT [symbol]]
                    UNIQUE [INDEX|KEY] [index_name]
                    [index_type] (index_col_name,...) [index_option] ...
              | ADD FULLTEXT [INDEX|KEY] [index_name]
                    (index_col_name,...) [index_option] ...
              | ADD SPATIAL [INDEX|KEY] [index_name]
                    (index_col_name,...) [index_option] ...
              | ADD [CONSTRAINT [symbol]]
                    FOREIGN KEY [index_name] (index_col_name,...)
                    reference_definition
              | ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
              | CHANGE [COLUMN] old_col_name new_col_name column_definition
                    [FIRST|AFTER col_name]
              | MODIFY [COLUMN] col_name column_definition
                    [FIRST | AFTER col_name]
              | DROP [COLUMN] col_name
              | DROP PRIMARY KEY
              | DROP {INDEX|KEY} index_name
              | DROP FOREIGN KEY fk_symbol
              | DISABLE KEYS
              | ENABLE KEYS
              | RENAME [TO] new_tbl_name
              | ORDER BY col_name [, col_name] ...
              | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]
              | [DEFAULT] CHARACTER SET [=] charset_name [COLLATE [=] collation_name]
              | DISCARD TABLESPACE
              | IMPORT TABLESPACE
              | partition_options
              | ADD PARTITION (partition_definition)
              | DROP PARTITION partition_names
              | COALESCE PARTITION number
              | REORGANIZE PARTITION [partition_names INTO (partition_definitions)]
              | ANALYZE PARTITION partition_names
              | CHECK PARTITION partition_names
              | OPTIMIZE PARTITION partition_names
              | REBUILD PARTITION partition_names
              | REPAIR PARTITION partition_names
              | REMOVE PARTITIONING
         */

        return super.parseAlterTableStatement(tokens, parentNode);
    }
655761
@Override
    public AstNode handleUnknownToken( DdlTokenStream tokens,
                                       String tokenValue ) throws ParsingException {
        if (tokenValue.equals("/")) {
            return nodeFactory().node("backslashTerminator", getRootNode(), TYPE_BACKSLASH_TERMINATOR);
        }

        return null;
    }
928412
func (p *Parser) parseGrantOnStatement() (*GrantStatement, error) {
	stmt := &GrantStatement{}

	// Parse the name of the database.
	lit, err := p.ParseIdent()
	if err != nil {
		return nil, err
	}
	stmt.On = lit

	// Parse TO clause.
	tok, pos, lit := p.ScanIgnoreWhitespace()

	// Check for required TO token.
	if tok != TO {
		return nil, newParseError(tokstr(tok, lit), []string{"TO"}, pos)
	}

	// Parse the name of the user.
	lit, err = p.ParseIdent()
	if err != nil {
		return nil, err
	}
	stmt.User = lit

	return stmt, nil
}
1351593
protected void parseElse() {
        Node parent = peek();
        if (!(parent instanceof IfNode)) {
            return;
        }
        IfNode ifNode = (IfNode) pop();
        ElseNode elseNode = new ElseNode();
        ifNode.setElseNode(elseNode);
        push(elseNode);
        tokenizer.skipWhitespace();
    }
715521
function parseDoWhileStatement(node) {
        var body, test, oldInIteration;

        expectKeyword('do');

        oldInIteration = state.inIteration;
        state.inIteration = true;

        body = parseStatement();

        state.inIteration = oldInIteration;

        expectKeyword('while');

        expect('(');

        test = parseExpression();

        expect(')');

        if (match(';')) {
            lex();
        }

        return node.finishDoWhileStatement(body, test);
    }