From 86b3eee86376dc78d499332e636dbad679ade4f4 Mon Sep 17 00:00:00 2001 From: XudongXie Date: Sat, 14 Sep 2024 15:26:01 +0800 Subject: [PATCH] add IF ELSIF --- sqlTranslate/.idea/workspace.xml | 20 ++-- sqlTranslate/src/main/java/Main.java | 18 +++- .../java/Parser/AST/IFELSIF/ELSENode.java | 4 + ...IFActionNode.java => ELSIFActionNode.java} | 12 ++- .../AST/IFELSIF/ELSIFConditionNode.java | 4 + .../java/Parser/AST/IFELSIF/EndIFNode.java | 4 + .../java/Parser/AST/IFELSIF/IFActionNode.java | 4 + .../Parser/AST/IFELSIF/IFConditionNode.java | 4 + .../src/main/java/Parser/OracleParser.java | 91 ++++++++++++++++++- 9 files changed, 141 insertions(+), 20 deletions(-) rename sqlTranslate/src/main/java/Parser/AST/IFELSIF/{ElSIFActionNode.java => ELSIFActionNode.java} (57%) diff --git a/sqlTranslate/.idea/workspace.xml b/sqlTranslate/.idea/workspace.xml index a6e79decc..82028ad94 100644 --- a/sqlTranslate/.idea/workspace.xml +++ b/sqlTranslate/.idea/workspace.xml @@ -6,10 +6,10 @@ - + - + @@ -111,13 +111,6 @@ diff --git a/sqlTranslate/src/main/java/Main.java b/sqlTranslate/src/main/java/Main.java index 5b072bf97..9a4cf148d 100644 --- a/sqlTranslate/src/main/java/Main.java +++ b/sqlTranslate/src/main/java/Main.java @@ -32,12 +32,22 @@ public class Main { // ");"; // String sql = "ALTER TABLE employees ADD email VARCHAR2(100) Check (email != '12813@163.com');"; // String sql = "CASE WHEN column2 > 0 THEN 'Positive' ELSE 'Non-positive' END"; - String sql = "CREATE OR REPLACE VIEW emp_dept_info AS SELECT e.first_name, e.last_name, d.department_name FROM employees e JOIN departments d Using e.department_id = d.department_id;"; +// String sql = "CREATE OR REPLACE VIEW emp_dept_info AS SELECT e.first_name, e.last_name, d.department_name FROM employees e JOIN departments d Using e.department_id = d.department_id;"; + String sql = "IF v_salary >= 100000 THEN\n" + + " v_bonus := v_salary * 0.1;\n" + + " ELSIF v_salary >= 50000 THEN\n" + + " v_bonus := v_salary * 0.08;\n" + + " ELSIF v_salary >= 30000 THEN\n" + + " v_bonus := v_salary * 0.05;\n" + + " ELSE\n" + + " v_bonus := v_salary * 0.03;\n" + + " END IF;"; OracleLexer lexer = new OracleLexer(sql); lexer.printTokens(); - OracleParser parser = new OracleParser(lexer); - ASTNode root = parser.parse(); -// ASTNode root = parser.parseCaseWhen(lexer.getTokens()); +// OracleParser parser = new OracleParser(lexer); +// ASTNode root = parser.parse(); + ASTNode root = OracleParser.parseIFELSE(lexer.getTokens()); +// ASTNode root = OracleParser.parseCaseWhen(lexer.getTokens()); // ASTNode root = OracleParser.parseJoin(lexer.getTokens()); System.out.println(root.toQueryString()); System.out.println(root.getASTString()); diff --git a/sqlTranslate/src/main/java/Parser/AST/IFELSIF/ELSENode.java b/sqlTranslate/src/main/java/Parser/AST/IFELSIF/ELSENode.java index c114d7ed0..dfb142007 100644 --- a/sqlTranslate/src/main/java/Parser/AST/IFELSIF/ELSENode.java +++ b/sqlTranslate/src/main/java/Parser/AST/IFELSIF/ELSENode.java @@ -3,19 +3,23 @@ package Parser.AST.IFELSIF; import Lexer.Token; import Parser.AST.ASTNode; +import java.util.ArrayList; import java.util.List; public class ELSENode extends ASTNode { public ELSENode() { super(); + setTokens(new ArrayList<>()); } public ELSENode(ASTNode node) { super(node); + setTokens(new ArrayList<>()); } public ELSENode(List tokens) { super(tokens); + setTokens(new ArrayList<>()); } @Override diff --git a/sqlTranslate/src/main/java/Parser/AST/IFELSIF/ElSIFActionNode.java b/sqlTranslate/src/main/java/Parser/AST/IFELSIF/ELSIFActionNode.java similarity index 57% rename from sqlTranslate/src/main/java/Parser/AST/IFELSIF/ElSIFActionNode.java rename to sqlTranslate/src/main/java/Parser/AST/IFELSIF/ELSIFActionNode.java index 20d72bc1a..2c88cb197 100644 --- a/sqlTranslate/src/main/java/Parser/AST/IFELSIF/ElSIFActionNode.java +++ b/sqlTranslate/src/main/java/Parser/AST/IFELSIF/ELSIFActionNode.java @@ -3,19 +3,23 @@ package Parser.AST.IFELSIF; import Lexer.Token; import Parser.AST.ASTNode; +import java.util.ArrayList; import java.util.List; -public class ElSIFActionNode extends ASTNode { - public ElSIFActionNode() { +public class ELSIFActionNode extends ASTNode { + public ELSIFActionNode() { super(); + setTokens(new ArrayList<>()); } - public ElSIFActionNode(ASTNode node) { + public ELSIFActionNode(ASTNode node) { super(node); + setTokens(new ArrayList<>()); } - public ElSIFActionNode(List tokens) { + public ELSIFActionNode(List tokens) { super(tokens); + setTokens(new ArrayList<>()); } @Override diff --git a/sqlTranslate/src/main/java/Parser/AST/IFELSIF/ELSIFConditionNode.java b/sqlTranslate/src/main/java/Parser/AST/IFELSIF/ELSIFConditionNode.java index 9b9e2c760..943791454 100644 --- a/sqlTranslate/src/main/java/Parser/AST/IFELSIF/ELSIFConditionNode.java +++ b/sqlTranslate/src/main/java/Parser/AST/IFELSIF/ELSIFConditionNode.java @@ -3,19 +3,23 @@ package Parser.AST.IFELSIF; import Lexer.Token; import Parser.AST.ASTNode; +import java.util.ArrayList; import java.util.List; public class ELSIFConditionNode extends ASTNode { public ELSIFConditionNode() { super(); + setTokens(new ArrayList<>()); } public ELSIFConditionNode(ASTNode node) { super(node); + setTokens(new ArrayList<>()); } public ELSIFConditionNode(List tokens) { super(tokens); + setTokens(new ArrayList<>()); } @Override diff --git a/sqlTranslate/src/main/java/Parser/AST/IFELSIF/EndIFNode.java b/sqlTranslate/src/main/java/Parser/AST/IFELSIF/EndIFNode.java index 00d84681c..b6aedf59a 100644 --- a/sqlTranslate/src/main/java/Parser/AST/IFELSIF/EndIFNode.java +++ b/sqlTranslate/src/main/java/Parser/AST/IFELSIF/EndIFNode.java @@ -3,19 +3,23 @@ package Parser.AST.IFELSIF; import Lexer.Token; import Parser.AST.ASTNode; +import java.util.ArrayList; import java.util.List; public class EndIFNode extends ASTNode { public EndIFNode() { super(); + setTokens(new ArrayList<>()); } public EndIFNode (ASTNode node) { super(node); + setTokens(new ArrayList<>()); } public EndIFNode (List tokens) { super(tokens); + setTokens(new ArrayList<>()); } @Override diff --git a/sqlTranslate/src/main/java/Parser/AST/IFELSIF/IFActionNode.java b/sqlTranslate/src/main/java/Parser/AST/IFELSIF/IFActionNode.java index 8b8df2111..5736d1470 100644 --- a/sqlTranslate/src/main/java/Parser/AST/IFELSIF/IFActionNode.java +++ b/sqlTranslate/src/main/java/Parser/AST/IFELSIF/IFActionNode.java @@ -3,19 +3,23 @@ package Parser.AST.IFELSIF; import Lexer.Token; import Parser.AST.ASTNode; +import java.util.ArrayList; import java.util.List; public class IFActionNode extends ASTNode { public IFActionNode() { super(); + setTokens(new ArrayList<>()); } public IFActionNode(ASTNode node) { super(node); + setTokens(new ArrayList<>()); } public IFActionNode(List tokens) { super(tokens); + setTokens(new ArrayList<>()); } @Override diff --git a/sqlTranslate/src/main/java/Parser/AST/IFELSIF/IFConditionNode.java b/sqlTranslate/src/main/java/Parser/AST/IFELSIF/IFConditionNode.java index 5fe23cc1d..462983042 100644 --- a/sqlTranslate/src/main/java/Parser/AST/IFELSIF/IFConditionNode.java +++ b/sqlTranslate/src/main/java/Parser/AST/IFELSIF/IFConditionNode.java @@ -3,19 +3,23 @@ package Parser.AST.IFELSIF; import Lexer.Token; import Parser.AST.ASTNode; +import java.util.ArrayList; import java.util.List; public class IFConditionNode extends ASTNode { public IFConditionNode() { super(); + setTokens(new ArrayList<>()); } public IFConditionNode(ASTNode node) { super(node); + setTokens(new ArrayList<>()); } public IFConditionNode(List tokens) { super(tokens); + setTokens(new ArrayList<>()); } @Override diff --git a/sqlTranslate/src/main/java/Parser/OracleParser.java b/sqlTranslate/src/main/java/Parser/OracleParser.java index a378246ab..d94c5f5ad 100644 --- a/sqlTranslate/src/main/java/Parser/OracleParser.java +++ b/sqlTranslate/src/main/java/Parser/OracleParser.java @@ -18,7 +18,7 @@ import Parser.AST.Drop.DropEndNode; import Parser.AST.Drop.DropObjNameNode; import Parser.AST.Drop.DropNode; import Parser.AST.Drop.DropOptionNode; -import Parser.AST.IFELSIF.IFConditionNode; +import Parser.AST.IFELSIF.*; import Parser.AST.Insert.InsertDataNode; import Parser.AST.Insert.InsertEndNode; import Parser.AST.Insert.InsertNode; @@ -554,9 +554,96 @@ public class OracleParser { */ public static ASTNode parseIFELSE(List parseTokens) { ASTNode root = new IFConditionNode(); + ASTNode currentNode = root; for (int i = 0; i < parseTokens.size(); i++) { - // TODO: implement + // match IF condition + if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("IF")) { + for (int j = i; j < parseTokens.size(); j++) { + if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("THEN")) { + i = j - 1; + break; + } + root.addToken(parseTokens.get(j)); + } + } + // match IF action + else if (currentNode instanceof IFConditionNode && parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("THEN")) { + ASTNode childNode = new IFActionNode(); + for (int j = i; j < parseTokens.size(); j++) { + childNode.addToken(parseTokens.get(j)); + if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) { + i = j; + break; + } + } + currentNode.addChild(childNode); + currentNode = childNode; + } + // match ELSIF condition + else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("ELSIF")) { + ASTNode childNode = new ELSIFConditionNode(); + for (int j = i; j < parseTokens.size(); j++) { + if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("THEN")) { + i = j - 1; + break; + } + childNode.addToken(parseTokens.get(j)); + } + currentNode.addChild(childNode); + currentNode = childNode; + } + // match ELSIF action + else if (currentNode instanceof ELSIFConditionNode && parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("THEN")) { + ASTNode childNode = new ELSIFActionNode(); + for (int j = i; j < parseTokens.size(); j++) { + childNode.addToken(parseTokens.get(j)); + if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) { + i = j; + break; + } + } + currentNode.addChild(childNode); + currentNode = childNode; + } + // match ELSE + else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("ELSE")) { + ASTNode childNode = new ELSENode(); + for (int j = i; j < parseTokens.size(); j++) { + childNode.addToken(parseTokens.get(j)); + if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) { + i = j; + break; + } + } + currentNode.addChild(childNode); + currentNode = childNode; + } + //match end if; + else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END")) { + ASTNode childNode = new EndIFNode(); + for (int j = i; j < parseTokens.size(); j++) { + childNode.addToken(parseTokens.get(j)); + if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) { + i = j; + break; + } + } + currentNode.addChild(childNode); + currentNode = childNode; + } + else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) { + break; + } + else { + try { + throw new ParseFailedException("Parse failed!--" + parseTokens.get(i).getValue()); + } + catch (ParseFailedException e) { + e.printStackTrace(); + } + } } + return root; }