情况:我有一种简单的语言,可以评估算术表达式。我为一个简单的表达式构造了一个AST:x + 8 * 9
(其中x
是一些变量)。 AST看起来像这样:
AddExpression
| |
Var(x) MultExpression
| |
Const(8) Const(9)
我有一个通用的Expression
基类,AddExpression
,MultExpression
,Var
和Const
都来自这些基类。 MultExpression
看起来有点像这样,例如:
class MultExpression : public Expression
{
std::unique_ptr<Expression> leftOperand;
std::unique_ptr<Expression> rightOperand;
bool canEvalCompileTime() const;
std::unique_ptr<Expression> evalCompileTime() const;
};
AddExpression
大致相同。
我现在想进行基本的恒定折叠;在这个例子中,我们想将表达式转换为x + 72
。最方便的方法是将MultExpression
转换为Const(72)
,而AddExpression
不知道或参与其中;但是,即使MultExpression
和Const
都有Expression
作为基类,我也无法将其变为另一个。
相反,我必须转而使用父节点(AddExpression
)并将其纳入流程;它必须验证确实可以执行优化,然后让MultExpression
执行它,然后将生成的Expression
指针指向其rightOperand
:
if (rightOperand->canEvalCompileTime())
{
rightOperand = rightOperand->evalCompileTime();
}
这有效,但我觉得第一个描述的方法会更清洁。是否有一种克服技术难度的干净方法?