427

我经常听到有人声称 C++ 是一种上下文相关的语言。举个例子:

a b(c);

这是变量定义还是函数声明?这取决于符号的含义c。如果c是一个变量,则a b(c);定义一个名为btype的变量a。它直接用 初始化c。但是如果c是一个类型,那么a b(c);声明一个名为的函数b,它接受一个c并返回一个a

如果您查看上下文无关语言的定义,它基本上会告诉您所有语法规则都必须具有仅由一个非终结符组成的左侧。另一方面,上下文相关文法允许在左侧出现任意的终结符和非终结符字符串。

浏览“C++ 编程语言”的附录 A,我找不到一个语法规则,它的左侧除了一个非终结符之外还有其他任何东西。这意味着 C++ 是上下文无关的。(当然,从上下文无关语言形成上下文相关语言的子集的意义上说,每种上下文无关语言也是上下文相关的,但这不是重点。)

那么,C++ 是上下文无关的还是上下文敏感的?

4

20 回答 20

364

下面是我(当前)最喜欢的演示为什么解析 C++ 是(可能)图灵完备的,因为它显示了一个程序在语法上是正确的,当且仅当给定整数是素数时。

所以我断言C++ 既不是 context-free 也不是 context-sensitive

如果在任何产生式的两边都允许任意符号序列,则在Chomsky 层次结构中产生一个 Type-0 语法(“无限制”) ,它比上下文相关语法更强大;不受限制的文法是图灵完备的。上下文相关(Type-1)语法允许在产生式的左侧出现多个上下文符号,但相同的上下文必须出现在产生式的右侧(因此名称为“上下文敏感”)。[1] 上下文相关文法等价于线性有界图灵机

在示例程序中,素数计算可以由线性有界图灵机执行,因此它并不能完全证明图灵等价,但重要的部分是解析器需要执行计算才能执行句法分析。它可以是任何可表示为模板实例化的计算,并且完全有理由相信 C++ 模板实例化是图灵完备的。例如,参见Todd L. Veldhuizen 2003 年的论文

无论如何,C++ 可以被计算机解析,所以它当然可以被图灵机解析。因此,不受限制的语法可以识别它。实际上编写这样的语法是不切实际的,这就是标准不尝试这样做的原因。(见下文。)

某些表达的“歧义”问题主要是红鲱鱼。首先,歧义是特定语法的特征,而不是语言。即使可以证明一种语言没有明确的语法,如果它可以被上下文无关语法识别,它就是上下文无关的。同样,如果它不能被上下文无关文法识别,但可以被上下文相关文法识别,则它是上下文相关的。模棱两可无关紧要。

但无论如何,就像auto b = foo<IsPrime<234799>>::typen<1>();下面程序中的第 21 行(即 )一样,表达式一点也不含糊;它们只是根据上下文进行不同的解析。在这个问题的最简单表达中,某些标识符的句法类别取决于它们的声明方式(例如类型和函数),这意味着形式语言必须认识到两个任意长度的字符串在相同的程序是相同的(声明和使用)。这可以通过“复制”语法来建模,该语法是识别同一单词的两个连续精确副本的语法。用抽水引理很容易证明这种语言不是上下文无关的。该语言的上下文敏感语法是可能的,并且在此问题的答案中提供了 Type-0 语法:https ://math.stackexchange.com/questions/163830/context-sensitive-grammar-for-the-复制语言

如果有人试图编写一种上下文相关(或不受限制)的语法来解析 C++,它很可能会用乱七八糟的东西填满整个宇宙。编写图灵机来解析 C++ 将是同样不可能的任务。甚至编写 C++ 程序也很困难,据我所知,没有一个被证明是正确的。这就是为什么该标准不尝试提供完整的形式语法,以及为什么它选择用技术英语编写一些解析规则的原因。

在 C++ 标准中看起来像形式语法的东西并不是 C++ 语言语法的完整形式定义。它甚至不是预处理后语言的完整正式定义,这可能更容易形式化。(不过,这不是语言:标准定义的 C++ 语言包括预处理器,并且预处理器的操作是用算法描述的,因为它很难用任何语法形式来描述。它在那个部分描述词法分解的标准,包括必须多次应用的规则。)

各种文法(用于词法分析的两种重叠文法,一种在预处理之前进行,另一种在必要时在之后进行,加上“句法”文法)收集在附录 A 中,并附有重要说明(添加了重点):

此 C++ 语法摘要旨在帮助理解。这不是语言的准确表述。特别是,此处描述的语法接受有效 C++ 构造的超集。必须应用消歧规则(6.8、7.1、10.2)来区分表达式和声明。此外,必须使用访问控制、歧义和类型规则来清除语法上有效但无意义的结构。

最后,这是承诺的程序。当且仅当 N inIsPrime<N>是素数时,第 21 行在语法上是正确的。否则,typen是整数,而不是模板,因此typen<1>()被解析为(typen<1)>()语法不正确,因为()它不是语法有效的表达式。

template<bool V> struct answer { answer(int) {} bool operator()(){return V;}};

template<bool no, bool yes, int f, int p> struct IsPrimeHelper
  : IsPrimeHelper<p % f == 0, f * f >= p, f + 2, p> {};
template<bool yes, int f, int p> struct IsPrimeHelper<true, yes, f, p> { using type = answer<false>; };
template<int f, int p> struct IsPrimeHelper<false, true, f, p> { using type = answer<true>; };

template<int I> using IsPrime = typename IsPrimeHelper<!(I&1), false, 3, I>::type;
template<int I>
struct X { static const int i = I; int a[i]; }; 

template<typename A> struct foo;
template<>struct foo<answer<true>>{
  template<int I> using typen = X<I>;
};
template<> struct foo<answer<false>>{
  static const int typen = 0;
};

int main() {
  auto b = foo<IsPrime<234799>>::typen<1>(); // Syntax error if not prime
  return 0;
}

[1] 更专业地说,上下文相关语法中的每个产生式都必须是以下形式:

αAβ → αγβ

其中A是一个非终结符 和α,β可能是语法符号的空序列, 并且γ是一个非空序列。(语法符号可以是终结符或非终结符)。

A → γ只能在上下文中阅读[α, β]。在上下文无关(类型 2)语法中,α并且β必须为空。

事实证明,您还可以使用“单调”限制来限制语法,其中每个产生式都必须采用以下形式:

α → β其中|α| ≥ |β| > 0  (|α|表示“的长度α”)

可以证明单调文法所识别的语言集与上下文相关文法所识别的语言集完全相同,而且通常更容易将证明建立在单调文法的基础上。因此,将“上下文敏感”视为“单调”的意思是很常见的。

于 2013-01-29T18:18:40.330 回答
122

首先,您正确地观察到 C++ 标准末尾的语法中没有上下文相关规则,因此语法上下文无关的。

但是,该语法并不能准确描述 C++ 语言,因为它会生成非 C++ 程序,例如

int m() { m++; }

或者

typedef static int int;

定义为“一组格式良好的 C++ 程序”的 C++ 语言不是上下文无关的(有可能表明仅仅需要声明的变量就可以做到这一点)。假设您理论上可以在模板中编写图灵完备的程序并根据其结果使程序格式错误,它甚至不是上下文敏感的。

现在,(无知的)人(通常不是语言理论家,而是解析器设计者)通常在以下某些含义中使用“非上下文无关”

  • 模糊的
  • 无法用 Bison 解析
  • 不是 LL(k)、LR(k)、LALR(k) 或他们选择的任何解析器定义的语言类

标准后面的语法不满足这些类别(即它是模棱两可的,而不是 LL(k)...),因此 C++ 语法对它们来说“不是上下文无关的”。从某种意义上说,他们是对的,很难产生一个工作的 C++ 解析器。

请注意,此处使用的属性仅与上下文无关语言微弱相关 - 歧义与上下文敏感性没有任何关系(实际上,上下文相关规则通常有助于消除产生歧义),其他两个只是上下文的子集- 免费语言。并且解析上下文无关语言不是一个线性过程(尽管解析确定性语言是)。

于 2013-01-29T18:43:17.387 回答
62

是的。以下表达式具有不同的操作顺序,具体取决于类型解析的上下文

编辑:当实际操作顺序发生变化时,使用“常规”编译器在装饰之前解析为未装饰的 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 );
于 2009-07-23T16:46:09.733 回答
29

要回答您的问题,您需要区分两个不同的问题。

  1. 几乎所有编程语言的语法都是上下文无关的。通常,它以扩展的 Backus-Naur 形式或上下文无关语法的形式给出。

  2. 然而,即使一个程序符合编程语言定义的上下文无关语法,它也不一定是一个有效的程序。程序必须满足许多非上下文无关属性才能成为有效程序。例如,最简单的此类属性是变量的范围。

总而言之,C++ 是否是上下文无关的取决于您提出的问题。

于 2013-01-29T18:52:31.027 回答
15

您可能想看看Bjarne Stroustrup的 The Design & Evolution of C++。在其中他描述了他尝试使用 yacc(或类似的)来解析 C++ 的早期版本时遇到的问题,并希望他使用递归下降代替。

于 2009-07-23T17:00:16.757 回答
13

是的,C++ 是上下文敏感的,非常上下文敏感的。您不能通过使用上下文无关解析器简单地解析文件来构建语法树,因为在某些情况下,您需要从先前的知识中知道符号来决定(即在解析时构建符号表)。

第一个例子:

A*B;

这是乘法表达式吗?

或者

这是将B变量声明为类型指针A吗?

如果 A 是一个变量,那么它就是一个表达式,如果 A 是一个类型,那么它就是一个指针声明。

第二个例子:

A B(bar);

这是一个接受bar类型参数的函数原型吗?

或者

这是声明B类型的变量并使用常量作为初始化程序A调用 A 的构造函数吗?bar

您需要再次知道bar是符号表中的变量还是类型。

第三个例子:

class Foo
{
public:
    void fn(){x*y;}
    int x, y;
};

这是在解析时构建符号表无济于事的情况,因为 x 和 y 的声明出现在函数定义之后。所以你需要先扫描类定义,然后再看一遍方法定义,告诉 x*y 是一个表达式,而不是一个指针声明或其他什么。

于 2011-10-31T20:51:26.963 回答
12

我感觉“上下文敏感”的正式定义和“上下文敏感”的非正式使用之间存在一些混淆。前者具有明确的含义。后者用于表示“您需要上下文才能解析输入”。

这也在这里被问到: Context-sensitive vs Ambiguity

这是一个上下文无关的语法:

<a> ::= <b> | <c>
<b> ::= "x"
<c> ::= "x"

它是模棱两可的,因此为了解析输入“x”,您需要一些上下文(或忍受模棱两可,或发出“警告:E8271 - 第 115 行中的输入模棱两可”)。但它肯定不是上下文相关的语法。

于 2013-01-29T18:26:16.573 回答
10

C++ 使用 GLR 解析器进行解析。这意味着在解析源代码期间,解析器可能会遇到歧义,但它应该继续并决定稍后使用哪个语法规则。

还看,

为什么不能用 LR(1) 解析器解析 C++?


请记住,上下文无关语法不能描述编程语言语法的所有规则。例如,属性文法用于检查表达式类型的有效性。

int x;
x = 9 + 1.0;

不能用上下文无关语法描述以下规则: 赋值的右侧应该与左侧的类型相同。

于 2009-07-23T16:37:46.333 回答
6

没有类似 Algol 的语言是上下文无关的,因为它们具有约束表达式和语句的规则,标识符可以根据其类型出现在其中,并且因为在声明和使用之间可以出现的语句数量没有限制。

通常的解决方案是编写一个上下文无关的解析器,它实际上接受有效程序的超集,并将上下文敏感部分放在附加到规则的临时“语义”代码中。

C++ 远不止于此,这要归功于其图灵完备的模板系统。请参阅堆栈溢出问题 794015

于 2013-01-30T18:58:54.360 回答
5

真的 :)

J.斯坦利沃福德。计算机系统。第 341-346 页。

于 2009-07-23T16:37:15.710 回答
5

有时情况更糟:人们说 C++ 有“不可判定的语法”是什么意思?

于 2009-07-23T16:50:13.143 回答
5

它是上下文相关的,a b(c);有两个有效的解析——声明和变量。当你说“Ifc是一个类型”时,这就是上下文,就在那里,你已经准确地描述了 C++ 对它的敏感程度。如果您没有“什么是c”的上下文 你无法明确地解析这个。

在这里,上下文以标记的选择来表达——如果解析器命名了一个类型,则解析器将一个标识符作为类型名标记读取。这是最简单的解决方案,并且避免了上下文敏感的许多复杂性(在这种情况下)。

编辑:当然,还有更多的上下文敏感性问题,我只关注你展示的那个。模板对此特别讨厌。

于 2013-01-29T18:08:53.013 回答
5

C++ 标准中的产生式是在上下文无关的情况下编写的,但众所周知,它并没有真正准确地定义语言。大多数人认为当前语言中的歧义可以(我相信)通过上下文相关语法明确解决。

对于最明显的例子,让我们考虑最令人烦恼的 Parse int f(X);:. 如果X是一个值,那么这定义f为一个变量,将用 初始化X。IfX是一个类型,它定义f为一个函数,接受一个 type 的参数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 的条件,至少作为通常使用的术语。

于 2013-01-31T00:01:07.520 回答
5

非上下文无关语法的最简单情况涉及解析涉及模板的表达式。

a<b<c>()

这可以解析为

template
   |
   a < expr > ()
        |
        <
      /   \
     b     c

或者

 expr
   |
   <
 /   \
a   template
     |
     b < expr > ()
          |
          c

这两个 AST 只能通过检查 'a' 的声明来消除歧义——如果 'a' 是模板,则前者为 AST,否则为后者。

于 2013-01-31T08:41:26.133 回答
4

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。}

于 2009-11-15T20:54:56.327 回答
3

C++ 不是上下文无关的。我前段时间在编译器讲座中学到了它。快速搜索给出了这个链接,其中“语法或语义”部分解释了为什么 C 和 C++ 不是上下文无关的:

维基百科谈话:上下文无关语法

问候,
欧文斯

于 2009-07-23T16:42:18.010 回答
2

显然,如果您逐字逐句回答这个问题,几乎所有带有标识符的语言都是上下文相关的。

需要知道一个标识符是一个类型名(一个类名、一个由typedef引入的名字、一个typename模板参数)、一个模板名还是一些其他的名字才能正确的使用一些标识符。例如:

x = (name)(expression);

如果name是类型名称,则为强制转换,如果name为函数名称,则为函数调用。另一种情况是所谓的“最令人烦恼的解析”,其中无法区分变量定义和函数声明(有一条规则说它是函数声明)。

这种困难引入了依赖名称的需要typenametemplate依赖名称。据我所知,C++ 的其余部分不是上下文敏感的(即可以为它编写一个上下文无关的语法)。

于 2009-07-23T17:02:05.380 回答
2

Meta-S" 是 Quinn Tyler Jackson 的上下文相关解析引擎。我没有使用它,但他讲述了一个令人印象深刻的故事。查看他在 comp.compilers 中的评论,并查看 rnaparse.com/MetaS%20defined.htm – 艾拉巴克斯特 7 月 25 日 10:42

正确的链接是解析引擎

Meta-S 是一家名为 Thothic 的已倒闭公司的财产。我可以将 Meta-S 的免费副本发送给任何感兴趣的人,并且我已经在 rna 解析研究中使用了它。请注意,示例文件夹中包含的“伪结语法”是由非生物信息学的业余程序员编写的,基本上不起作用。我的语法采用了不同的方法并且效果很好。

于 2009-09-18T11:31:35.407 回答
1

这里的一个大问题是“上下文无关”和“上下文敏感”这两个术语在计算机科学中有点不直观。对于 C++,上下文敏感性看起来很像模棱两可,但在一般情况下不一定如此。

在 C/++ 中,if 语句只允许在函数体内使用。这似乎使它与上下文相关,对吧?嗯,不。上下文无关文法实际上并不需要您可以提取某行代码并确定其是否有效的属性。这实际上并不是上下文无关的意思。它实际上只是一个标签,模糊地暗示着某种与它的声音有关的东西。

现在,如果函数体内的语句根据直接语法祖先之外定义的内容(例如标识符是否描述类型或变量)而被不同地解析a * b;,那么它实际上是上下文相关的。这里没有真正的歧义。a如果是类型,它将被解析为指针的声明,否则将被解析为乘法。

上下文相关并不一定意味着“难以解析”。C 实际上并不难,因为臭名昭著的a * b;“歧义”可以用typedef之前遇到的包含 s 的符号表来解决。它不需要任何任意模板实例化(已被证明是图灵完备的)来解决这种情况,就像 C++ 有时所做的那样。实际上不可能编写一个不会在有限时间内编译的 C 程序,即使它具有与 C++ 相同的上下文敏感性。

Python(和其他对空格敏感的语言)也是上下文相关的,因为它需要词法分析器中的状态来生成缩进和缩进标记,但这并不比典型的 LL-1 语法更难解析。它实际上使用了解析器生成器,这也是 Python 具有如此无信息语法错误消息的部分原因。这里还需要注意的是,没有像a * b;Python 中的问题那样的“歧义”,给出了一个没有“歧义”语法的上下文相关语言的一个很好的具体示例(如第一段所述)。

于 2019-07-29T16:34:11.667 回答
-4

这个答案说 C++ 不是上下文无关的......有一个暗示(不是回答者)它无法被解析,并且答案提供了一个困难的代码示例,如果某个常量不是一个,它会产生一个无效的 C++ 程序素数。

正如其他人所观察到的,关于语言是否是上下文相关/自由的问题与关于特定语法的相同问题不同。

为了解决关于可解析性的问题,我提供了经验证据,证明 C++ 存在上下文无关文法,可用于生成 AST,以通过实际上用现有 GLR 解析源文本来对源文本进行无上下文解析- 由显式语法驱动的基于解析器的工具。

是的,它通过“接受太多”而成功;并非它接受的所有内容都是有效的 C++ 程序,这就是为什么它会进行额外的检查(类型检查)。是的,类型检查器可能会遇到可计算性问题。在实践中工具没有这个问题;如果人们编写这样的程序,他们都不会编译。(我认为该标准实际上限制了展开模板的计算量,因此实际上计算量实际上是有限的,但可能相当大)。

如果您的意思是,确定源程序是否是一组有效的 C++ 源程序的成员,那么我同意这个问题要困难得多。但问题不是解析

该工具通过将解析与对已解析程序的类型检查隔离开来解决此问题。(如果在没有上下文的情况下有多种解释,它会在解析树中记录一个歧义节点,并带有几个可能的解析;类型检查决定哪一个是正确的并消除无效的子树)。您可以在下面的示例中看到(部分)解析树;整棵树太大而无法放入 SO 答案中。请注意,无论使用值 234797 还是 234799,您都会得到一个解析树。

使用原始值 234799 在 AST 上运行工具的名称/类型解析器成功。使用值 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
于 2016-05-29T04:37:12.740 回答