自上而下的递归下降解析:依靠尾声优化
Top Down Recursive Descent Parsing : Relying on tail call optimization
我正在构建一个递归下降解析器,我有两个规则,这些规则构建了一个列表:
ValueList -> TOKEN_IDENTIFER TOKEN_QUOTE ValueListP
ValueListP -> ValueList
| %EPSILON%
现在,我知道您可以轻松地将这两个规则优化为单个规则,但我也知道编译器可以并且将在看到它的位置执行尾部调用优化。这是我当前的代码:
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() + """ );
}
所以我有两个问题:
1)我提供的代码杠杆尾部调用优化吗?
2)即使一块代码确实利用了尾巴调用优化,我们作为程序员是否应该在微不足道的情况下试图使我们的自我(删除递归并用循环替换)?
不,grammarValueList
不执行尾声。
问题是std::string
型的局部变量有两个局部变量,该变量具有非平凡的破坏者。这些破坏者必须在方法返回之前调用,这是在调用grammarValueListP
之后的。因此,呼叫grammarValueListP
不在尾部位置。
当然,有可能访问破坏者定义的优化器可能会发现,可以过早地破坏var1
和var2
而不会改变函数的可见行为(假设可能;它取决于;它取决于;部分关于ValueNode
构造函数内部发生的事情)。但是我不认为大多数C 实现都试图优化尾巴调用。
就个人而言,我会使用一个循环,因为即使您设法消除了Destructor呼叫,编译器仍然找不到TCO。从这个显然很简单的例子中可以看出,C 中的尾巴通常并不像它们在表面上那样琐碎,而且令人惊讶的是说服优化者生产一个。
相关文章:
- MacOS通过在莫哈韦"wchar.h"下破碎的自制啤酒发出叮当声
- 为什么 gcc 会产生这种奇怪的组件与叮当声?
- 如何在窗户上使用和配置叮当声?
- 叮当声:折叠表情和"expression result unused"警告
- PJSUA在两个或多个不同的音频声卡之间切换
- 在C++中重载运算符时,为什么T*优先于bool
- 我是否以错误的方式声明了getpriorityvalues函数
- 使用NOLINT抑制叮当声.如何抑制抑制?
- 是否有可能编写新的叮当声现代化规则?
- 代码的最优解,以便它可以执行高达 10^18 的计算
- 忽略由第三方标头引起的 [叮当声诊断错误] 叮当声整洁
- Rcpp - 使用最优函数
- 使叮当声忽略对线路的评论
- 我可以依靠 initializer_list::const_iterator 是一个普通的指针吗?
- 我可以依靠 TCHAR 的定义对我正在使用的字符集做出正确的假设吗?
- 如何在Raspberry Pi上使用C /libao/alsa通过USB声卡播放音频
- Tensorflow c++ API 失败设置 gpu/cpu 编号:SetDefaultDevice 错误:具有相同优
- 在叮当声中regex_constants实现错误
- 依靠网络 I/O 在C++中提供跨线程同步
- 用叮当声(3.8)和Android NDK R14B建筑物提升(1.58)