All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.weaverplatform.sp4rql.model.expression.ExpressionFactory Maven / Gradle / Ivy

package com.weaverplatform.sp4rql.model.expression;

import com.weaverplatform.sp4rql.error.ParseException;
import com.weaverplatform.sp4rql.model.scope.ScopeExists;
import com.weaverplatform.sp4rql.model.scope.Sp4rqlScope;
import com.weaverplatform.sp4rql.model.token.LiteralToken;
import com.weaverplatform.sp4rql.model.token.TokenFactory;
import com.weaverplatform.sp4rql.model.token.VariableToken;
import com.weaverplatform.sp4rql.parser.QueryUnitListener;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.RuleNode;
import org.antlr.v4.runtime.tree.TerminalNode;
import sp4rql.Sp4rql11Parser;

import java.util.ArrayList;

public class ExpressionFactory {

  private QueryUnitListener mainListener;
  private TokenFactory tokenFactory;

  public ExpressionFactory(QueryUnitListener listener, TokenFactory tokenFactory) {
    this.mainListener = listener;
    this.tokenFactory = tokenFactory;
  }

  public ExpressionArgument getExpression(Sp4rql11Parser.BuiltInCallContext ctx) {
    if(ctx.aggregate() != null) {
      return getExpression(ctx.aggregate());
    } else if(ctx.substringExpression() != null) {
      return getExpression(ctx.substringExpression());
    } else if(ctx.strReplaceExpression() != null) {
      return getExpression(ctx.strReplaceExpression());
    } else if(ctx.regexExpression() != null) {
      return getExpression(ctx.regexExpression());
    } else if(ctx.existsFunc() != null) {
      Sp4rqlScope currentScope = mainListener.getCurrentScope();
      ScopeExists scope = new ScopeExists(currentScope);
      currentScope.addExpressionScope(scope);
      mainListener.setCurrentScope(scope);
      ExpressionUnit expression = new ExpressionUnit(Operator.EXISTS);
      expression.addArgument(scope);
      return expression;
    } else if(ctx.notExistsFunc() != null) {
      Sp4rqlScope currentScope = mainListener.getCurrentScope();
      ScopeExists scope = new ScopeExists(currentScope);
      currentScope.addExpressionScope(scope);
      mainListener.setCurrentScope(scope);
      ExpressionUnit expression = new ExpressionUnit(Operator.NOT_EXISTS);
      expression.addArgument(scope);
      return expression;
    } else {
      String operator = ctx.children.get(0).getText();
      ExpressionUnit expression = new ExpressionUnit(operator);

      for(ParseTree item : ctx.children) {
        if(item instanceof Sp4rql11Parser.ExpressionContext) {
          expression.addArgument(getExpression((Sp4rql11Parser.ExpressionContext) item));
        } else if(item instanceof Sp4rql11Parser.VarContext) {
          VariableToken variable = tokenFactory.getToken((Sp4rql11Parser.VarContext) item);
          expression.addArgument(variable);
        } else if(item instanceof Sp4rql11Parser.ExpressionListContext) {
          Sp4rql11Parser.ExpressionListContext list = (Sp4rql11Parser.ExpressionListContext) item;
          for(Sp4rql11Parser.ExpressionContext argument : list.expression()) {
            expression.addArgument(getExpression(argument));
          }
        } else {
          // Skip everything apart from VarContext, ExpressionContext and ExpressionListContext, see grammar rule 121
        }
      }
      return expression;
    }
  }

  public ExpressionArgument getExpression(Sp4rql11Parser.AggregateContext ctx) {
    ExpressionUnit expression = new ExpressionUnit(ctx.children.get(0).getText());
    if(ctx.DISTINCT() != null) {
      expression.setDistinct();
    }
    if(ctx.ASTERISK() != null) {
      expression.setWildcard();
    }
    if(ctx.expression() != null) {
      expression.addArgument(getExpression(ctx.expression()));
    }
    // For the GROUP_CONCAT the second argument
    if(ctx.string() != null) {
      expression.addArgument(tokenFactory.getToken(ctx.string()));
    }
    return expression;
  }

  public ExpressionArgument getExpression(Sp4rql11Parser.SubstringExpressionContext ctx) {
    ExpressionUnit expression = new ExpressionUnit(Operator.SUBSTR);
    for(Sp4rql11Parser.ExpressionContext exp : ctx.expression()) {
      expression.addArgument(getExpression(exp));
    }
    return expression;
  }

  public ExpressionArgument getExpression(Sp4rql11Parser.StrReplaceExpressionContext ctx) {
    ExpressionUnit expression = new ExpressionUnit(Operator.REPLACE);
    for(Sp4rql11Parser.ExpressionContext exp : ctx.expression()) {
      expression.addArgument(getExpression(exp));
    }
    return expression;
  }

  public ExpressionArgument getExpression(Sp4rql11Parser.RegexExpressionContext ctx) {
    ExpressionUnit expression = new ExpressionUnit(Operator.REGEX);
    for(Sp4rql11Parser.ExpressionContext exp : ctx.expression()) {
      expression.addArgument(getExpression(exp));
    }
    return expression;
  }

  public ExpressionArgument getExpression(Sp4rql11Parser.ExpressionContext ctx) {
    return getExpression(ctx.conditionalOrExpression());
  }

  public ExpressionArgument getExpression(Sp4rql11Parser.ConditionalOrExpressionContext ctx) {
    if(ctx.children.size() == 1) {
      return getExpression(ctx.conditionalAndExpression().get(0));
    }
    ExpressionUnit expression = new ExpressionUnit(Operator.OR);
    for(ParseTree child : ctx.children) {
      if(child instanceof Sp4rql11Parser.ConditionalAndExpressionContext) {
        expression.addArgument(getExpression((Sp4rql11Parser.ConditionalAndExpressionContext) child));
      }
    }
    return expression;
  }

  public ExpressionArgument getExpression(Sp4rql11Parser.ConditionalAndExpressionContext ctx) {
    if(ctx.children.size() == 1) {
      return getExpression(ctx.valueLogical().get(0).relationalExpression());
    }
    ExpressionUnit expression = new ExpressionUnit(Operator.AND);
    for(ParseTree child : ctx.children) {
      if(child instanceof Sp4rql11Parser.ValueLogicalContext) {
        expression.addArgument(getExpression(((Sp4rql11Parser.ValueLogicalContext) child).relationalExpression()));
      }
    }
    return expression;
  }

  public ExpressionArgument getExpression(Sp4rql11Parser.ConstraintContext ctx) {
    if(ctx.brackettedExpression() != null) {
      return getExpression(ctx.brackettedExpression().expression());
    } else if(ctx.builtInCall() != null) {
      return getExpression(ctx.builtInCall());
    } else if(ctx.functionCall() != null) {
      return getExpression(ctx.functionCall());
    }
    throw new ParseException("Could not parse the constraint");
  }

  public ExpressionUnit getExpression(Sp4rql11Parser.FunctionCallContext ctx) {
    String operator = tokenFactory.getToken(ctx.iri()).toString();
    ExpressionUnit expression = new ExpressionUnit(operator);
    if(ctx.argList() != null) {
      if(ctx.argList().DISTINCT() != null) {
        expression.isDistinct();
      }
      for (Sp4rql11Parser.ExpressionContext argument : ctx.argList().expression()) {
        expression.addArgument(getExpression(argument));
      }
    }
    return expression;
  }

  public ExpressionArgument getExpression(Sp4rql11Parser.RelationalExpressionContext ctx) {
    if(ctx.children.size() == 1) {
      return getExpression(ctx.numericExpression().get(0));
    }
    ExpressionUnit expression;
    if(ctx.EQUAL() != null) {
      expression = new ExpressionUnit(Operator.EQUAL);
    } else if(ctx.NOT_EQUAL() != null) {
      expression = new ExpressionUnit(Operator.NOT_EQUAL);
    } else if(ctx.LESS() != null) {
      expression = new ExpressionUnit(Operator.LESS);
    } else if(ctx.GREATER() != null) {
      expression = new ExpressionUnit(Operator.GREATER);
    } else if(ctx.LESS_EQUAL() != null) {
      expression = new ExpressionUnit(Operator.LESS_EQUAL);
    } else if(ctx.GREATER_EQUAL() != null) {
      expression = new ExpressionUnit(Operator.GREATER_EQUAL);
    } else if(ctx.GREATER_EQUAL() != null) {
      expression = new ExpressionUnit(Operator.GREATER_EQUAL);
    } else if(ctx.IN() != null && ctx.NOT() == null) {
      expression = new ExpressionUnit(Operator.IN);
    } else if(ctx.NOT() != null && ctx.IN() != null) {
      expression = new ExpressionUnit(Operator.NOT_IN);
    } else {
      throw new RuntimeException("Could not parse relationalExpression");
    }
    expression.addArgument(getExpression(ctx.numericExpression(0)));
    if(ctx.expressionList() != null) {
      for(Sp4rql11Parser.ExpressionContext item : ctx.expressionList().expression()) {
        expression.addArgument(getExpression(item));
      }
    } else {
      expression.addArgument(getExpression(ctx.numericExpression(1)));
    }
    return expression;
  }

  public ExpressionArgument getExpression(Sp4rql11Parser.NumericExpressionContext ctx) {
    return getExpression(ctx.additiveExpression());
  }

  public ExpressionArgument getExpression(Sp4rql11Parser.AdditiveExpressionContext ctx) {
    if(ctx.children.size() == 1) {
      return getExpression(ctx.multiplicativeExpression().get(0));
    }

    ExpressionUnit currentExpression = new ExpressionUnit(Operator.PLUS);
    ArrayList stack = new ArrayList<>();


    ExpressionArgument previous = null;
    ExpressionArgument numberOrMultiplication = null;
    String lastOperator = null;
    for(ParseTree child : ctx.children) {
      if(child instanceof RuleNode) {
        if(previous != null) {
          currentExpression.addArgument(previous);
        }
        if(!(child instanceof Sp4rql11Parser.UnaryExpressionContext)) {
          if(!stack.isEmpty()) {
            currentExpression = stack.get(0);
            stack.clear();
          }
        }
      }

      if(child instanceof Sp4rql11Parser.MultiplicativeExpressionContext) {
        numberOrMultiplication = getExpression((Sp4rql11Parser.MultiplicativeExpressionContext) child);
        if("-".equals(lastOperator)) {
          ExpressionUnit negated = new ExpressionUnit(Operator.MINUS);
          negated.addArgument(numberOrMultiplication);
          numberOrMultiplication = negated;
        }
        currentExpression.addArgument(numberOrMultiplication);
      } else if(child instanceof Sp4rql11Parser.NumericLiteralPositiveContext) {
        previous = tokenFactory.getToken((Sp4rql11Parser.NumericLiteralPositiveContext) child);
      } else if(child instanceof Sp4rql11Parser.NumericLiteralNegativeContext) {
        previous = tokenFactory.getToken((Sp4rql11Parser.NumericLiteralNegativeContext) child);
      } else if(child instanceof Sp4rql11Parser.UnaryExpressionContext) {
        previous = getExpression((Sp4rql11Parser.UnaryExpressionContext) child);
      } else if(child instanceof TerminalNode) {
        lastOperator = child.getText();
        if("*".equals(lastOperator)) {
          ExpressionUnit multiply = new ExpressionUnit("*");
          multiply.addArgument(previous);
          previous = null;
          currentExpression.addArgument(multiply);
          stack.add(currentExpression);
          currentExpression = multiply;
        }
        if("/".equals(lastOperator)) {
          ExpressionUnit divide = new ExpressionUnit("/");
          divide.addArgument(previous);
          previous = null;
          currentExpression.addArgument(divide);
          stack.add(currentExpression);
          currentExpression = divide;
        }
      }
    }
    if(previous != null) {
      currentExpression.addArgument(previous);
    }
    if(!stack.isEmpty()) {
      currentExpression = stack.get(0);
      stack.clear();
    }
    return currentExpression;
  }
  
  public ExpressionArgument getExpression(Sp4rql11Parser.MultiplicativeExpressionContext ctx) {
    if(ctx.children.size() == 1) {
      return getExpression(ctx.unaryExpression().get(0));
    }

    ExpressionArgument first = null;
    ExpressionUnit previous = null;
    for(ParseTree child : ctx.children) {
      if(child instanceof Sp4rql11Parser.UnaryExpressionContext) {
        ExpressionArgument argument = getExpression((Sp4rql11Parser.UnaryExpressionContext) child);
        if(previous == null) {
          first = argument;
        } else {
          previous.addArgument(argument);
        }
      } else {
        ExpressionUnit expression;
        if(Operator.MULTIPLY.equals(child.getText())) {
          expression = new ExpressionUnit(Operator.MULTIPLY);
        } else if(Operator.DIVIDE.equals(child.getText())) {
          expression = new ExpressionUnit(Operator.DIVIDE);
        } else {
          throw new ParseException("Could not parse multiplicativeExpression");
        }
        if(first != null) {
          expression.addArgument(first);
          first = null;
        } else {
          expression.addArgument(previous);
        }
        previous = expression;
      }
    }
    return previous;
  }
  
  public ExpressionArgument getExpression(Sp4rql11Parser.UnaryExpressionContext ctx) {
    if(ctx.NOT_SIGN() != null) {
      ExpressionUnit expression = new ExpressionUnit(Operator.NOT);
      expression.addArgument(getExpression(ctx.primaryExpression()));
      return expression;
    } else if(ctx.PLUS() != null) {
      ExpressionUnit expression = new ExpressionUnit(Operator.PLUS);
      expression.addArgument(getExpression(ctx.primaryExpression()));
      return expression;
    } else if(ctx.DASH() != null) {
      ExpressionUnit expression = new ExpressionUnit(Operator.MINUS);
      expression.addArgument(getExpression(ctx.primaryExpression()));
      return expression;
    } else {
      return getExpression(ctx.primaryExpression());
    }
  }
  
  public ExpressionArgument getExpression(Sp4rql11Parser.PrimaryExpressionContext ctx) {
    if(ctx.brackettedExpression() != null) {
      return getExpression(ctx.brackettedExpression().expression());
    } else if(ctx.builtInCall() != null) {
      return getExpression(ctx.builtInCall());
    } else if(ctx.iriOrFunction() != null) {
      return getExpression(ctx.iriOrFunction());
    } else if(ctx.rDFLiteral() != null) {
      return tokenFactory.getToken(ctx.rDFLiteral());
    } else if(ctx.numericLiteral() != null) {
      return tokenFactory.getToken(ctx.numericLiteral());
    } else if(ctx.booleanLiteral() != null) {
      return tokenFactory.getToken(ctx.booleanLiteral());
    } else if(ctx.var() != null) {
      return tokenFactory.getToken(ctx.var());
    }
    throw new ParseException("Could not parse the primaryExpression");
  }

  public ExpressionArgument getExpression(Sp4rql11Parser.IriOrFunctionContext ctx) {
    if(ctx.argList() == null) {
      return tokenFactory.getToken(ctx.iri());
    } else {
      String operator = tokenFactory.getToken(ctx.iri()).toString();
      ExpressionUnit expression = new ExpressionUnit(operator);

      if(ctx.argList().DISTINCT() != null) {
        expression.isDistinct();
      }
      for (Sp4rql11Parser.ExpressionContext argument : ctx.argList().expression()) {
        expression.addArgument(getExpression(argument));
      }
      return expression;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy