Для контекста, пожалуйста, прочтите сначала this question about Ternary Operators.Анализ тернарных операторов с алгоритмом шунтирующего двора
Я создаю свой собственный язык программирования, который позволяет вам определять пользовательские операторы. Потому что я хочу, чтобы иметь несколько компилятор встроенные модулей, как это возможно, она должна позволить определение пользовательских трехкомпонентных операторов, предпочтительно в форме
infix operator ? : { precedence 120 }
Мой (рукописный) Expression Parser будет превращать вложенные тройные операторы в список операндов, разделенных операторами.
a ? b ? c : d : e
(a) ? (b) ? (c) : (d) : (d)
OperatorChain(operators: [?, ?, :, :], operands: [a, b, c, d, e])
OperatorChain
класса выглядит теперь до операторов из определений операторов в области видимости и преобразует список в двоичные узлы AST, используя модифицированную версию маневрового алгоритма двора, который показан ниже:
// 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);
Как мне нужно изменить этот алгоритм для работы с тройными операторами, в том числе и с обычными?
Большое спасибо! Мне удалось адаптировать класс 'OperatorChain' для поддержки пользовательских тернарных операторов. Единственное различие заключается в том, что он обрабатывает ':' без предшествующих'?'как право-ассоциативный, хотя это и предназначено. – Clashsoft