Ich baue eine Rekursiver Abstieg und ich habe zwei Regeln, die eine Liste zu erstellen:Top Down Recursive Descent Parsing: Unter Berufung auf Endrekursion Optimierung
ValueList -> TOKEN_IDENTIFER TOKEN_QUOTE ValueListP
ValueListP -> ValueList
| %EPSILON%
Jetzt weiß ich, dass Sie diese beiden Regeln in eine optimieren einzelne Regel mit einer Schleife leicht, aber ich weiß auch, dass der Compiler kann und wird Tail Call-Optimierung, wo es es sieht. Hier ist mein aktueller Code:
void Parser::grammarValueList(std::deque<std::unique_ptr<ValueNode>>& arg1)
{
std::string var1 = m_currentToken.getValue().string;
if(acceptToken(Token::Type::TOKEN_IDENTIFIER))
{
std::string var2 = m_currentToken.getValue().string;
if(acceptToken(Token::Type::TOKEN_QUOTE))
{
arg1.push_back(std::unique_ptr<ValueNode>(new ValueNode(var1, var2)));
if(peekValueListP())
{
return grammarValueListP(arg1);
}
}
}
throw ParseException("Error: did not expect \"" + m_currentToken.toString() + "\"");
}
void Parser::grammarValueListP(std::deque<std::unique_ptr<ValueNode>>& arg1)
{
if(peekValueList())
{
return grammarValueList(arg1);
}
else
{
return;
}
throw ParseException("Error: did not expect \"" + m_currentToken.toString() + "\"");
}
So habe ich zwei Fragen:
1) Ist meine bereitgestellten Code Hebel Endaufruf Optimierung?
2) Auch wenn ein Stück Code die Tail Call Optimierung nutzt, sollten wir als Programmierer versuchen, diese Optimierung zu unserem Selbst zu machen (Entfernen der Rekursion und Ersetzen durch eine Schleife) in trivialen Fällen?
Wenn Sie wissen möchten, ob Ihr spezifischer Compiler die Tail-Call-Optimierung durchführt, sehen Sie sich den Code der ausgegebenen Assemblersprache an. –
Nur weil ein Compiler kann nicht bedeutet, dass Ihr Compiler wird. Der C++ - Standard ermöglicht es dem Compiler, jede Optimierung durchzuführen, die nicht beobachtbar ist. aber der Compiler muss das auch nicht tun. –
Die einfache Lösung besteht darin, eine Iteration anstelle einer Rekursion zu verwenden. – EJP