private static Computation parse(
        Expression expression, AtomicInteger counter, Map<String, Integer> symbolToIndex) {
      if (expression instanceof ArithmeticBinaryExpression) {
        ArithmeticBinaryExpression arithmeticExpr = (ArithmeticBinaryExpression) expression;
        Computation left = parse(arithmeticExpr.getLeft(), counter, symbolToIndex);
        Computation right = parse(arithmeticExpr.getRight(), counter, symbolToIndex);
        ArithmeticOperator op = mapArithmeticOperator(arithmeticExpr.getOperator());
        return new BinaryComputation(left, right, op);
      } else if (expression instanceof ComparisonExpression) {
        ComparisonExpression comparisonExpr = (ComparisonExpression) expression;
        Computation left = parse(comparisonExpr.getLeft(), counter, symbolToIndex);
        Computation right = parse(comparisonExpr.getRight(), counter, symbolToIndex);
        ComparisonOperator op = mapComparisonOperator(comparisonExpr.getOperator());
        return new BinaryComputation(left, right, op);
      } else if (expression instanceof LogicalExpression) {
        LogicalExpression logicalExpr = (LogicalExpression) expression;
        List<Computation> computations = new ArrayList<>();
        for (Expression term : logicalExpr.getTerms()) {
          computations.add(parse(term, counter, symbolToIndex));
        }
        NaryOperator op = mapLogicalOperator(logicalExpr.getOperator());
        return new NaryComputation(computations, op);
      } else if (expression instanceof SymbolReference) {
        // Upon encountering a SymbolReference type, it is converted into a ReferenceComputation.
        // B.value < LAST(B.value) -> b_0 < b_1
        // LAST(B.value, 1) < LAST(B.value, 2) -> b_0 < b_1 + 1
        SymbolReference symRef = (SymbolReference) expression;
        String name = symRef.getName();
        // If an index has not been previously assigned to the symbol, a new index is allocated.
        if (!symbolToIndex.containsKey(name)) {
          symbolToIndex.put(name, counter.getAndIncrement());
        }
        int index = symbolToIndex.get(name);
        return new ReferenceComputation(index);
      } else if (expression instanceof LongLiteral) {
        LongLiteral constExpr = (LongLiteral) expression;
        return new ConstantComputation(constExpr.getParsedValue());
      } else if (expression instanceof DoubleLiteral) {
        DoubleLiteral constExpr = (DoubleLiteral) expression;
        return new ConstantComputation(constExpr.getValue());
      } else if (expression instanceof StringLiteral) {
        StringLiteral constExpr = (StringLiteral) expression;
        return new ConstantComputation(constExpr.getValue());
      } else if (expression instanceof BooleanLiteral) {
        // undefined pattern variable is 'true'
        BooleanLiteral constExpr = (BooleanLiteral) expression;
        return new ConstantComputation(constExpr.getValue());
      } else {
        throw new IllegalArgumentException(
            "Unsupported expression type: " + expression.getClass().getName());
      }
    }
A helper method for recursively parsing an Expression.

@param expression The expression currently being parsed
@param counter Used to sequentially assign parameter indices
@param symbolToIndex Records the index corresponding to each symbol, ensuring that the same
    index is used when the same symbol reappears
@return The constructed Computation expression tree
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/Computation.java