为了背景,请先阅读有关三元运算符的这个问题。
我正在构建自己的编程语言,允许定义自定义运算符。因为我希望它尽可能少地使用编译器内置函数,所以应该允许定义自定义三元运算符,最好是以下形式:
我的(手写的)表达式解析器将把嵌套的三元运算符转换为由运算符分隔的操作数列表。
我正在构建自己的编程语言,允许定义自定义运算符。因为我希望它尽可能少地使用编译器内置函数,所以应该允许定义自定义三元运算符,最好是以下形式:
infix operator ? : { precedence 120 }
我的(手写的)表达式解析器将把嵌套的三元运算符转换为由运算符分隔的操作数列表。
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