asterixdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From amo...@apache.org
Subject [1/2] asterixdb git commit: Add Maven Plugin for Grammar Extension
Date Sat, 23 Jul 2016 20:15:17 GMT
Repository: asterixdb
Updated Branches:
  refs/heads/master 1958541a4 -> 806f7d264


http://git-wip-us.apache.org/repos/asf/asterixdb/blob/806f7d26/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpdateStatement.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpdateStatement.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpdateStatement.java
index da74549..8ccc694 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpdateStatement.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpdateStatement.java
@@ -28,7 +28,7 @@ import org.apache.asterix.lang.common.expression.VariableExpr;
 import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
 import org.apache.commons.lang3.ObjectUtils;
 
-public class UpdateStatement extends Statement {
+public class UpdateStatement implements Statement {
 
     private VariableExpr vars;
     private Expression target;
@@ -44,7 +44,7 @@ public class UpdateStatement extends Statement {
 
     @Override
     public byte getKind() {
-        return Statement.UPDATE;
+        return Statement.Kind.UPDATE;
     }
 
     public VariableExpr getVariableExpr() {

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/806f7d26/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpsertStatement.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpsertStatement.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpsertStatement.java
index f562927..1fb1de2 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpsertStatement.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpsertStatement.java
@@ -29,12 +29,12 @@ public class UpsertStatement extends InsertStatement {
 
     @Override
     public byte getKind() {
-        return Statement.UPSERT;
+        return Statement.Kind.UPSERT;
     }
 
     @Override
     public int hashCode() {
-        return super.hashCode() + Statement.UPSERT;
+        return super.hashCode() + Statement.Kind.UPSERT;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/806f7d26/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/WriteStatement.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/WriteStatement.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/WriteStatement.java
index 1c49b9d..a755a54 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/WriteStatement.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/WriteStatement.java
@@ -23,7 +23,7 @@ import org.apache.asterix.lang.common.base.Statement;
 import org.apache.asterix.lang.common.struct.Identifier;
 import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
 
-public class WriteStatement extends Statement {
+public class WriteStatement implements Statement {
 
     private final Identifier ncName;
     private final String fileName;
@@ -49,7 +49,7 @@ public class WriteStatement extends Statement {
 
     @Override
     public byte getKind() {
-        return Statement.WRITE;
+        return Statement.Kind.WRITE;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/806f7d26/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/pom.xml b/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/pom.xml
new file mode 100644
index 0000000..d3e4a41
--- /dev/null
+++ b/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/pom.xml
@@ -0,0 +1,102 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.asterix</groupId>
+        <artifactId>asterix-maven-plugins</artifactId>
+        <version>0.8.9-SNAPSHOT</version>
+    </parent>
+    <artifactId>asterix-grammar-extension-maven-plugin</artifactId>
+    <packaging>maven-plugin</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-plugin-api</artifactId>
+            <version>3.2.5</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-core</artifactId>
+            <version>3.2.5</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-compat</artifactId>
+            <version>3.2.5</version>
+        </dependency>
+    <!-- dependencies to annotations -->
+        <dependency>
+            <groupId>org.apache.maven.plugin-tools</groupId>
+            <artifactId>maven-plugin-annotations</artifactId>
+            <version>3.4</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.asterix</groupId>
+            <artifactId>asterix-external-data</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.plugin-testing</groupId>
+            <artifactId>maven-plugin-testing-harness</artifactId>
+            <version>3.3.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.asterix</groupId>
+            <artifactId>asterix-lang-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>javacc-maven-plugin</artifactId>
+                <version>2.6</version>
+                <executions>
+                    <execution>
+                        <id>javacc</id>
+                        <goals>
+                            <goal>javacc</goal>
+                        </goals>
+                        <phase>verify</phase>
+                        <configuration>
+                            <isStatic>false</isStatic>
+                            <javaUnicodeEscape>true</javaUnicodeEscape>
+                            <sourceDirectory>${project.build.directory}/generated-sources/lang</sourceDirectory>
+                            <outputDirectory>${project.build.directory}/generated-sources/javacc</outputDirectory>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>javacc-jjdoc</id>
+                        <goals>
+                            <goal>jjdoc</goal>
+                        </goals>
+                        <phase>verify</phase>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-plugin-plugin</artifactId>
+                    <version>3.3</version>
+                    <configuration>
+                        <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
+                    </configuration>
+                    <executions>
+                        <execution>
+                            <id>mojo-descriptor</id>
+                            <phase>process-classes</phase>
+                            <goals>
+                                <goal>descriptor</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/806f7d26/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/main/java/org/apache/asterix/extension/grammar/GrammarExtensionMojo.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/main/java/org/apache/asterix/extension/grammar/GrammarExtensionMojo.java b/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/main/java/org/apache/asterix/extension/grammar/GrammarExtensionMojo.java
new file mode 100644
index 0000000..8f263f7
--- /dev/null
+++ b/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/main/java/org/apache/asterix/extension/grammar/GrammarExtensionMojo.java
@@ -0,0 +1,841 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.extension.grammar;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.asterix.external.input.record.CharArrayRecord;
+import org.apache.asterix.external.util.ExternalDataConstants;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hyracks.algebricks.common.utils.Pair;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+
+/**
+ * a Mojo for creating a grammar extension
+ */
+@Mojo(name = "grammarix")
+public class GrammarExtensionMojo extends AbstractMojo {
+
+    private static final String PARSER_BEGIN = "PARSER_BEGIN";
+    private static final String PARSER_END = "PARSER_END";
+    private static final char OPEN_BRACE = '{';
+    private static final char CLOSE_BRACE = '}';
+    private static final char OPEN_ANGULAR = '<';
+    private static final char CLOSE_ANGULAR = '>';
+    private static final char OPEN_PAREN = '(';
+    private static final char CLOSE_PAREN = ')';
+    private static final char SEMICOLON = ';';
+    private static final List<Character> SIG_SPECIAL_CHARS =
+            Arrays.asList(new Character[] { '(', ')', ':', '<', '>', ';', '.' });
+    private static final String KWCLASS = "class";
+    private static final String KWIMPORT = "import";
+    private static final String KWPACKAGE = "package";
+    private static final String NEWPRODUCTION = "@new";
+    private static final String MERGEPRODUCTION = "@merge";
+    private static final String OVERRIDEPRODUCTION = "@override";
+    private static final String BEFORE = "before:";
+    private static final String AFTER = "after:";
+    private static final List<String> KEYWORDS =
+            Arrays.asList(new String[] { KWCLASS, KWIMPORT, KWPACKAGE, PARSER_BEGIN, PARSER_END });
+    private static final List<String> EXTENSIONKEYWORDS =
+            Arrays.asList(new String[] { KWIMPORT, NEWPRODUCTION, OVERRIDEPRODUCTION, MERGEPRODUCTION });
+    private static final String REGEX_WS_DOT_SEMICOLON = "\\s|[.]|[;]";
+    private static final String REGEX_WS_PAREN = "\\s|[(]|[)]";
+    private static final String OPTIONS = "options";
+    private CharArrayRecord record = new CharArrayRecord();
+    private Position position = new Position();
+    private Map<String, Pair<String, String>> extensibles = new HashMap<>();
+    private Map<String, String[]> mergeElements = new HashMap<>();
+    private List<Pair<String, String>> finals = new ArrayList<>();
+    private List<List<String>> imports = new ArrayList<>();
+    private String baseClassName;
+    private String baseClassDef;
+    private String optionsBlock;
+    private boolean read = false;
+
+    @Parameter(property = "grammarix.base")
+    private String base;
+
+    @Parameter(property = "grammarix.extension")
+    private String extension;
+
+    @Parameter(property = "grammarix.output")
+    private String output;
+
+    @Parameter(property = "grammarix.packageName")
+    private String packageName;
+
+    @Parameter(property = "grammarix.parserClassName")
+    private String parserClassName;
+    private String lastIdentifier;
+
+    @Override
+    public void execute() throws MojoExecutionException {
+        getLog().info("Current dir: " + System.getProperty("user.dir"));
+        getLog().info("base: " + base);
+        getLog().info("extension: " + extension);
+        processBase();
+        processExtension();
+        generateOutput();
+    }
+
+    private void generateOutput() throws MojoExecutionException {
+        File outputFile = prepareOutputFile();
+        try (BufferedWriter writer = Files.newBufferedWriter(outputFile.toPath(), StandardCharsets.UTF_8)) {
+            // Options
+            if (optionsBlock != null) {
+                writer.write(OPTIONS);
+                writer.write(optionsBlock);
+            }
+            writer.newLine();
+
+            // Parser Begin
+            writer.write(PARSER_BEGIN);
+            writer.write(OPEN_PAREN);
+            writer.write(parserClassName);
+            writer.write(CLOSE_PAREN);
+            writer.newLine();
+            writer.newLine();
+
+            // Package
+            writer.write(KWPACKAGE);
+            writer.write(" ");
+            writer.write(packageName);
+            writer.write(SEMICOLON);
+            writer.newLine();
+            writer.newLine();
+
+            // Imports
+            List<String> importList = new ArrayList<>();
+            for (List<String> importTokens : imports) {
+                importList.add(importToString(importTokens));
+            }
+            Collections.sort(importList);
+            for (String importStatement : importList) {
+                writer.write(importStatement);
+                writer.newLine();
+            }
+
+            writer.newLine();
+
+            // Class definition
+            writer.write(baseClassDef.replaceAll(baseClassName, parserClassName));
+            writer.newLine();
+
+            // Parser End
+            writer.write(PARSER_END);
+            writer.write(OPEN_PAREN);
+            writer.write(parserClassName);
+            writer.write(CLOSE_PAREN);
+            writer.newLine();
+            writer.newLine();
+
+            // Extinsibles
+            for (Entry<String, Pair<String, String>> entry : extensibles.entrySet()) {
+                writer.newLine();
+                String signature = entry.getKey();
+                if (mergeElements.containsKey(signature)) {
+                    writer.write("// Merged Non-terminal");
+                    writer.newLine();
+                }
+                writer.write(extensibleSignatureToOutput(signature));
+                writer.newLine();
+                if (mergeElements.containsKey(signature)) {
+                    merge(writer, entry.getValue(), mergeElements.get(signature));
+                } else {
+                    writer.write(entry.getValue().first);
+                    writer.newLine();
+                    if (entry.getValue().second != null) {
+                        writer.write(entry.getValue().second);
+                        writer.newLine();
+                    }
+                }
+            }
+
+            for (Pair<String, String> element : finals) {
+                writer.write(toOutput(element.first));
+                writer.newLine();
+                writer.write(element.second);
+                writer.newLine();
+            }
+
+        } catch (Exception e) {
+            getLog().error(e);
+            throw new MojoExecutionException(e.getMessage(), e);
+        }
+    }
+
+    private String extensibleSignatureToOutput(String signature) {
+        StringBuilder aString = new StringBuilder();
+        String[] tokens = signature.split(" ");
+        aString.append(tokens[0]);
+        for (int i = 1; i < tokens.length; i++) {
+            if (tokens[i - 1].charAt(tokens[i - 1].length() - 1) == CLOSE_PAREN
+                    || (!SIG_SPECIAL_CHARS.contains(tokens[i].charAt(0))
+                            && !SIG_SPECIAL_CHARS.contains(tokens[i - 1].charAt(tokens[i - 1].length() - 1)))) {
+                aString.append(" ");
+            }
+            aString.append(tokens[i]);
+        }
+        return aString.toString();
+    }
+
+    private String toOutput(String signature) {
+        if (signature.indexOf(OPEN_ANGULAR) == 0) {
+            // a final
+            StringBuilder aString = new StringBuilder();
+            aString.append(signature.substring(0, signature.indexOf(CLOSE_ANGULAR) + 1));
+            aString.append('\n');
+            aString.append(signature.substring(signature.indexOf(CLOSE_ANGULAR) + 1));
+            return aString.toString();
+        } else {
+            return signature;
+        }
+    }
+
+    private void merge(BufferedWriter writer, Pair<String, String> baseBlocks, String[] extensions)
+            throws IOException, MojoExecutionException {
+        String errorMessage = "Merged base node doesn't conform to expected mergable node structure";
+        int block1Open = baseBlocks.first.indexOf(OPEN_BRACE);
+        int block1Close = baseBlocks.first.lastIndexOf(CLOSE_BRACE);
+        // first block
+        writer.write(OPEN_BRACE);
+        if (extensions[0] != null) {
+            writer.write(extensions[0]);
+        }
+        writer.write(baseBlocks.first.substring(block1Open + 1, block1Close));
+        if (extensions[1] != null) {
+            writer.write(extensions[1]);
+        }
+        writer.write(CLOSE_BRACE);
+        writer.newLine();
+        // second block
+        writer.write(OPEN_BRACE);
+        writer.newLine();
+        writer.write("  ");
+        writer.write(OPEN_PAREN);
+        if (extensions[2] != null) {
+            writer.write(extensions[2]);
+        }
+        String innerBlock2String = null;
+        if (baseBlocks.second != null) {
+            BufferedReader blockReader = stringToReader(baseBlocks.second);
+            Position blockPosition = new Position();
+            blockPosition.index = 0;
+            blockPosition.line = blockReader.readLine();
+            while (blockPosition.line != null && blockPosition.line.trim().length() == 0) {
+                blockPosition.line = blockReader.readLine();
+            }
+            int block2Open = blockPosition.line.indexOf(OPEN_BRACE);
+            if (block2Open < 0) {
+                throw new MojoExecutionException(errorMessage);
+            }
+            blockPosition.line = blockPosition.line.substring(block2Open + 1);
+            while (blockPosition.line != null && blockPosition.line.trim().length() == 0) {
+                blockPosition.line = blockReader.readLine();
+            }
+            int innerBlock1Open = blockPosition.line.indexOf(OPEN_PAREN);
+            if (innerBlock1Open < 0) {
+                throw new MojoExecutionException(errorMessage);
+            }
+            blockPosition.index = innerBlock1Open;
+            readBlock(blockReader, OPEN_PAREN, CLOSE_PAREN, blockPosition);
+            String innerBlock1String = record.toString();
+            writer.newLine();
+            writer.write("    ");
+            writer.write(innerBlock1String
+                    .substring(innerBlock1String.indexOf(OPEN_PAREN) + 1, innerBlock1String.lastIndexOf(CLOSE_PAREN))
+                    .trim());
+            writer.newLine();
+            record.reset();
+            // read second inner block
+            blockPosition.line = blockReader.readLine();
+            while (blockPosition.line != null && blockPosition.line.trim().length() == 0) {
+                blockPosition.line = blockReader.readLine();
+            }
+            int innerBlock2Open = blockPosition.line.indexOf(OPEN_BRACE);
+            if (innerBlock2Open < 0) {
+                throw new MojoExecutionException(errorMessage);
+            }
+            blockPosition.index = innerBlock2Open;
+            readBlock(blockReader, OPEN_BRACE, CLOSE_BRACE, blockPosition);
+            innerBlock2String = record.toString();
+            record.reset();
+        }
+        if (extensions[3] != null) {
+            writer.write(extensions[3]);
+        }
+        writer.newLine();
+        writer.write("  ");
+        writer.write(CLOSE_PAREN);
+        writer.newLine();
+        writer.write("  ");
+        writer.write(OPEN_BRACE);
+        if (extensions[4] != null) {
+            writer.write(extensions[4]);
+        }
+        if (innerBlock2String != null) {
+            writer.newLine();
+            writer.write("  ");
+            writer.write(innerBlock2String
+                    .substring(innerBlock2String.indexOf(OPEN_BRACE) + 1, innerBlock2String.lastIndexOf(CLOSE_BRACE))
+                    .trim());
+            writer.newLine();
+        }
+        if (extensions[5] != null) {
+            writer.write(extensions[5]);
+        }
+        // Close inner second block
+        writer.write("  ");
+        writer.write(CLOSE_BRACE);
+        writer.newLine();
+        // Close second block
+        writer.write(CLOSE_BRACE);
+        writer.newLine();
+    }
+
+    class Position {
+        String line;
+        int index;
+    }
+
+    private void readBlock(BufferedReader reader, char start, char end) throws IOException, MojoExecutionException {
+        readBlock(reader, start, end, position);
+    }
+
+    private void readBlock(BufferedReader reader, char start, char end, Position position)
+            throws IOException, MojoExecutionException {
+        record.reset();
+        char[] chars = position.line.toCharArray();
+        if (chars[position.index] != start) {
+            throw new MojoExecutionException(
+                    "attempt to read a non terminal that doesn't start with a brace. @Line: " + position.line);
+        }
+        boolean prevCharEscape = false;
+        boolean inString = false;
+        boolean hasFinished = false;
+        int depth = 0;
+        int bufferPosn = position.index;
+        int bufferLength = chars.length;
+        do {
+            int startPosn = bufferPosn;
+            if (bufferPosn >= bufferLength) {
+                startPosn = bufferPosn = 0;
+                record.append("\n".toCharArray());
+                position.line = reader.readLine();
+                chars = position.line.toCharArray();
+                bufferLength = chars.length;
+            }
+            for (; bufferPosn < bufferLength; ++bufferPosn) {
+                if (inString) {
+                    // we are in a string, we only care about the string end
+                    if (chars[bufferPosn] == ExternalDataConstants.QUOTE && !prevCharEscape) {
+                        inString = false;
+                    }
+                    if (prevCharEscape) {
+                        prevCharEscape = false;
+                    } else {
+                        prevCharEscape = chars[bufferPosn] == ExternalDataConstants.ESCAPE;
+                    }
+                } else {
+                    if (chars[bufferPosn] == ExternalDataConstants.QUOTE) {
+                        inString = true;
+                    } else if (chars[bufferPosn] == start) {
+                        depth += 1;
+                    } else if (chars[bufferPosn] == end) {
+                        depth -= 1;
+                        if (depth == 0) {
+                            hasFinished = true;
+                            bufferPosn++;
+                            position.index = bufferPosn;
+                            break;
+                        }
+                    }
+                }
+            }
+            int appendLength = bufferPosn - startPosn;
+            if (appendLength > 0) {
+                record.append(chars, startPosn, appendLength);
+            }
+        } while (!hasFinished);
+        record.endRecord();
+    }
+
+    private void processBase() throws MojoExecutionException {
+        try (BufferedReader reader = Files.newBufferedReader(Paths.get(base), StandardCharsets.UTF_8)) {
+            StringBuilder identifier = new StringBuilder();
+            while ((position.line = reader.readLine()) != null) {
+                if (position.line.trim().startsWith("//")) {
+                    // skip comments
+                    continue;
+                }
+                String[] tokens = position.line.split(REGEX_WS_PAREN);
+                position.index = 0;
+                int openBraceIndex = position.line.indexOf(OPEN_BRACE);
+                int openAngularIndex = position.line.trim().indexOf(OPEN_ANGULAR);
+                if (tokens.length > 0 && identifier.length() == 0 && KEYWORDS.contains(tokens[0])) {
+                    handleSpecialToken(tokens[0], reader);
+                } else if (openBraceIndex >= 0 && openAngularIndex < 0) {
+                    String beforeBrace = position.line.substring(0, openBraceIndex);
+                    if (beforeBrace.trim().length() > 0) {
+                        identifier.append(beforeBrace);
+                    } else if (identifier.length() == 0) {
+                        identifier.append(lastIdentifier);
+                    }
+                    position.index = openBraceIndex;
+                    readBlock(reader, OPEN_BRACE, CLOSE_BRACE);
+                    // if next non-white space character is an open brace, then  we need to append
+                    addExtensibleProduction(identifier);
+                } else if (openAngularIndex == 0) {
+                    position.index = position.line.indexOf(OPEN_ANGULAR);
+                    readFinalProduction(identifier, reader);
+                    addFinalProduction(identifier);
+                } else if (identifier.length() > 0 || position.line.trim().length() > 0) {
+                    identifier.append(position.line);
+                    identifier.append('\n');
+                }
+            }
+        } catch (Exception e) {
+            getLog().error(e);
+            throw new MojoExecutionException(e.getMessage(), e);
+        }
+    }
+
+    private void handleSpecialToken(String token, BufferedReader reader) throws IOException, MojoExecutionException {
+        switch (token) {
+            case PARSER_BEGIN:
+                // parser begin. duh!
+                parserBegin(reader);
+                break;
+            case PARSER_END:
+                // parser end
+                parserEnd(reader);
+                break;
+            case KWCLASS:
+                // class declaration
+                handleClassDeclaration(reader);
+                break;
+            case KWPACKAGE:
+                // package declaration
+                skipPackageDeclaration(reader);
+                break;
+            case KWIMPORT:
+                handleImport(reader);
+                // import statement
+                break;
+            default:
+                break;
+        }
+    }
+
+    private void addFinalProduction(StringBuilder identifier) {
+        String sig = toSignature(identifier.toString());
+        finals.add(new Pair<String, String>(sig, record.toString()));
+        record.reset();
+        identifier.setLength(0);
+        lastIdentifier = null;
+    }
+
+    private void handleImport(BufferedReader reader) throws IOException {
+        // will not work on two imports on a single line
+        ArrayList<String> importList = new ArrayList<>();
+        String[] tokens = position.line.split(REGEX_WS_DOT_SEMICOLON);
+        importList.addAll(Arrays.asList(tokens));
+        while (position.line.indexOf(SEMICOLON) < 0) {
+            position.line = reader.readLine();
+            tokens = position.line.split(REGEX_WS_DOT_SEMICOLON);
+            importList.addAll(Arrays.asList(tokens));
+        }
+        imports.add(importList);
+    }
+
+    private String importToString(List<String> importTokens) {
+        return "import " + StringUtils.join(importTokens.subList(1, importTokens.size()), '.') + ";";
+    }
+
+    private void skipPackageDeclaration(BufferedReader reader) throws IOException {
+        while (position.line.indexOf(SEMICOLON) < 0) {
+            position.line = reader.readLine();
+        }
+    }
+
+    private void handleClassDeclaration(BufferedReader reader) throws IOException, MojoExecutionException {
+        StringBuilder parserDef = new StringBuilder();
+        int classPosition = position.line.indexOf(KWCLASS);
+        int startIndex = position.line.indexOf(OPEN_BRACE, classPosition);
+        if (startIndex < 0) {
+            position.line = position.line.substring(classPosition).replace(baseClassName, parserClassName);
+            while (startIndex < 0) {
+                parserDef.append(position.line);
+                parserDef.append('\n');
+                position.line = reader.readLine();
+                startIndex = position.line.indexOf(OPEN_BRACE);
+            }
+            parserDef.append(position.line, 0, startIndex);
+        } else {
+            parserDef.append(position.line, classPosition, startIndex);
+        }
+        position.index = startIndex;
+        readBlock(reader, OPEN_BRACE, CLOSE_BRACE);
+        String classBody = record.toString();
+        parserDef.append(classBody);
+        parserDef.append('\n');
+        baseClassDef = parserDef.toString();
+    }
+
+    private void parserEnd(BufferedReader reader) throws IOException {
+        int endIndex = position.line.indexOf(CLOSE_PAREN, position.index);
+        while (endIndex < 0) {
+            position.line = reader.readLine();
+            endIndex = position.line.indexOf(CLOSE_PAREN);
+        }
+        position.index = endIndex;
+    }
+
+    private void parserBegin(BufferedReader reader) throws IOException {
+        StringBuilder aStringBuilder = new StringBuilder();
+        int startIndex = position.line.indexOf(OPEN_PAREN, position.index);
+        while (startIndex < 0) {
+            position.line = reader.readLine();
+            startIndex = position.line.indexOf(OPEN_PAREN);
+        }
+        int endIndex = position.line.indexOf(CLOSE_PAREN, startIndex);
+        if (endIndex < 0) {
+            // start and end on different lines
+            position.line = position.line.substring(startIndex + 1);
+            while (endIndex < 0) {
+                aStringBuilder.append(position.line);
+                position.line = reader.readLine();
+                endIndex = position.line.indexOf(CLOSE_PAREN);
+            }
+            aStringBuilder.append(position.line, 0, endIndex);
+        } else {
+            // start and end on the same line
+            aStringBuilder.append(position.line.substring(startIndex + 1, endIndex));
+        }
+        position.index = endIndex;
+        baseClassName = aStringBuilder.toString().trim();
+    }
+
+    private void readFinalProduction(StringBuilder identifier, BufferedReader reader)
+            throws IOException, MojoExecutionException {
+        int blockStart = position.line.indexOf(OPEN_BRACE);
+        if (blockStart < 0) {
+            position.line = position.line.substring(position.index);
+            while (blockStart < 0) {
+                identifier.append(position.line);
+                identifier.append('\n');
+                position.line = reader.readLine();
+                blockStart = position.line.indexOf(OPEN_BRACE);
+            }
+            identifier.append(position.line.substring(0, blockStart));
+        } else {
+            identifier.append(position.line.substring(position.index, blockStart));
+        }
+        position.index = blockStart;
+        readBlock(reader, OPEN_BRACE, CLOSE_BRACE);
+    }
+
+    private void addExtensibleProduction(StringBuilder identifier) {
+        if (identifier.toString().trim().equals(OPTIONS)) {
+            optionsBlock = record.toString();
+        } else {
+            String sig = toSignature(identifier.toString());
+            Pair<String, String> pair = extensibles.get(sig);
+            if (pair == null) {
+                pair = new Pair<>(record.toString(), null);
+                extensibles.put(sig, pair);
+            } else {
+                pair.second = record.toString();
+            }
+            lastIdentifier = identifier.toString();
+        }
+        record.reset();
+        identifier.setLength(0);
+    }
+
+    private void processExtension() throws MojoExecutionException {
+        try (BufferedReader reader = Files.newBufferedReader(Paths.get(extension), StandardCharsets.UTF_8)) {
+            StringBuilder identifier = new StringBuilder();
+            String nextOperation = OVERRIDEPRODUCTION;
+            while (read || (position.line = reader.readLine()) != null) {
+                read = false;
+                if (position.line.trim().startsWith("//")) {
+                    // skip comments
+                    continue;
+                }
+                String[] tokens = position.line.split(REGEX_WS_PAREN);
+                position.index = 0;
+                int openBraceIndex = position.line.indexOf(OPEN_BRACE);
+                int openAngularIndex = position.line.trim().indexOf(OPEN_ANGULAR);
+                if (tokens.length > 0 && identifier.length() == 0 && EXTENSIONKEYWORDS.contains(tokens[0])) {
+                    switch (tokens[0]) {
+                        case KWIMPORT:
+                            handleImport(reader);
+                            // import statement
+                            break;
+                        case NEWPRODUCTION:
+                            nextOperation = NEWPRODUCTION;
+                            break;
+                        case MERGEPRODUCTION:
+                            nextOperation = MERGEPRODUCTION;
+                            break;
+                        case OVERRIDEPRODUCTION:
+                            nextOperation = OVERRIDEPRODUCTION;
+                            break;
+                        default:
+                            break;
+                    }
+                } else if (openBraceIndex >= 0 && openAngularIndex < 0) {
+                    String beforeBrace = position.line.substring(0, openBraceIndex);
+                    if (beforeBrace.trim().length() > 0) {
+                        identifier.append(beforeBrace);
+                    } else if (identifier.length() == 0) {
+                        identifier.append(lastIdentifier);
+                    }
+                    position.index = openBraceIndex;
+                    switch (nextOperation) {
+                        case NEWPRODUCTION:
+                            handleNew(identifier, reader);
+                            break;
+                        case OVERRIDEPRODUCTION:
+                            handleOverride(identifier, reader);
+                            break;
+                        case MERGEPRODUCTION:
+                            handleMerge(identifier, reader);
+                            break;
+                        default:
+                            throw new MojoExecutionException("Malformed extention file");
+                    }
+                    nextOperation = NEWPRODUCTION;
+                } else if (openAngularIndex == 0) {
+                    if (nextOperation != NEWPRODUCTION) {
+                        throw new MojoExecutionException("Can only add new REGEX production kind");
+                    }
+                    position.index = position.line.indexOf(OPEN_ANGULAR);
+                    readFinalProduction(identifier, reader);
+                    addFinalProduction(identifier);
+                } else if (identifier.length() > 0 || position.line.trim().length() > 0) {
+                    identifier.append(position.line);
+                    identifier.append('\n');
+                }
+            }
+        } catch (Exception e) {
+            getLog().error(e);
+            throw new MojoExecutionException(e.getMessage(), e);
+        }
+    }
+
+    private void handleOverride(StringBuilder identifier, BufferedReader reader)
+            throws MojoExecutionException, IOException {
+        readBlock(reader, OPEN_BRACE, CLOSE_BRACE);
+        Pair<String, String> pair = new Pair<>(record.toString(), null);
+        String sig = toSignature(identifier.toString());
+        extensibles.put(sig, pair);
+        record.reset();
+        identifier.setLength(0);
+        // will read ahead of loop cycle
+        read = true;
+        position.index = 0;
+        position.line = reader.readLine();
+        while (position.line != null && position.line.trim().length() == 0) {
+            position.line = reader.readLine();
+        }
+        int openBraceIndex = position.line.indexOf(OPEN_BRACE);
+        if (openBraceIndex > -1) {
+            // consume
+            read = false;
+            position.index = openBraceIndex;
+            readBlock(reader, OPEN_BRACE, CLOSE_BRACE);
+            pair.second = record.toString();
+            record.reset();
+        }
+    }
+
+    private void handleNew(StringBuilder identifier, BufferedReader reader) throws MojoExecutionException, IOException {
+        String sig = toSignature(identifier.toString());
+        if (extensibles.containsKey(sig)) {
+            throw new MojoExecutionException(identifier.toString() + " already exists in base grammar");
+        }
+        handleOverride(identifier, reader);
+    }
+
+    private void handleMerge(StringBuilder identifier, BufferedReader reader)
+            throws MojoExecutionException, IOException {
+        String sig = toSignature(identifier.toString());
+        if (!extensibles.containsKey(sig)) {
+            throw new MojoExecutionException(identifier.toString() + " doesn't exist in base grammar");
+        }
+        String[] amendments = new String[6];
+        mergeElements.put(sig, amendments);
+        // we don't need the identifier anymore
+        identifier.setLength(0);
+        readBlock(reader, OPEN_BRACE, CLOSE_BRACE);
+        String block = record.toString();
+        extractBeforeAndAfter(block, amendments, 0, 1);
+        record.reset();
+        position.index = 0;
+        position.line = reader.readLine();
+        while (position.line != null && position.line.trim().length() == 0) {
+            position.line = reader.readLine();
+        }
+        int openBraceIndex = position.line.indexOf(OPEN_BRACE);
+        if (openBraceIndex > -1) {
+            position.index = openBraceIndex;
+            readBlock(reader, OPEN_BRACE, CLOSE_BRACE);
+        } else {
+            throw new MojoExecutionException("merge element doesn't have a second block");
+        }
+        block = record.toString();
+        BufferedReader blockReader = stringToReader(block);
+        String line = blockReader.readLine();
+        while (line != null && line.indexOf(OPEN_BRACE) < 0) {
+            line = blockReader.readLine();
+        }
+        if (line == null) {
+            throw new MojoExecutionException("merge element doesn't have a correct second block");
+        }
+        line = line.substring(line.indexOf(OPEN_BRACE) + 1);
+        while (line != null && line.trim().length() == 0) {
+            line = blockReader.readLine();
+        }
+        if (line == null) {
+            throw new MojoExecutionException("merge element doesn't have a correct second block");
+        }
+        int openParenIndex = line.indexOf(OPEN_PAREN);
+        if (openParenIndex < 0) {
+            throw new MojoExecutionException("second block in merge element doesn't have a correct () block");
+        }
+        Position blockPosition = new Position();
+        blockPosition.line = line;
+        blockPosition.index = openParenIndex;
+        readBlock(blockReader, OPEN_PAREN, CLOSE_PAREN, blockPosition);
+        extractBeforeAndAfter(record.toString(), amendments, 2, 3);
+        record.reset();
+        // process third block:
+        blockPosition.index = 0;
+        blockPosition.line = blockReader.readLine();
+        while (blockPosition.line != null && blockPosition.line.trim().length() == 0) {
+            blockPosition.line = blockReader.readLine();
+        }
+        openBraceIndex = blockPosition.line.indexOf(OPEN_BRACE);
+        if (openBraceIndex > -1) {
+            blockPosition.index = openBraceIndex;
+            readBlock(blockReader, OPEN_BRACE, CLOSE_BRACE, blockPosition);
+        } else {
+            throw new MojoExecutionException("merge element doesn't have a second block");
+        }
+        extractBeforeAndAfter(record.toString(), amendments, 4, 5);
+        record.reset();
+    }
+
+    private void extractBeforeAndAfter(String block, String[] amendments, int beforeIndex, int afterIndex) {
+        int before = block.indexOf(BEFORE);
+        int after = block.indexOf(AFTER);
+        if (before >= 0) {
+            // before exists
+            amendments[beforeIndex] =
+                    block.substring(before + BEFORE.length(), (after >= 0) ? after : block.length() - 1);
+            if (amendments[beforeIndex].trim().length() == 0) {
+                amendments[beforeIndex] = null;
+            }
+        }
+        if (after >= 0) {
+            // after exists
+            amendments[afterIndex] = block.substring(after + AFTER.length(), block.length() - 1);
+            if (amendments[afterIndex].trim().length() == 0) {
+                amendments[afterIndex] = null;
+            }
+        }
+    }
+
+    private BufferedReader stringToReader(String aString) {
+        InputStream is = new ByteArrayInputStream(aString.getBytes(StandardCharsets.UTF_8));
+        return new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
+    }
+
+    private File prepareOutputFile() throws MojoExecutionException {
+        // write output
+        File outputFile = new File(output);
+        if (outputFile.exists() && (!outputFile.delete())) {
+            throw new MojoExecutionException("Unable to delete file " + output);
+        }
+        try {
+            outputFile.getParentFile().mkdirs();
+            if (!outputFile.createNewFile()) {
+                throw new MojoExecutionException("Unable to create file " + output);
+            }
+        } catch (IOException ioe) {
+            throw new MojoExecutionException("Unable to create file " + output, ioe);
+        }
+        return outputFile;
+    }
+
+    private String toSignature(String identifier) {
+        StringBuilder aString = new StringBuilder();
+        char[] chars = identifier.toCharArray();
+        int index = 0;
+        boolean first = true;
+        while (index < chars.length) {
+            int begin;
+            while (Character.isWhitespace(chars[index])) {
+                index++;
+                if (index == chars.length) {
+                    break;
+                }
+            }
+            if (index == chars.length) {
+                break;
+            }
+            begin = index;
+            while (!Character.isWhitespace(chars[index])) {
+                index++;
+                if ((index == chars.length) || SIG_SPECIAL_CHARS.contains(chars[index - 1])
+                        || ((index < chars.length - 1) && SIG_SPECIAL_CHARS.contains(chars[index]))) {
+                    break;
+                }
+            }
+            if (!first) {
+                aString.append(' ');
+            }
+            aString.append(new String(chars, begin, index - begin));
+            first = false;
+        }
+        return aString.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/806f7d26/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/java/org/apache/asterix/extension/grammar/GrammarExtensionMojoTest.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/java/org/apache/asterix/extension/grammar/GrammarExtensionMojoTest.java b/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/java/org/apache/asterix/extension/grammar/GrammarExtensionMojoTest.java
new file mode 100644
index 0000000..386c4f3
--- /dev/null
+++ b/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/java/org/apache/asterix/extension/grammar/GrammarExtensionMojoTest.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.extension.grammar;
+
+import java.io.File;
+
+import org.apache.maven.plugin.testing.AbstractMojoTestCase;
+import org.junit.Test;
+
+public class GrammarExtensionMojoTest extends AbstractMojoTestCase {
+
+    /**
+     * @throws Exception
+     */
+    @Test
+    public void testMojoGoal() throws Exception {
+        File testPom =
+                new File(getBasedir(), "src" + File.separator + "test" + File.separator + "resources" + File.separator
+                        + "unit" + File.separator + "basic-test" + File.separator + "basic-test-plugin-config.xml");
+        GrammarExtensionMojo mojo = (GrammarExtensionMojo) lookupMojo("grammarix", testPom);
+        assertNotNull(mojo);
+        mojo.execute();
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/806f7d26/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/java/org/apache/asterix/lang/extension/EchoStatement.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/java/org/apache/asterix/lang/extension/EchoStatement.java b/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/java/org/apache/asterix/lang/extension/EchoStatement.java
new file mode 100644
index 0000000..7c6e882
--- /dev/null
+++ b/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/java/org/apache/asterix/lang/extension/EchoStatement.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.lang.extension;
+
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.lang.common.base.Statement;
+import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+
+public class EchoStatement implements Statement {
+
+    private final String arg;
+
+    public EchoStatement(String arg) {
+        this.arg = arg;
+    }
+
+    @Override
+    public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws AsterixException {
+        return null;
+    }
+
+    @Override
+    public byte getKind() {
+        return -1;
+    }
+
+    public String getArg() {
+        return arg;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/806f7d26/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/resources/lang/extension.jj
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/resources/lang/extension.jj b/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/resources/lang/extension.jj
new file mode 100644
index 0000000..2106e4d
--- /dev/null
+++ b/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/resources/lang/extension.jj
@@ -0,0 +1,45 @@
+import org.apache.asterix.lang.extension.EchoStatement;
+
+// Merging of non-terminals can only be done on non-terminals which conform to the following structure.
+// Content will simply be prepended or appended to the base blocks.
+// Note: refrain from using the strings "before:" and "after:" in the merge areas as that will break the merge.
+// As a workaround, you can always override
+@merge
+Statement SingleStatement() throws ParseException:
+{
+  // merge area 1
+  before:
+  after:
+}
+{
+  (
+    // merge area 2
+    before:
+    after:    | stmt = EchoStatement())
+  {
+    // merge area 3
+  }
+}
+
+// The default
+// Adding a new node. if a node exists, it will throw an exception.
+@new
+Statement EchoStatement() throws ParseException:
+{
+  String arg = null;
+}
+{
+  <ECHO> arg = Identifier()
+    {
+      return new EchoStatement(arg);
+    }
+}
+
+<DEFAULT,IN_DBL_BRACE>
+TOKEN :
+{
+    <ECHO : "echo">
+}
+
+// Overriding a non-terminal. if exists in base, it will be overriden, otherwise, it will be added
+// @override

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/806f7d26/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/resources/unit/basic-test/basic-test-plugin-config.xml
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/resources/unit/basic-test/basic-test-plugin-config.xml b/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/resources/unit/basic-test/basic-test-plugin-config.xml
new file mode 100644
index 0000000..b8253bb
--- /dev/null
+++ b/asterixdb/asterix-maven-plugins/asterix-grammar-extension-maven-plugin/src/test/resources/unit/basic-test/basic-test-plugin-config.xml
@@ -0,0 +1,80 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.asterix</groupId>
+        <artifactId>asterix-opt</artifactId>
+        <version>0.1-SNAPSHOT</version>
+    </parent>
+    <groupId>org.apache.extension</groupId>
+    <artifactId>grammar-extension</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.asterix</groupId>
+            <artifactId>asterix-external-data</artifactId>
+            <version>0.8.9-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>com.couchbase.client</groupId>
+            <artifactId>core-io</artifactId>
+            <version>1.2.8</version>
+        </dependency>
+        <dependency>
+            <groupId>io.reactivex</groupId>
+            <artifactId>rxjava</artifactId>
+            <version>1.0.15</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.asterix</groupId>
+                <artifactId>asterix-grammar-extension-maven-plugin</artifactId>
+                <version>0.8.9-SNAPSHOT</version>
+                <configuration>
+                    <base>../../asterix-lang-aql/src/main/javacc/AQL.jj</base>
+                    <extension>src/test/resources/lang/extension.jj</extension>
+                    <output>target/generated-sources/lang/grammar.jj</output>
+                    <parserClassName>ExtendedParser</parserClassName>
+                    <packageName>org.apache.asterix.lang.extension.parser</packageName>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>grammarix</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <pluginManagement>
+            <plugins>
+            <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+                <plugin>
+                    <groupId>org.eclipse.m2e</groupId>
+                    <artifactId>lifecycle-mapping</artifactId>
+                    <version>1.0.0</version>
+                    <configuration>
+                        <lifecycleMappingMetadata>
+                            <pluginExecutions>
+                                <pluginExecution>
+                                    <pluginExecutionFilter>
+                                        <groupId>org.apache.asterix</groupId>
+                                        <artifactId>asterix-grammar-extension-maven-plugin</artifactId>
+                                        <versionRange>[0.8.9-SNAPSHOT,)</versionRange>
+                                        <goals>
+                                            <goal>grammarix</goal>
+                                        </goals>
+                                    </pluginExecutionFilter>
+                                    <action>
+                                        <ignore></ignore>
+                                    </action>
+                                </pluginExecution>
+                            </pluginExecutions>
+                        </lifecycleMappingMetadata>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/806f7d26/asterixdb/asterix-maven-plugins/pom.xml
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-maven-plugins/pom.xml b/asterixdb/asterix-maven-plugins/pom.xml
index 2623c64..9207abe 100644
--- a/asterixdb/asterix-maven-plugins/pom.xml
+++ b/asterixdb/asterix-maven-plugins/pom.xml
@@ -56,5 +56,6 @@
     <module>record-manager-generator-maven-plugin</module>
     <module>asterix-evaluator-generator-maven-plugin</module>
     <module>asterix-test-datagenerator-maven-plugin</module>
+    <module>asterix-grammar-extension-maven-plugin</module>
   </modules>
 </project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/806f7d26/asterixdb/asterix-tools/src/main/java/org/apache/asterix/tools/translator/ADGenDmlTranslator.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-tools/src/main/java/org/apache/asterix/tools/translator/ADGenDmlTranslator.java b/asterixdb/asterix-tools/src/main/java/org/apache/asterix/tools/translator/ADGenDmlTranslator.java
index a5b8f48..a525b1b 100644
--- a/asterixdb/asterix-tools/src/main/java/org/apache/asterix/tools/translator/ADGenDmlTranslator.java
+++ b/asterixdb/asterix-tools/src/main/java/org/apache/asterix/tools/translator/ADGenDmlTranslator.java
@@ -53,7 +53,7 @@ public class ADGenDmlTranslator extends AbstractLangTranslator {
         typeDataGenMap = new HashMap<TypeSignature, TypeDataGen>();
 
         for (Statement stmt : aqlStatements) {
-            if (stmt.getKind() == Statement.TYPE_DECL) {
+            if (stmt.getKind() == Statement.Kind.TYPE_DECL) {
                 TypeDecl td = (TypeDecl) stmt;
                 String typeDataverse =
                         td.getDataverseName() == null ? defaultDataverse : td.getDataverseName().getValue();
@@ -73,7 +73,7 @@ public class ADGenDmlTranslator extends AbstractLangTranslator {
 
     private String getDefaultDataverse() {
         for (Statement stmt : aqlStatements) {
-            if (stmt.getKind() == Statement.DATAVERSE_DECL) {
+            if (stmt.getKind() == Statement.Kind.DATAVERSE_DECL) {
                 return ((DataverseDecl) stmt).getDataverseName().getValue();
             }
         }


Mime
View raw message