Pour le contexte, veuillez d'abord lire this question about Ternary Operators.Analyse syntaxique de l'opérateur ternaire avec l'algorithme de shunt Yard
Je construis mon propre langage de programmation qui vous permet de définir des opérateurs personnalisés. Parce que je veux qu'il y ait aussi peu compilateur ENCASTRÉS possible, il devrait permettre la définition des opérateurs ternaires personnalisés, de préférence sous la forme
infix operator ? : { precedence 120 }
Mon (écrit à la main) Expression Parser transformera les opérateurs ternaires imbriqués en une liste d'opérandes séparés par des opérateurs.
a ? b ? c : d : e
(a) ? (b) ? (c) : (d) : (d)
OperatorChain(operators: [?, ?, :, :], operands: [a, b, c, d, e])
La OperatorChain
classe regarde maintenant les opérateurs de définitions de l'opérateur portée et convertit la liste en noeuds AST binaires en utilisant une version modifiée de l'algorithme de cour de triage, qui est indiqué ci-dessous:
// Note: OperatorElement is a class that merely stores an Identifier, an associated source code position and the resolved operator.
// IValue is the base interface for all Expression AST nodes
final Stack<OperatorElement> operatorStack = new LinkedList<>();
final Stack<IValue> operandStack = new LinkedList<>();
operandStack.push(this.operands[0]);
for (int i = 0; i < this.operatorCount; i++)
{
final OperatorElement element1 = this.operators[i];
OperatorElement element2;
while (!operatorStack.isEmpty())
{
element2 = operatorStack.peek();
final int comparePrecedence = element1.operator.comparePrecedence(element2.operator);
if (comparePrecedence < 0
|| element1.operator.getAssociativity() != IOperator.RIGHT && comparePrecedence == 0)
{
operatorStack.pop();
this.pushCall(operandStack, element2);
}
else
{
break;
}
}
operatorStack.push(element1);
operandStack.push(this.operands[i + 1]);
}
while (!operatorStack.isEmpty())
{
this.pushCall(operandStack, operatorStack.pop());
}
return operandStack.pop().resolve(markers, context);
Comment aurais-je besoin de modifier cet algorithme pour travailler avec des opérateurs ternaires, y compris ceux personnalisés?
Merci beaucoup! J'ai réussi à adapter ma classe 'OperatorChain' pour supporter les opérateurs ternaires personnalisés. La seule différence est qu'il traite ':' sans précéder '?'comme droit-associatif, bien que ce soit intentionnel. – Clashsoft