我经常听到C ++是一种上下文敏感语言的说法。请看以下示例:
a b(c);
这是变量定义还是函数声明?这取决于符号c
的含义。如果c
是变量,则a b(c);
定义名为b
的{{1}}类型的变量。它使用a
直接初始化。但如果c
是类型,那么c
会声明一个名为a b(c);
的函数,该函数需要b
并返回c
。
如果你查找无上下文语言的定义,它基本上会告诉你所有语法规则必须有左侧,只包含一个非终端符号。另一方面,上下文敏感语法允许在左侧使用任意字符串的终端和非终端符号。
浏览“The C ++ Programming Language”的附录A,我找不到单个语法规则,除了左侧的单个非终端符号之外还有其他任何东西。这意味着C ++是无上下文的。 (当然,每种无上下文的语言也都是上下文敏感的,因为无上下文的语言构成了上下文敏感语言的一个子集,但这不是重点。)
那么,C ++是无上下文还是上下文敏感?
答案 0 :(得分:112)
首先,您正确地观察到C ++标准末尾的语法中没有上下文敏感规则,因此语法 无上下文。
然而,该语法并没有精确地描述C ++语言,因为它产生非C ++程序,如
int m() { m++; }
或
typedef static int int;
定义为“一组结构良好的C ++程序”的C ++语言不是无上下文的(可以证明只需要声明要求的变量就可以了)。理论上,你可以在模板中编写图灵完备程序,并根据结果使程序格式不正确,它甚至不是上下文敏感的。
现在,(无知)人(通常不是语言理论家,但是解析器设计者)通常在以下某些含义中使用“不具有上下文”
标准背面的语法不满足这些类别(即它不明确,而不是LL(k)......)因此C ++语法对它们来说“不具有上下文”。从某种意义上说,他们是对的,很难生成一个可行的C ++解析器。
请注意,此处使用的属性仅与上下文无关语言微弱关联 - 模糊性与上下文敏感性无关(事实上,上下文相关规则通常有助于消除歧义的制作),另外两个仅仅是无上下文语言的子集。解析无上下文语言不是一个线性过程(尽管解析确定性语言)。
答案 1 :(得分:59)
是。以下表达式具有不同的操作顺序,具体取决于类型已解析的上下文:
编辑:当实际操作顺序不同时,使用“常规”编译器在装饰之前解析未修饰的AST(传播类型信息)非常困难。与此相比,提到的其他上下文敏感事物“相当容易”(并非模板评估很容易)。
#if FIRST_MEANING
template<bool B>
class foo
{ };
#else
static const int foo = 0;
static const int bar = 15;
#endif
其次是:
static int foobar( foo < 2 ? 1 < 1 : 0 > & bar );
答案 2 :(得分:23)
要回答您的问题,您需要区分两个不同的问题。
几乎所有编程语言的语法都是无上下文的。通常,它是作为扩展的Backus-Naur形式或无上下文的gramar给出的。
但是,即使程序符合编程语言定义的无上下文gramar,它也不一定是有效的程序。程序必须满足许多非上下文无关的特性才能成为有效的程序。例如,最简单的这种属性是变量的范围。
总而言之,C ++是否无上下文取决于你问的问题。
答案 3 :(得分:11)
你可能想看看Bjarne Stroustrup的The Design & Evolution of C++。在其中,他描述了他试图使用yacc(或类似)来解析早期版本的C ++,并希望他使用递归下降的问题。
答案 4 :(得分:10)
使用GLR解析器解析C ++。这意味着在解析源代码时,解析器可能遇到歧义,但它应该继续并决定使用以后的语法规则。
看看,
Why C++ cannot be parsed with a LR(1) parser?
请记住,无上下文语法不能描述 ALL 编程语言语法的规则。例如,属性语法用于检查表达式类型的有效性。
int x;
x = 9 + 1.0;
您无法使用无上下文语法描述以下规则: 作业的右侧应与左手侧的类型相同。
答案 5 :(得分:10)
是的C ++是上下文敏感的,非常依赖于上下文。您无法通过使用无上下文解析器解析文件来构建语法树,因为在某些情况下,您需要知道先前知识中的符号来决定(即在解析时构建符号表)。
第一个例子:
A*B;
这是乘法表达式吗?
OR
这是B
变量的声明是A
类型的指针吗?
如果A是变量,那么它是一个表达式,如果A是类型,它就是一个指针声明。
第二个例子:
A B(bar);
这是一个函数原型,它采用bar
类型的参数吗?
OR
这是B
类型的变量A
,并且调用A的构造函数bar
常量作为初始值设定项吗?
您需要再次知道bar
是变量还是符号表中的类型。
第三个例子:
class Foo
{
public:
void fn(){x*y;}
int x, y;
};
构建符号表时就是这种情况,而解析没有帮助,因为x和y的声明位于函数定义之后。所以你需要首先扫描类定义,然后在第二遍中查看方法定义,告诉x * y是一个表达式,而不是指针声明或其他。
答案 6 :(得分:8)
我感觉在“上下文敏感”的正式定义与“上下文敏感”的非正式使用之间存在一些混淆。前者具有明确的含义。后者用于说“你需要上下文来解析输入”。
这里也有人问: Context-sensitivity vs Ambiguity
这是一个无上下文的语法:
<a> ::= <b> | <c>
<b> ::= "x"
<c> ::= "x"
这是不明确的,所以为了解析输入“x”你需要一些上下文(或者带有模糊性,或者发出“警告:E8271 - 输入在第115行中是模糊的”)。但它肯定不是一个上下文敏感的语法。
答案 7 :(得分:5)
没有类似Algol的语言是无上下文的,因为它们具有限制表达式和语句可以根据其类型出现的规则,并且因为声明和使用之间可能发生的语句数量没有限制。
通常的解决方案是编写一个无上下文的解析器,它实际上接受有效程序的超集,并将上下文相关部分放在附加到规则的 ad hoc “语义”代码中。
由于其图灵完整的模板系统,C ++远远超出了这个范围。请参阅Stack Overflow Question 794015。
答案 8 :(得分:5)
最简单的非上下文语法包括解析涉及模板的表达式。
a<b<c>()
这可以解析为
template
|
a < expr > ()
|
<
/ \
b c
或
expr
|
<
/ \
a template
|
b < expr > ()
|
c
这两个AST只能通过检查'a'的声明来消除歧义 - 如果'a'是模板,则为前AST,如果不是,则为后者。
答案 9 :(得分:4)
它是上下文相关的,因为a b(c);
有两个有效的parses-声明和变量。如果你说“如果c
是一个类型”,那就是那个上下文,你已经准确地描述了C ++对它的敏感程度。如果你没有“什么是c
?”的背景你不能毫不含糊地解析这个。
这里,上下文在标记的选择中表示 - 如果标识符命名类型,则解析器将标识符读取为类型名称标记。这是最简单的解决方案,并且避免了上下文敏感的大部分复杂性(在这种情况下)。
编辑:当然,有更多的情境敏感问题,我只关注你所展示的问题。模板对此特别讨厌。
答案 10 :(得分:4)
真:)
学家斯坦利沃福德。 Computer systems。第341-346页。
答案 11 :(得分:4)
C ++标准中的作品是无上下文的,但我们都知道并没有真正定义语言。大多数人认为当前语言中含糊不清的一些内容(我相信)可以通过上下文敏感语法明确地解决。
对于最明显的例子,让我们考虑最令人烦恼的解析:int f(X);
。如果X
是值,则将f
定义为将使用X
初始化的变量。如果X
是一种类型,则会将f
定义为采用X
类型的单个参数的函数。
从语法的角度来看,我们可以这样看:
A variable_decl ::= <type> <identifier> '(' initializer ')' ';'
B function_decl ::= <type> <identifier> '(' param_decl ')' ';'
A ::= [declaration of X as value]
B ::= [declaration of X as type]
当然,为了完全正确,我们需要添加一些额外的“东西”来说明干预其他类型声明的可能性(即,A和B都应该是“声明包括X声明的声明。 ..,或者那个订单上的东西。)
这仍然与典型的CSG有所不同(或者至少我记得它们)。这取决于正在构造的符号表 - 特别将X
识别为类型或值的部分,而不仅仅是此前的某种类型的语句,而是正确的符号/标识符的正确语句类型。
因此,我必须做一些寻找确定,但我的直接猜测是,这并不符合CSG,至少通常使用该术语。
答案 12 :(得分:3)
C ++模板已被证明是图灵强大的。虽然不是一个正式的参考,但在这方面,这里是一个值得关注的地方:
http://cpptruths.blogspot.com/2005/11/c-templates-are-turing-complete.html
我会冒险猜测(就像一个民俗和简洁的CACM证明,表明60年代的ALGOL无法被CFG重新制定)并且说C ++因此不能仅通过CFG正确解析。 CFG,结合树木通过或减少事件期间的各种TP机制 - 这是另一个故事。在一般意义上,由于停止问题,存在一些C ++程序无法显示正确/不正确但仍然是正确/不正确的。
{PS-作为Meta-S的作者(上面有几个人提到) - 我可以肯定地说,Thothic既不会失效,也不会免费提供软件。也许我已经措辞了这个版本的回复,这样我就不会被删除或投票到-3。}
答案 13 :(得分:3)
答案 14 :(得分:2)
C ++不是上下文。不久前我在编译器讲座中学到了它。快速搜索给出了这个链接,其中“语法或语义”部分解释了为什么C和C ++不是无上下文的:
Wikipedia Talk: Context-Free grammar
的问候,
Ovanes
答案 15 :(得分:1)
显然,如果你逐字逐句地提出问题,几乎所有带标识符的语言都是上下文敏感的。
需要知道标识符是类型名称(类名,typedef引入的名称,typename模板参数),模板名称还是其他一些名称才能正确使用标识符。例如:
x = (name)(expression);
如果name
是类型名称,则是强制转换,如果name
是函数名,则为函数调用。另一种情况是所谓的“最令人烦恼的解析”,它不可能区分变量定义和函数声明(有一条规则说它是一个函数声明)。
这种困难引入了typename
和template
与依赖名称的需求。据我所知,C ++的其余部分对上下文不敏感(即可以为它编写无上下文语法)。
答案 16 :(得分:1)
Meta-S“是Quinn Tyler Jackson的一个上下文敏感的解析引擎。我没有使用它,但他讲述了一个令人印象深刻的故事。请查看他在comp.compilers中的评论,并参阅rnaparse.com/MetaS% 20defined.htm - Ira Baxter 7月25日10:42
正确的链接是parsing enigines
Meta-S是一家名为Thothic的已停业公司的财产。我可以向任何感兴趣的人发送免费的Meta-S副本,我已经在rna解析研究中使用过它。请注意,示例文件夹中包含的“pseudoknot语法”是由非生物信息学,不成熟的程序员编写的,基本上不起作用。我的语法采用不同的方法,并且工作得很好。
答案 17 :(得分:0)
这里的一个大问题是,在计算机科学中,术语“无上下文”和“上下文敏感”有点不直观。对于C ++,上下文敏感性看上去很像模棱两可,但是在通常情况下并不一定是如此。
在C / ++中,仅在函数体内允许使用if语句。这似乎使它与上下文相关,对吗?好吧,不。上下文无关的语法实际上不需要该属性,您可以在其中提取一些代码行并确定其是否有效。这实际上不是上下文无关的意思。它实际上只是一个标签,含糊地暗示着与它听起来像的某种联系。
现在,如果像a * b;
情况那样,根据直接语法祖先外部定义的内容(例如,标识符是描述类型还是变量)对函数体内的语句进行不同的解析,则实际上,上下文相关。这里没有实际的歧义;如果a
是类型,则将其解析为指针的声明,否则将是乘法。
对上下文敏感并不一定意味着“难以解析”。实际上,C并不难,因为臭名昭著的a * b;
的“歧义性”可以通过包含先前遇到的typedef
的符号表来解决。它不需要任何模板实例化(已被证明是Turing Complete)就可以像C ++那样解决这种情况。即使C语言具有与C ++相同的上下文敏感性,实际上也不可能编写不会在有限时间内编译的C程序。
Python(以及其他对空格敏感的语言)也依赖于上下文,因为它需要词法分析器中的状态来生成缩进和缩进标记,但这并不比典型的LL-1语法更难解析。实际上,它使用了一个解析器生成器,这就是为什么Python包含这种无用的语法错误消息的一部分。在这里还需要注意的是,Python中没有像a * b;
问题那样的“模棱两可”,它是上下文敏感语言的一个很好的具体示例,没有“模棱两可”的语法(如第一段所述)。 / p>
答案 18 :(得分:-4)
This answer says C++ is not context-free...有一个暗示(不是由回答者)它无法解析,并且答案提供了一个困难的代码示例,如果某个常量不是素数,则会产生无效的C ++程序。< / p>
正如其他人所观察到的,关于语言是否是上下文敏感/自由的问题与关于特定语法的相同问题不同。
为了设置关于可解析性的问题,我提供了经验证据,证明C ++有无上下文的语法,可以使用 为源文本的无上下文解析生成AST 事实上,用一个由显式语法驱动的现有基于GLR解析器的工具解析它。
是的,它成功地“接受了太多”;并非它接受的一切都是有效的C ++程序,这就是为什么它会跟进额外的检查(类型检查)。是的,类型检查器可能会遇到可计算性问题。在实践中,工具没有这个问题;如果人们写这样的程序,他们都不会编译。 (我认为标准实际上限制了你可以展开模板的计算量,所以实际上计算实际上是有限的,但可能非常大)。
如果您的意思是,确定源程序是否是成员 一组有效的C ++源程序,那么我会同意 问题要困难得多。但它不是解析这就是问题。
该工具通过将解析与类型检查隔离来解决此问题 解析的程序。 (有多种解释的地方 在没有上下文的情况下,它会记录歧义节点 在解析树中有几个可能的解析;类型 检查决定哪一个是正确的并消除无效 子树)。您可以在下面的示例中看到(部分)解析树;整棵树太大了,不适合SO答案。请注意,无论是使用值234797还是234799,都会得到一个解析树。
在AST上运行工具的名称/类型解析器,原始值为234799成功。使用值234797,名称解析程序失败(按预期方式),并显示错误消息“typen不是类型”。因此该版本不是有效的C ++程序。
967 tree nodes in tree.
15 ambiguity nodes in tree.
(translation_unit@Cpp~GCC5=2#6b11a20^0 Line 1 Column 1 File C:/temp/prime_with_templates.cpp
(declaration_seq@Cpp~GCC5=1021#6b06640^1#6b11a20:1 {10} Line 1 Column 1 File C:/temp/prime_with_templates.cpp
(pp_declaration_seq@Cpp~GCC5=1022#6b049a0^1#6b06640:1 Line 1 Column 1 File C:/temp/prime_with_templates.cpp
(declaration@Cpp~GCC5=1036#6b04980^1#6b049a0:1 Line 1 Column 1 File C:/temp/prime_with_templates.cpp
|(template_declaration@Cpp~GCC5=2079#6b04960^1#6b04980:1 Line 1 Column 1 File C:/temp/prime_with_templates.cpp
| (template_parameter_list@Cpp~GCC5=2082#6afbde0^1#6b04960:1 Line 1 Column 10 File C:/temp/prime_with_templates.cpp
| (template_parameter@Cpp~GCC5=2085#6afbd80^1#6afbde0:1 Line 1 Column 10 File C:/temp/prime_with_templates.cpp
| (parameter_declaration@Cpp~GCC5=1611#6afbd40^1#6afbd80:1 Line 1 Column 10 File C:/temp/prime_with_templates.cpp
| |(basic_decl_specifier_seq@Cpp~GCC5=1070#6afb880^1#6afbd40:1 Line 1 Column 10 File C:/temp/prime_with_templates.cpp
| | (decl_specifier@Cpp~GCC5=1073#6afb840^1#6afb880:1 Line 1 Column 10 File C:/temp/prime_with_templates.cpp
| | (trailing_type_specifier@Cpp~GCC5=1118#6afb7e0^1#6afb840:1 Line 1 Column 10 File C:/temp/prime_with_templates.cpp
| | (simple_type_specifier@Cpp~GCC5=1138#6afb7a0^1#6afb7e0:1 Line 1 Column 10 File C:/temp/prime_with_templates.cpp)simple_type_specifier
| | )trailing_type_specifier#6afb7e0
| | )decl_specifier#6afb840
| |)basic_decl_specifier_seq#6afb880
| |(ptr_declarator@Cpp~GCC5=1417#6afbc40^1#6afbd40:2 Line 1 Column 15 File C:/temp/prime_with_templates.cpp
| | (noptr_declarator@Cpp~GCC5=1421#6afbba0^1#6afbc40:1 Line 1 Column 15 File C:/temp/prime_with_templates.cpp
| | (declarator_id@Cpp~GCC5=1487#6afbb80^1#6afbba0:1 Line 1 Column 15 File C:/temp/prime_with_templates.cpp
| | (id_expression@Cpp~GCC5=317#6afbaa0^1#6afbb80:1 Line 1 Column 15 File C:/temp/prime_with_templates.cpp
| | |(unqualified_id@Cpp~GCC5=319#6afb9c0^1#6afbaa0:1 Line 1 Column 15 File C:/temp/prime_with_templates.cpp
| | | (IDENTIFIER@Cpp~GCC5=3368#6afb780^1#6afb9c0:1[`V'] Line 1 Column 15 File C:/temp/prime_with_templates.cpp)IDENTIFIER
| | |)unqualified_id#6afb9c0
| | )id_expression#6afbaa0
| | )declarator_id#6afbb80
| | )noptr_declarator#6afbba0
| |)ptr_declarator#6afbc40
| )parameter_declaration#6afbd40
| )template_parameter#6afbd80
| )template_parameter_list#6afbde0
| (declaration@Cpp~GCC5=1033#6b04940^1#6b04960:2 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
| (block_declaration@Cpp~GCC5=1050#6b04920^1#6b04940:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
| (simple_declaration@Cpp~GCC5=1060#6b04900^1#6b04920:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
| |(basic_decl_specifier_seq@Cpp~GCC5=1070#6b048e0^1#6b04900:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
| | (decl_specifier@Cpp~GCC5=1073#6b048c0^1#6b048e0:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
| | (type_specifier@Cpp~GCC5=1110#6b048a0^1#6b048c0:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
| | (class_specifier@Cpp~GCC5=1761#6b04880^1#6b048a0:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
| | |(class_head@Cpp~GCC5=1763#6afb980^1#6b04880:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp
| | | (class_key@Cpp~GCC5=1791#6afbca0^1#6afb980:1 Line 1 Column 18 File C:/temp/prime_with_templates.cpp)class_key
| | | (IDENTIFIER@Cpp~GCC5=3368#6afbcc0^1#6afb980:2[`answer'] Line 1 Column 25 File C:/temp/prime_with_templates.cpp)IDENTIFIER
| | | (optional_base_clause@Cpp~GCC5=1872#6afba60^1#6afb980:3 Line 1 Column 32 File C:/temp/prime_with_templates.cpp)optional_base_clause
| | |)class_head#6afb980
| | |(member_specification@Cpp~GCC5=1794#6b042e0^1#6b04880:2 {2} Line 1 Column 34 File C:/temp/prime_with_templates.cpp
| | | (member_declaration_or_access_specifier@Cpp~GCC5=1806#6b04060^1#6b042e0:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
| | | (member_declaration@Cpp~GCC5=1822#6b04040^1#6b04060:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
| | | (function_definition@Cpp~GCC5=1632#6b04020^1#6b04040:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
| | | |(function_head@Cpp~GCC5=1673#6afbec0^1#6b04020:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
| | | | (ptr_declarator@Cpp~GCC5=1417#6afbfe0^1#6afbec0:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
| | | | (noptr_declarator@Cpp~GCC5=1422#6afbf80^1#6afbfe0:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
| | | | (noptr_declarator@Cpp~GCC5=1421#6afbf60^1#6afbf80:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
| | | | |(declarator_id@Cpp~GCC5=1487#6afbea0^1#6afbf60:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
| | | | | (id_expression@Cpp~GCC5=317#6afbb40^1#6afbea0:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
| | | | | (unqualified_id@Cpp~GCC5=319#6afbc80^1#6afbb40:1 Line 1 Column 34 File C:/temp/prime_with_templates.cpp
| | | | | (IDENTIFIER@Cpp~GCC5=3368#6afbc20^1#6afbc80:1[`answer'] Line 1 Column 34 File C:/temp/prime_with_templates.cpp)IDENTIFIER
| | | | | )unqualified_id#6afbc80
| | | | | )id_expression#6afbb40
| | | | |)declarator_id#6afbea0
| | | | )noptr_declarator#6afbf60
| | | | (parameter_declaration_clause@Cpp~GCC5=1559#6afbd00^1#6afbf80:2 Line 1 Column 41 File C:/temp/prime_with_templates.cpp
| | | | |(pp_parameter_declaration_list@Cpp~GCC5=1570#6afb940^1#6afbd00:1 Line 1 Column 41 File C:/temp/prime_with_templates.cpp
| | | | | (pp_parameter_declaration_seq@Cpp~GCC5=1574#6afb800^1#6afb940:1 Line 1 Column 41 File C:/temp/prime_with_templates.cpp
| | | | | (parameter_declaration@Cpp~GCC5=1610#6afb9a0^1#6afb800:1 Line 1 Column 41 File C:/temp/prime_with_templates.cpp
| | | | | (basic_decl_specifier_seq@Cpp~GCC5=1070#6afbf40^1#6afb9a0:1 Line 1 Column 41 File C:/temp/prime_with_templates.cpp
| | | | | |(decl_specifier@Cpp~GCC5=1073#6afbfa0^1#6afbf40:1 Line 1 Column 41 File C:/temp/prime_with_templates.cpp
| | | | | | (trailing_type_specifier@Cpp~GCC5=1118#6afbfc0^1#6afbfa0:1 Line 1 Column 41 File C:/temp/prime_with_templates.cpp
| | | | | | (simple_type_specifier@Cpp~GCC5=1140#6afb860^1#6afbfc0:1 Line 1 Column 41 File C:/temp/prime_with_templates.cpp)simple_type_specifier
| | | | | | )trailing_type_specifier#6afbfc0
| | | | | |)decl_specifier#6afbfa0
| | | | | )basic_decl_specifier_seq#6afbf40
| | | | | )parameter_declaration#6afb9a0
| | | | | )pp_parameter_declaration_seq#6afb800
| | | | |)pp_parameter_declaration_list#6afb940
| | | | )parameter_declaration_clause#6afbd00
| | | | (function_qualifiers@Cpp~GCC5=1438#6afbce0^1#6afbf80:3 Line 1 Column 46 File C:/temp/prime_with_templates.cpp)function_qualifiers
| | | | )noptr_declarator#6afbf80
| | | | )ptr_declarator#6afbfe0
| | | |)function_head#6afbec0
| | | |(function_body@Cpp~GCC5=1680#6b04000^1#6b04020:2 Line 1 Column 46 File C:/temp/prime_with_templates.cpp
| | | | (compound_statement@Cpp~GCC5=888#6afbee0^1#6b04000:1 Line 1 Column 46 File C:/temp/prime_with_templates.cpp)compound_statement
| | | |)function_body#6b04000
| | | )function_definition#6b04020
| | | )member_declaration#6b04040
| | | )member_declaration_or_access_specifier#6b04060
| | | (member_declaration_or_access_specifier@Cpp~GCC5=1806#6b042c0^1#6b042e0:2 Line 1 Column 49 File C:/temp/prime_with_templates.cpp
| | | (member_declaration@Cpp~GCC5=1822#6b04820^1#6b042c0:1 Line 1 Column 49 File C:/temp/prime_with_templates.cpp
| | | (function_definition@Cpp~GCC5=1632#6b04280^1#6b04820:1 Line 1 Column 49 File C:/temp/prime_with_templates.cpp
| | | |(function_head@Cpp~GCC5=1674#6b04220^1#6b04280:1 Line 1 Column 49 File C:/temp/prime_with_templates.cpp
| | | | (basic_decl_specifier_seq@Cpp~GCC5=1070#6b040e0^1#6b04220:1 Line 1 Column 49 File C:/temp/prime_with_templates.cpp
| | | | (decl_specifier@Cpp~GCC5=1073#6b040c0^1#6b040e0:1 Line 1 Column 49 File C:/temp/prime_with_templates.cpp
| | | | (trailing_type_specifier@Cpp~GCC5=1118#6b040a0^1#6b040c0:1 Line 1 Column 49 File C:/temp/prime_with_templates.cpp
| | | | |(simple_type_specifier@Cpp~GCC5=1138#6b04080^1#6b040a0:1 Line 1 Column 49 File C:/temp/prime_with_templates.cpp)simple_type_specifier
| | | | )trailing_type_specifier#6b040a0
| | | | )decl_specifier#6b040c0
| | | | )basic_decl_specifier_seq#6b040e0
| | | | (ptr_declarator@Cpp~GCC5=1417#6b04200^1#6b04220:2 Line 1 Column 54 File C:/temp/prime_with_templates.cpp
| | | | (noptr_declarator@Cpp~GCC5=1422#6b041e0^1#6b04200:1 Line 1 Column 54 File C:/temp/prime_with_templates.cpp
| | | | (noptr_declarator@Cpp~GCC5=1421#6b041a0^1#6b041e0:1 Line 1 Column 54 File C:/temp/prime_with_templates.cpp
| | | | |(declarator_id@Cpp~GCC5=1487#6b04180^1#6b041a0:1 Line 1 Column 54 File C:/temp/prime_with_templates.cpp
| | | | | (id_expression@Cpp~GCC5=317#6b04160^1#6b04180:1 Line 1 Column 54 File C:/temp/prime_with_templates.cpp
| | | | | (unqualified_id@Cpp~GCC5=320#6b04140^1#6b04160:1 Line 1 Column 54 File C:/temp/prime_with_templates.cpp
| | | | | (operator_function_id@Cpp~GCC5=2027#6b04120^1#6b04140:1 Line 1 Column 54 File C:/temp/prime_with_templates.cpp
| | | | | |(operator@Cpp~GCC5=2070#6b04100^1#6b04120:1 Line 1 Column 62 File C:/temp/prime_with_templates.cpp)operator
| | | | | )operator_function_id#6b04120
| | | | | )unqualified_id#6b04140
| | | | | )id_expression#6b04160
| | | | |)declarator_id#6b04180
| | | | )noptr_declarator#6b041a0
| | | | (parameter_declaration_clause@Cpp~GCC5=1558#6afba40^1#6b041e0:2 Line 1 Column 65 File C:/temp/prime_with_templates.cpp)parameter_declaration_clause
| | | | (function_qualifiers@Cpp~GCC5=1438#6b041c0^1#6b041e0:3 Line 1 Column 66 File C:/temp/prime_with_templates.cpp)function_qualifiers
| | | | )noptr_declarator#6b041e0
| | | | )ptr_declarator#6b04200
| | | |)function_head#6b04220
| | | |(function_body@Cpp~GCC5=1680#6b04300^1#6b04280:2 Line 1 Column 66 File C:/temp/prime_with_templates.cpp
| | | | (compound_statement@Cpp~GCC5=889#6b04760^1#6b04300:1 Line 1 Column 66 File C:/temp/prime_with_templates.cpp
| | | | (pp_statement_seq@Cpp~GCC5=894#6b04780^1#6b04760:1 Line 1 Column 67 File C:/temp/prime_with_templates.cpp
| | | | (statement@Cpp~GCC5=857#6b04440^1#6b04780:1 Line 1 Column 67 File C:/temp/prime_with_templates.cpp
| | | | |(jump_statement@Cpp~GCC5=1011#6afba80^1#6b04440:1 Line 1 Column 67 File C:/temp/prime_with_templates.cpp
| | | | | (pm_expression@Cpp~GCC5=551#6b04380^1#6afba80:1 Line 1 Column 74 File C:/temp/prime_with_templates.cpp
| | | | | (cast_expression@Cpp~GCC5=543#6b04360^1#6b04380:1 Line 1 Column 74 File C:/temp/prime_with_templates.cpp
| | | | | (unary_expression@Cpp~GCC5=465#6b04340^1#6b04360:1 Line 1 Column 74 File C:/temp/prime_with_templates.cpp
| | | | | |(primary_expression@Cpp~GCC5=307#6b04320^1#6b04340:1 Line 1 Column 74 File C:/temp/prime_with_templates.cpp
| | | | | | (id_expression@Cpp~GCC5=317#6b042a0^1#6b04320:1 Line 1 Column 74 File C:/temp/prime_with_templates.cpp
| | | | | | (unqualified_id@Cpp~GCC5=319#6b04260^1#6b042a0:1 Line 1 Column 74 File C:/temp/prime_with_templates.cpp
| | | | | | (IDENTIFIER@Cpp~GCC5=3368#6b04240^1#6b04260:1[`V'] Line 1 Column 74 File C:/temp/prime_with_templates.cpp)IDENTIFIER
| | | | | | )unqualified_id#6b04260
| | | | | | )id_expression#6b042a0
| | | | | |)primary_expression#6b04320
| | | | | )unary_expression#6b04340
| | | | | )cast_expression#6b04360
| | | | | )pm_expression#6b04380
| | | | |)jump_statement#6afba80
| | | | )statement#6b04440
| | | | )pp_statement_seq#6b04780
| | | | )compound_statement#6b04760
| | | |)function_body#6b04300
| | | )function_definition#6b04280
| | | )member_declaration#6b04820
| | | )member_declaration_or_access_specifier#6b042c0
| | |)member_specification#6b042e0
| | )class_specifier#6b04880
| | )type_specifier#6b048a0
| | )decl_specifier#6b048c0
| |)basic_decl_specifier_seq#6b048e0
| )simple_declaration#6b04900
| )block_declaration#6b04920
| )declaration#6b04940
|)template_declaration#6b04960
)declaration#6b04980
)pp_declaration_seq#6b049a0
(pp_declaration_seq@Cpp~GCC5=1022#6b06620^1#6b06640:2 Line 3 Column 1 File C:/temp/prime_with_templates.cpp
(declaration@Cpp~GCC5=1036#6b06600^1#6b06620:1 Line 3 Column 1 File C:/temp/prime_with_templates.cpp
|(template_declaration@Cpp~GCC5=2079#6b065e0^1#6b06600:1 Line 3 Column 1 File C:/temp/prime_with_templates.cpp
| (template_parameter_list@Cpp~GCC5=2083#6b05460^1#6b065e0:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
| (template_parameter_list@Cpp~GCC5=2083#6b05140^1#6b05460:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
| (template_parameter_list@Cpp~GCC5=2083#6b04ee0^1#6b05140:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
| |(template_parameter_list@Cpp~GCC5=2082#6b04cc0^1#6b04ee0:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
| | (template_parameter@Cpp~GCC5=2085#6b04ca0^1#6b04cc0:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
| | (parameter_declaration@Cpp~GCC5=1611#6b04c80^1#6b04ca0:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
| | (basic_decl_specifier_seq@Cpp~GCC5=1070#6b04a40^1#6b04c80:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
| | |(decl_specifier@Cpp~GCC5=1073#6b04a20^1#6b04a40:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
| | | (trailing_type_specifier@Cpp~GCC5=1118#6b04a00^1#6b04a20:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp
| | | (simple_type_specifier@Cpp~GCC5=1138#6b049e0^1#6b04a00:1 Line 3 Column 10 File C:/temp/prime_with_templates.cpp)simple_type_specifier
| | | )trailing_type_specifier#6b04a00
| | |)decl_specifier#6b04a20
| | )basic_decl_specifier_seq#6b04a40
| | (ptr_declarator@Cpp~GCC5=1417#6b04c40^1#6b04c80:2 Line 3 Column 15 File C:/temp/prime_with_templates.cpp
| | |(noptr_declarator@Cpp~GCC5=1421#6b04be0^1#6b04c40:1 Line 3 Column 15 File C:/temp/prime_with_templates.cpp
| | | (declarator_id@Cpp~GCC5=1487#6b04bc0^1#6b04be0:1 Line 3 Column 15 File C:/temp/prime_with_templates.cpp
| | | (id_expression@Cpp~GCC5=317#6b04b60^1#6b04bc0:1 Line 3 Column 15 File C:/temp/prime_with_templates.cpp
| | | (unqualified_id@Cpp~GCC5=319#6b04ac0^1#6b04b60:1 Line 3 Column 15 File C:/temp/prime_with_templates.cpp
| | | |(IDENTIFIER@Cpp~GCC5=3368#6b049c0^1#6b04ac0:1[`no'] Line 3 Column 15 File C:/temp/prime_with_templates.cpp)IDENTIFIER
| | | )unqualified_id#6b04ac0
| | | )id_expression#6b04b60
| | | )declarator_id#6b04bc0
| | |)noptr_declarator#6b04be0
| | )ptr_declarator#6b04c40
| | )parameter_declaration#6b04c80
| | )template_parameter#6b04ca0
| |)template_parameter_list#6b04cc0
| |(template_parameter@Cpp~GCC5=2085#6b04ec0^1#6b04ee0:2 Line 3 Column 19 File C:/temp/prime_with_templates.cpp
| | (parameter_declaration@Cpp~GCC5=1611#6b04ea0^1#6b04ec0:1 Line 3 Column 19 File C:/temp/prime_with_templates.cpp
| | (basic_decl_specifier_seq@Cpp~GCC5=1070#6b04b40^1#6b04ea0:1 Line 3 Column 19 File C:/temp/prime_with_templates.cpp
| | (decl_specifier@Cpp~GCC5=1073#6b04ba0^1#6b04b40:1 Line 3 Column 19 File C:/temp/prime_with_templates.cpp
| | |(trailing_type_specifier@Cpp~GCC5=1118#6b04c60^1#6b04ba0:1 Line 3 Column 19 File C:/temp/prime_with_templates.cpp
| | | (simple_type_specifier@Cpp~GCC5=1138#6b04580^1#6b04c60:1 Line 3 Column 19 File C:/temp/prime_with_templates.cpp)simple_type_specifier
| | |)trailing_type_specifier#6b04c60
| | )decl_specifier#6b04ba0
| | )basic_decl_specifier_seq#6b04b40
| | (ptr_declarator@Cpp~GCC5=1417#6b04e60^1#6b04ea0:2 Line 3 Column 24 File C:/temp/prime_with_templates.cpp
| | (noptr_declarator@Cpp~GCC5=1421#6b04e40^1#6b04e60:1 Line 3 Column 24 File C:/temp/prime_with_templates.cpp
| | |(declarator_id@Cpp~GCC5=1487#6b04de0^1#6b04e40:1 Line 3 Column 24 File C:/temp/prime_with_templates.cpp
| | | (id_expression@Cpp~GCC5=317#6b04d80^1#6b04de0:1 Line 3 Column 24 File C:/temp/prime_with_templates.cpp
| | | (unqualified_id@Cpp~GCC5=319#6b04ce0^1#6b04d80:1 Line 3 Column 24 File C:/temp/prime_with_templates.cpp
| | | (IDENTIFIER@Cpp~GCC5=3368#6b04560^1#6b04ce0:1[`yes'] Line 3 Column 24 File C:/temp/prime_with_templates.cpp)IDENTIFIER
| | | )unqualified_id#6b04ce0
| | | )id_expression#6b04d80
| | |)declarator_id#6b04de0
| | )noptr_declarator#6b04e40
| | )ptr_declarator#6b04e60
| | )parameter_declaration#6b04ea0
| |)template_parameter#6b04ec0
| )template_parameter_list#6b04ee0
| (template_parameter@Cpp~GCC5=2085#6b05120^1#6b05140:2 Line 3 Column 29 File C:/temp/prime_with_templates.cpp
| |(parameter_declaration@Cpp~GCC5=1611#6b05100^1#6b05120:1 Line 3 Column 29 File C:/temp/prime_with_templates.cpp
| | (basic_decl_specifier_seq@Cpp~GCC5=1070#6b04d20^1#6b05100:1 Line 3 Column 29 File C:/temp/prime_with_templates.cpp
| | (decl_specifier@Cpp~GCC5=1073#6b04dc0^1#6b04d20:1 Line 3 Column 29 File C:/temp/prime_with_templates.cpp
| | (trailing_type_specifier@Cpp~GCC5=1118#6b04e80^1#6b04dc0:1 Line 3 Column 29 File C:/temp/prime_with_templates.cpp
| | |(simple_type_specifier@Cpp~GCC5=1140#6b046e0^1#6b04e80:1 Line 3 Column 29 File C:/temp/prime_with_templates.cpp)simple_type_specifier
| | )trailing_type_specifier#6b04e80
| | )decl_specifier#6b04dc0
| | )basic_decl_specifier_seq#6b04d20
| | (ptr_declarator@Cpp~GCC5=1417#6b05080^1#6b05100:2 Line 3 Column 33 File C:/temp/prime_with_templates.cpp
| | (noptr_declarator@Cpp~GCC5=1421#6b05020^1#6b05080:1 Line 3 Column 33 File C:/temp/prime_with_templates.cpp
| | (declarator_id@Cpp~GCC5=1487#6b05000^1#6b05020:1 Line 3 Column 33 File C:/temp/prime_with_templates.cpp
| | |(id_expression@Cpp~GCC5=317#6b04fa0^1#6b05000:1 Line 3 Column 33 File C:/temp/prime_with_templates.cpp
| | | (unqualified_id@Cpp~GCC5=319#6b04f00^1#6b04fa0:1 Line 3 Column 33 File C:/temp/prime_with_templates.cpp
| | | (IDENTIFIER@Cpp~GCC5=3368#6b046c0^1#6b04f00:1[`f'] Line 3 Column 33 File C:/temp/prime_with_templates.cpp)IDENTIFIER
| | | )unqualified_id#6b04f00
| | |)id_expression#6b04fa0
| | )declarator_id#6b05000
| | )noptr_declarator#6b05020
| | )ptr_declarator#6b05080
| |)parameter_declaration#6b05100
| )template_parameter#6b05120
| )template_parameter_list#6b05140
| (template_parameter@Cpp~GCC5=2085#6b05440^1#6b05460:2 Line 3 Column 36 File C:/temp/prime_with_templates.cpp
| (parameter_declaration@Cpp~GCC5=1611#6b05420^1#6b05440:1 Line 3 Column 36 File C:/temp/prime_with_templates.cpp
| |(basic_decl_specifier_seq@Cpp~GCC5=1070#6b05160^1#6b05420:1 Line 3 Column 36 File C:/temp/prime_with_templates.cpp
| | (decl_specifier@Cpp~GCC5=1073#6b04fe0^1#6b05160:1 Line 3 Column 36 File C:/temp/prime_with_templates.cpp
| | (trailing_type_specifier@Cpp~GCC5=1118#6b050e0^1#6b04fe0:1 Line 3 Column 36 File C:/temp/prime_with_templates.cpp
| | (simple_type_specifier@Cpp~GCC5=1140#6b050c0^1#6b050e0:1 Line 3 Column 36 File C:/temp/prime_with_templates.cpp)simple_type_specifier
| | )trailing_type_specifier#6b050e0
| | )decl_specifier#6b04fe0
| |)basic_decl_specifier_seq#6b05160
| |(ptr_declarator@Cpp~GCC5=1417#6b053e0^1#6b05420:2 Line 3 Column 40 File C:/temp/prime_with_templates.cpp
| | (noptr_declarator@Cpp~GCC5=1421#6b053c0^1#6b053e0:1 Line 3 Column 40 File C:/temp/prime_with_templates.cpp
| | (declarator_id@Cpp~GCC5=1487#6b05360^1#6b053c0:1 Line 3 Column 40 File C:/temp/prime_with_templates.cpp
| | (id_expression@Cpp~GCC5=317#6b05280^1#6b05360:1 Line 3 Column 40 File C:/temp/prime_with_templates.cpp
| | |(unqualified_id@Cpp~GCC5=319#6b051a0^1#6b05280:1 Line 3 Column 40 File C:/temp/prime_with_templates.cpp
| | | (IDENTIFIER@Cpp~GCC5=3368#6b046a0^1#6b051a0:1[`p'] Line 3 Column 40 File C:/temp/prime_with_templates.cpp)IDENTIFIER
| | |)unqualified_id#6b051a0
| | )id_expression#6b05280
| | )declarator_id#6b05360
| | )noptr_declarator#6b053c0
| |)ptr_declarator#6b053e0
| )parameter_declaration#6b05420
| )template_parameter#6b05440
| )template_parameter_list#6b05460