Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import {CDSAggregate, CDSArithParen, CDSCase, CDSCast, CDSFunction, CDSPrefixedName, CDSString} from ".";
import {altPrio, Expression, plusPrio, seq, starPrio} from "../../abap/2_statements/combi";
import {IStatementRunnable} from "../../abap/2_statements/statement_runnable";
import {CDSInteger} from "./cds_integer";
/**
* Arithmetic expression: one or more values joined by +, -, *, /.
*
* Parenthesized sub-expressions of any nesting depth are handled via the
* separate CDSArithParen singleton (which wraps back to CDSArithmetics).
* The mutual reference between two distinct singletons enables true n-level
* nesting with no fixed limit and no infinite recursion.
*
* Grammar (simplified):
* CDSArithmetics → operand (op operand)+ -- with-operator form
* | unary val -- unary form
* | unary val (op operand)+ -- unary + continuation
* | unary CDSArithParen -- unary applied to paren, e.g. -(field)
* | unary CDSArithParen (op op)+ -- unary paren + continuation
* operand → CDSArithParen | val
* CDSArithParen → "(" CDSArithmetics ")" | "(" CDSArithParen ")" | "(" val ")"
*/
export class CDSArithmetics extends Expression {
public getRunnable(): IStatementRunnable {
const val = altPrio(CDSInteger, CDSFunction, CDSCase, CDSCast, CDSString, CDSAggregate, CDSPrefixedName);
const operator = altPrio("+", "-", "*", "/");
// Unary operator prefix, e.g. -field, +field
const unary = altPrio("-", "+");
const unaryExpression = seq(unary, val);
// An operand is either a parenthesized sub-expression (any depth) or a bare value.
// CDSArithParen = "(" altPrio(CDSArithmetics, CDSArithParen, val) ")" — separate singleton that
// can recursively contain itself, enabling deeply nested parentheses without infinite recursion.
const operand = altPrio(CDSArithParen, val);
const operatorValue = seq(operator, operand);
// Main form: operand op operand op ... (leading term may itself be a paren)
const withOperators = seq(operand, plusPrio(operatorValue));
// Unary followed by optional continuation operators: -1 * field, -field + 1
const unaryWithOps = seq(unaryExpression, plusPrio(operatorValue));
// Top-level parenthesized expression as a standalone field value: (A + B) * C
const parenExpr = altPrio(withOperators, unaryExpression);
const paren = seq("(", parenExpr, ")");
// Unary applied to a parenthesized group, e.g. -(TaxAmount)
const unaryParen = seq(unary, CDSArithParen);
return altPrio(
seq(paren, starPrio(operatorValue)), // (expr) op ...
seq(unaryParen, starPrio(operatorValue)), // -(paren) op ...
unaryWithOps, // -val op ...
unaryExpression, // -val
unaryParen, // -(paren)
withOperators, // operand op operand ...
);
}
}
|