Ask*_*aga 19 c++ compiler-construction syntax parsing
在C++中,符号"<"和">"用于比较以及表示模板参数.因此,代码片段
[...] Foo < Bar > [...]
Run Code Online (Sandbox Code Playgroud)
可能被解释为以下两种方式中的任何一种:
C++编译器的解析器如何有效地决定这两种可能性?
n. *_* m. 15
如果Foo已知是模板名称(例如,template <...> Foo ...声明在范围内,或者编译器看到template Foo序列),那么Foo < Bar就不能进行比较.它必须是模板实例化的开始(或Foo < Bar >本周所称的任何内容).
如果Foo是没有模板名称,则Foo < Bar是一个比较.
在大多数情况下,它是众所周知Foo的,因为标识符通常必须在使用前声明,因此决定一种方式或另一种方式没有问题.但有一个例外:解析模板代码.如果Foo<Bar>在模板内,并且含义Foo取决于模板参数,则不知道是否Foo是模板.除非前面有关键字,否则语言标准会将其视为非模板template.
解析器可以通过将上下文反馈给词法分析器来实现此目的.词法分析器识别Foo为不同类型的标记,具体取决于解析器提供的上下文.
Mik*_*sev 10
要记住的重要一点是C++语法不是无上下文的.即,当解析器看到Foo < Bar(在大多数情况下)知道Foo引用模板定义时(通过在符号表中查找),因此<不能进行比较.
当你需要引导解析器时,有一些困难的情况.例如,假设正在编写具有模板成员函数的类模板,您希望将其显式专门化.您可能必须使用如下语法:
a->template foo<int>();
Run Code Online (Sandbox Code Playgroud)
(在某些情况下; 有关详细信息,请参阅模板类中的调用模板函数)
此外,非类型模板参数内的比较必须用括号括起来,即:
foo<(A > B)>
Run Code Online (Sandbox Code Playgroud)
不
foo<A > B>
Run Code Online (Sandbox Code Playgroud)
非静态数据成员初始化器带来更多乐趣:http://open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#325
C和C++解析器是"上下文敏感的",换句话说,对于给定的令牌或词汇,它不能保证是不同的并且只有一个含义 - 它取决于使用令牌的上下文.
因此,编译器的解析器部分将知道(通过理解"它在源中的位置")它正在解析某种类型或某种类型的比较(这不是很容易知道,这就是为什么阅读源代码有能力的C或C++编译器并不完全是直接的 - 有很多条件和函数调用检查"这是其中之一,如果这样做,否则做其他事情").
该关键字template有助于编译器理解发生了什么,但在大多数情况下,编译器只是知道,因为<在另一方面没有意义 - 如果它在EITHER形式中没有意义,那么它是一个错误,所以那么这只是试图弄清楚程序员可能想要什么的问题 - 这是有时候的一个原因,一个简单的错误,例如缺失}或者template可能导致整个解析误入歧途并导致数百或数千个错误[虽然理智的编译器在合理的数字后停止,以便用错误消息填充整个Universe]
| 归档时间: |
|
| 查看次数: |
1342 次 |
| 最近记录: |