私はいくつかの再帰的上昇パーサーを書いてきましたが、苦労してきたことの 1 つは左再帰です。次のように、正しい再帰を再帰的に表現できることは明らかです。
addExpr
: primaryExpr '+' addExpr
| primaryExpr;
の線に沿った何かによって
parseAddExpr() {
auto x = parsePrimaryExpr();
if (next_token == '+') {
auto result = make_unique<PlusExpr>();
result->lhs = x;
result->rhs = parseAddExpr();
return std::move(result);
}
return std::move(x);
}
しかし、左再帰については、while ループしか思いつきませんでした。
mulExpr
: mulExpr '*' addExpr
| addExpr;
parseMulExpr() {
auto expr = parseAddExpr();
while(next_token == '*') {
auto mul_expr = make_unique<MulExpr>();
mul_expr->lhs = std::move(expr);
mul_expr->rhs = parseAddExpr();
expr = std::move(mul_expr);
}
return std::move(expr);
}
つまり、これは正常に機能しますが、再帰バージョンが必要だと常に感じていました。左結合演算子を反復ではなく再帰的に実装することは可能ですか?