diff --git a/sqlTranslate/.idea/workspace.xml b/sqlTranslate/.idea/workspace.xml
index 67d9ae73..00b09c29 100644
--- a/sqlTranslate/.idea/workspace.xml
+++ b/sqlTranslate/.idea/workspace.xml
@@ -4,16 +4,12 @@
-
-
-
-
-
-
-
+
+
-
-
+
+
+
@@ -45,13 +41,13 @@
- {
+ "keyToString": {
+ "RunOnceActivity.OpenProjectViewOnStart": "true",
+ "RunOnceActivity.ShowReadmeOnStart": "true",
+ "SHARE_PROJECT_CONFIGURATION_FILES": "true"
}
-}]]>
+}
@@ -113,7 +109,14 @@
1723106890550
-
+
+ 1723818930161
+
+
+
+ 1723818930161
+
+
@@ -129,6 +132,7 @@
-
+
+
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/Lexer/OracleLexer.java b/sqlTranslate/src/main/java/Lexer/OracleLexer.java
index 005e683b..2f441600 100644
--- a/sqlTranslate/src/main/java/Lexer/OracleLexer.java
+++ b/sqlTranslate/src/main/java/Lexer/OracleLexer.java
@@ -8,7 +8,8 @@ import java.util.regex.Pattern;
public class OracleLexer {
- public static final String[] keywords = {"SELECT", "FROM", "WHERE", "AND", "OR", "INSERT", "UPDATE", "DELETE", "now()"};
+ public static final String[] keywords = {"SELECT", "FROM", "WHERE", "AND", "OR", "INSERT", "UPDATE", "DELETE",
+ "now()"};
private static final Pattern TOKEN_PATTERN = Pattern.compile(
"(now\\(\\))|" + // now() function
"(\\b[A-Za-z_][A-Za-z0-9_]*\\b)|" + // Keywords and identifiers
diff --git a/sqlTranslate/src/main/java/Lexer/Token.java b/sqlTranslate/src/main/java/Lexer/Token.java
index b8319f0d..e4574aa3 100644
--- a/sqlTranslate/src/main/java/Lexer/Token.java
+++ b/sqlTranslate/src/main/java/Lexer/Token.java
@@ -5,7 +5,7 @@ public class Token {
KEYWORD, IDENTIFIER, NUMBER, OPERATOR, STRING, SYMBOL, EOF
}
- private final TokenType type;
+ private TokenType type;
private final String value;
public Token(TokenType type, String value) {
@@ -21,6 +21,10 @@ public class Token {
return value;
}
+ public boolean hasType(TokenType type) {
+ return this.type == type;
+ }
+
@Override
public String toString() {
return "Token{" +
diff --git a/sqlTranslate/src/main/java/Main.java b/sqlTranslate/src/main/java/Main.java
index b68a4f3d..b17fc7ce 100644
--- a/sqlTranslate/src/main/java/Main.java
+++ b/sqlTranslate/src/main/java/Main.java
@@ -5,7 +5,7 @@ import java.util.List;
public class Main {
public static void main(String[] args) {
- String sql = "SELECT now() FROM table WHERE name = 'John Doe';";
+ String sql = "SELECT adef FROM table WHERE name = 'John Doe';";
OracleLexer lexer = new OracleLexer(sql);
List tokens = lexer.tokenize();
diff --git a/sqlTranslate/src/main/java/Parser/ASTNode.java b/sqlTranslate/src/main/java/Parser/ASTNode.java
new file mode 100644
index 00000000..3df84539
--- /dev/null
+++ b/sqlTranslate/src/main/java/Parser/ASTNode.java
@@ -0,0 +1,145 @@
+package Parser;
+
+import Lexer.Token;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class ASTNode {
+ private Token token;
+ private ASTNode parent;
+ private List children = new ArrayList<>();
+
+ public ASTNode(Token token) {
+ this.token = token;
+ }
+
+ public ASTNode(ASTNode node) {
+ this.token = node.token;
+ this.parent = node.parent;
+ this.children = new ArrayList<>(node.children);
+ }
+
+ public Token getToken() {
+ return token;
+ }
+
+ public void setToken(Token token) {
+ this.token = token;
+ }
+
+ public ASTNode getParent() {
+ return parent;
+ }
+
+ public void setParent(ASTNode parent) {
+ this.parent = parent;
+ }
+
+ public List getChildren() {
+ return children;
+ }
+
+ public ASTNode getChildByName(String childName) {
+ for (ASTNode child : children) {
+ if (child.toString().equals(childName)) {
+ return child;
+ }
+ }
+
+ return null;
+ }
+
+ public List getChildrenByName(String childName) {
+ List nodes = new ArrayList<>();
+ for (ASTNode child : children) {
+ if (child.toString().equals(childName)) {
+ nodes.add(child);
+ }
+ }
+
+ return nodes;
+ }
+
+ /**
+ * 将对应名称的node更新为新的child
+ */
+ public void setChildrenByName(String childName, ASTNode child) {
+ for (int i = 0; i < this.children.size(); i++) {
+ if (this.children.get(i).getToken().getValue().contains(childName)) {
+ this.children.set(i, child);
+ break;
+ }
+ }
+ }
+
+ public void addChild(ASTNode childNode) {
+ childNode.setParent(this);
+ children.add(childNode);
+ }
+
+ public void replaceChild(ASTNode oldChild, ASTNode newChild) {
+ newChild.setParent(this);
+ children.set(children.indexOf(oldChild), newChild);
+ }
+
+ // add a child node at position index of children
+ public void addChild(int index, ASTNode childNode) {
+ childNode.setParent(this);
+ children.add(index, childNode);
+ }
+
+ public void removeChild(ASTNode childNode) {
+ children.remove(childNode);
+ }
+
+ public String toQueryString() {
+ StringBuilder queryString = new StringBuilder();
+ visit(this, queryString, false);
+ return queryString.toString();
+ }
+
+ private void visit(ASTNode node, StringBuilder queryString, boolean hasPrespace) {
+ if (node == null) {
+ return;
+ }
+ if (node.getToken().hasType(Token.TokenType.KEYWORD)) {
+ String value = node.getToken().getValue();
+ if (value == null || value.trim().isEmpty()) {
+ return;
+ }
+ boolean preSpace = true;
+ if (queryString.length() == 0) {
+ preSpace = false;
+ } else if (queryString.charAt(queryString.length() - 1) == '(') {
+ preSpace = false;
+ } else if (Arrays.asList(",", ";", ")").contains(value)) {
+ preSpace = false;
+ } else if (!hasPrespace) {
+ // If the token does not have pre space, we should not add, either.
+ preSpace = false;
+ }
+ if (preSpace) {
+ queryString.append(" ");
+ }
+ queryString.append(value);
+ } else {
+ for (int i = 0; i < node.getChildren().size(); i++) {
+ ASTNode childNode = node.getChildren().get(i);
+ if (i == 0) {
+ visit(childNode, queryString, hasPrespace || childNode.getToken().hasPreSpace());
+ } else {
+ visit(childNode, queryString, childNode.getToken().hasPreSpace());
+ }
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return token.getValue();
+ }
+
+
+}