C ++上下文无关或上下文敏感?
我经常听到C ++是一种上下文敏感语言的说法。 以下面的例子:
ab(c);
这是一个variables定义或函数声明? 这取决于符号c
的含义。 如果c
是variables ,则ab(c);
定义了一个types为b
的variablesb
。 它直接用c
初始化。 但如果c
是一个types ,那么ab(c);
声明一个名为b
的函数,它接受一个c
并返回一个a
。
如果你查找上下文无关语言的定义,它将基本上告诉你,所有的语法规则都必须包含一个只包含一个非终结符号的左边。 另一方面,上下文敏感的语法允许在左侧的任意string的terminal和非terminal符号。
通过浏览“C ++编程语言”的附录A,我找不到一个单独的文法规则,除了左边的一个非terminal符号外,还有其他的东西。 这意味着C ++是上下文无关的。 (当然,上下文无关的语言也是上下文敏感的,上下文无关语言构成上下文敏感语言的一个子集,但这不是重点。)
那么,C ++是上下文无关的还是上下文敏感的?
下面是我的(当前)最喜欢的演示为什么parsingC ++是(可能) 图灵完整的 ,因为它显示了一个程序,当且仅当给定的整数是素数时,它在语法上是正确的。
所以我断言C ++既不是上下文自由的,也不是上下文敏感的 。
如果你允许在任何生产的两边都使用任意的符号序列,你可以在乔姆斯基层次结构中产生一个types0的语法(“无限制的”),它比上下文敏感的语法更强大。 不受限制的语法是图灵完整的。 上下文相关的(Type-1)语法允许在生产左侧的上下文的多个符号,但是相同的上下文必须出现在生产的右侧(因此名称“上下文相关”)。 [1]语境敏感语法相当于线性界限的图灵机 。
在示例程序中,素数计算可以由一个线性有界的图灵机来完成,所以它不能很好地certificate图灵等价性,但重要的部分是parsing器需要执行计算以进行句法分析。 它可能是任何可以作为模板实例化expression的计算,并且有充分理由相信C ++模板实例化是图灵完备的。 例如,见Todd L. Veldhuizen 2003年的论文 。
无论如何,C ++可以被计算机parsing,所以它肯定可以被图灵机parsing。 因此,一个不受限制的语法可以识别它。 实际上写这样一个语法是不切实际的,这就是为什么标准没有这样做的原因。 (见下文。)
某些expression方式的“模棱两可”问题大多是红鲱鱼。 首先,歧义是特定语法的一个特征,而不是语言。 即使一种语言可以被certificate没有明确的语法,如果它可以被一个上下文无关的语法所识别,那么它就是上下文无关的。 类似地,如果上下文无关的语法不能识别它,但是它可以被上下文敏感的语法识别,则它是上下文敏感的。 歧义是不相关的。
但是在任何情况下,如下面的程序中的第21行(即auto b = foo<IsPrime<234799>>::typen<1>();
),expression式根本auto b = foo<IsPrime<234799>>::typen<1>();
; 他们根据上下文简单地被parsing。 在这个问题的最简单的expression中,某些标识符的语法类别取决于它们是如何被声明的(例如types和函数),这意味着forms语言将不得不认识到两个任意长度的string相同的程序是相同的(声明和使用)。 这可以通过“复制”语法来模拟,该语法是识别相同单词的两个连续精确副本的语法。 用抽象引理certificate这个语言没有上下文是很容易的。 这种语言的上下文敏感语法是可能的,在这个问题的答案中提供了一个0型语法: https : //math.stackexchange.com/questions/163830/context-sensitive-grammar-for-the-the-复制语言 。
如果有人试图编写一个上下文敏感的(或不受限制的)语法来parsingC ++,那很可能会用涂鸦来填充整个宇宙。 编写一个图灵机来parsingC ++将是一个同样不可能的事情。 即使编写一个C ++程序也很困难,据我所知,没有一个certificate是正确的。 这就是为什么标准没有提供完整的forms语法的原因,为什么select在技术英语中编写一些parsing规则。
看起来像C ++标准中的forms语法并不是C ++语言的完整forms化定义。 它甚至不是预处理后语言的完整forms化定义,这可能更容易forms化。 (但这不是语言:标准定义的C ++语言包括预处理器,预处理器的操作在algorithm上被描述,因为在任何语法forms中描述都是非常困难的,在这个部分在描述词法分解的标准中,包括必须多次应用的规则。)
附录A收集了各种语法(词法分析中的两个重叠语法,一个在预处理之前发生,另一个在必要时,再加上“语法”语法)附录A中。
C ++语法的这个总结旨在帮助理解。 这不是语言的确切说明 。 特别是,这里描述的语法接受有效C ++结构的超集 。 必须应用消歧规则(6.8,7.1,10.2)来区分expression式和声明。 此外,必须使用访问控制,模糊性和types规则来清除语法上有效但无意义的构造。
最后,这是承诺的计划。 只有当IsPrime<N>
中的IsPrime<N>
是素数时,第21 IsPrime<N>
语法上才是正确的。 否则, typen
是一个整数,而不是一个模板,所以typen<1>()
被parsing为(typen<1)>()
,这在语法上是不正确的,因为()
不是一个语法上有效的expression式。
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]从技术上讲,在语境敏感的语法中,每个生产都必须具有以下forms:
αAβ → αγβ
其中A
是非terminal, α
, β
可能是语法符号的空序列,而γ
是非空序列。 (语法符号可以是terminal或非terminal)。
这可以理解为A → γ
A → γ
仅在上下文[α, β]
。 在上下文无关的(types2)语法中, α
和β
必须是空的。
事实certificate,你也可以用“单调”限制来限制语法,每一个生产必须是这样的forms:
α → β
α → β
其中|α| ≥ |β| > 0
|α| ≥ |β| > 0
|α| ≥ |β| > 0
( |α|
表示“ α
的长度”)
有可能certificate由单调语法识别的语言集合与由语境敏感语法识别的语言集合完全相同,并且通常情况下,基于单调语法的证据更容易。 因此,将“上下文相关”用作“单调”意义相当普遍。
首先,你正确地观察到在C ++标准结尾的语法中没有上下文敏感的规则,所以语法是上下文无关的。
但是,该语法并没有精确地描述C ++语言,因为它产生非C ++程序,如
int m() { m++; }
要么
typedef static int int;
被定义为“一组格式良好的C ++程序”的C ++语言不是上下文无关的(可以certificate只需要声明要求的variables就可以)。 考虑到理论上你可以在模板中编写图灵完整的程序,并根据其结果编写一个不合格的程序,它甚至不是上下文敏感的。
现在,(无知的)人(通常不是语言理论家,但是parsing器devise者)通常在下面的一些含义中使用“没有上下文的”
- 暧昧
- 不能与野牛parsing
- 而不是LL(k),LR(k),LALR(k)或他们select的任何语法分析器定义的语言类
在标准背后的语法不符合这些类别(即不明确,而不是LL(k)…),所以C ++语法对于他们来说“没有上下文”。 从某种意义上说,它们是正确的,生成一个可用的C ++parsing器是非常困难的。
请注意,这里使用的属性只与上下文无关的语言有微弱的联系 – 模糊与上下文敏感没有任何关系(实际上,上下文敏感的规则通常有助于消除生成歧义),另外两个仅仅是上下文的子集免费的语言。 parsing上下文无关语言不是一个线性过程(虽然parsing确定性的过程是)。
是。 以下expression式具有不同的操作顺序,具体取决于parsing的上下文types :
编辑:当操作的实际顺序不同时,使用“常规”编译器parsing未装饰的AST之前(传播types信息)难以置信地困难。 与此相比,其他与上下文相关的事物“相当容易”(模板评估不是那么简单)。
#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 );
要回答你的问题,你需要区分两个不同的问题。
-
几乎所有编程语言的简单语法都是上下文无关的。 通常,它是作为一个扩展的Backus-Naurforms或上下文无关的Gramar给出的。
-
但是,即使程序符合编程语言定义的上下文无关的语法,也不一定是有效的程序。 为了成为一个有效的程序,程序必须满足许多非上下文无关的属性。 例如,最简单的这种属性就是variables的范围。
总而言之,C ++是否是上下文的,取决于你所问的问题。
用GLRparsing器分析C ++。 这意味着在parsing源代码的过程中,parsing器可能会遇到不明确的地方,但是它应该继续下去,并决定稍后使用哪个语法规则。
也看,
为什么C ++不能用LR(1)parsing器parsing?
请记住,上下文无关语法不能描述编程语言语法的所有规则。 例如,属性语法用于检查expression式types的有效性。
int x; x = 9 + 1.0;
你不能用上下文无关的语法来描述下面的规则: 赋值的右边应该是左手边的相同types。
是的C ++是上下文敏感的,非常上下文敏感。 您不能通过使用上下文自由分析器parsing文件来构build语法树,因为在某些情况下,您需要知道先前知识中的符号来决定(即在parsing时构build符号表)。
第一个例子:
A*B;
这是一个乘法expression式吗?
要么
这是B
variables的声明是B
types的指针吗?
如果A是一个variables,那么它就是一个expression式,如果A是types的,它是一个指针声明。
第二个例子:
AB(bar);
这是一个函数原型采取bar
forms的参数?
要么
这是声明typesA
variablesB
,并调用A的构造函数与bar
常量作为初始化?
您需要再次知道bar
是variables还是符号表中的types。
第三个例子:
class Foo { public: void fn(){x*y;} int x, y; };
在分析时构build符号表无法提供帮助,因为x和y的声明在函数定义之后。 所以你需要首先扫描类定义,然后在第二遍中查看方法定义,告诉x * y是expression式,而不是指针声明或其他。
您可能想看看由Bjarne Stroustrup编写的“C ++的devise与演变” 。 在这篇文章中,他描述了他尝试使用yacc(或类似)来parsing早期版本的C ++的问题,并希望他使用recursion下降。
我有一种感觉,“情境敏感”的正式定义和“情境敏感”的非正式使用之间存在一些混淆。 前者有明确的含义。 后者用于说“你需要上下文以parsinginput”。
这也是在这里问: 上下文敏感与歧义 。
这是一个上下文无关的语法:
<a> ::= <b> | <c> <b> ::= "x" <c> ::= "x"
这是模棱两可的,所以为了parsinginput“x”,你需要一些上下文(或生活在模棱两可的地方,或者发出“警告:E8271 – input在第115行不明确”)。 但这当然不是一个语境敏感的语法。
没有类似Algol的语言是上下文无关的,因为它们有规则来约束expression式和标识符可以根据它们的types出现的语句,因为在声明和使用之间可能发生的语句的数量是没有限制的。
通常的解决scheme是编写一个上下文无关的parsing器,它实际上接受有效程序的超集,并将上下文敏感的部分放置在附加在规则上的临时 “语义”代码中。
由于其图灵完整的模板系统,C ++远远超出了这个范围。 请参阅堆栈溢出问题794015 。
非上下文无关语法的最简单情况涉及parsing涉及模板的expression式。
a<b<c>()
这可以parsing为
template | a < expr > () | < / \ bc
要么
expr | < / \ a template | b < expr > () | c
这两个AST只能通过检查“a”的声明来消除歧义 – 如果“a”是模板,则前AST;如果没有,则为后者。
真的:)
J. Stanley Warford。 计算机系统 。 第341-346页。
这是上下文敏感的,如ab(c);
有两个有效的parsing – 声明和variables。 当你说“如果c
是一个types”,那就是上下文,而且你已经描述了C ++是如何对它敏感的。 如果你没有这个“什么是c
? 你不能毫不含糊地parsing这个问题。
在这里,上下文表示在标记的select中 – 如果分析器命名了一个types,则分析器读取标识符作为types名称标记。 这是最简单的解决scheme,并避免了很多复杂的上下文敏感(在这种情况下)。
编辑:当然,还有更多的上下文敏感问题,我只专注于你所展示的那个。 模板特别讨厌这个。
C ++标准中的产品是上下文无关的,但是我们都知道,并没有精确地定义语言。 一些大多数人认为当前语言中的歧义可以(我相信)用语境敏感的语法来明确地解决。
举一个最明显的例子,我们来考虑一下最烦人的分析: int f(X);
。 如果X
是一个值,那么这将f
定义为将用X
初始化的variables。 如果X
是一个types,它将f
定义为一个采用X
types的单个参数的函数。
从语法的angular度来看,我们可以这样看:
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]
当然,为了完全正确,我们需要添加一些额外的“东西”来说明其他types的干预声明的可能性(即,A和B两者都应该是“声明X包括…的声明” ,或者按照这个顺序的东西)。
虽然(或者至less我记得他们),但这与典型的CSG还是有很大差别的。 这取决于正在构造的符号表 – 将X
特定地识别为types或值的部分,而不仅仅是在此之前的某种types的语句,而是正确的符号/标识符的正确types的语句。
因此,我不得不做一些确定的事情,但我的直接猜测是,这并不是真正的CSG资格,至less在正常情况下是这样的。
有时候更糟糕: 当人们说C ++有“不可判断的语法”时,人们意味着什么?
C ++模板已被certificate是图灵function强大的。 虽然不是一个正式的参考,这里有一个地方来看待这方面:
http://cpptruths.blogspot.com/2005/11/c-templates-are-turing-complete.html
我会冒险一个猜测(就像一个民间和简明的CACMcertificate,显示60年代的ALGOL不能被CFG重新规划),并且说C ++不能因此只能被CFG正确地parsing。 CFG,结合各种TP机制在树形通行证或减less事件期间 – 这是另一回事。 In a general sense, due to the Halting Problem, there exists some C++ program that cannot be shown to be correct/incorrect but is nonetheless correct/incorrect.
{PS- As the author of Meta-S (mentioned by several people above) — I can most assuredly say that Thothic is neither defunct, nor is the software available for free. Perhaps I have worded this version of my response such that I do not get deleted or voted down to -3.}
C++ is not context free. I learned it some time ago in compilers lecture. A quick search gave this link, where the "Syntax or semantics" section explains why C and C++ are not context free:
Wikipedia Talk: Context-Free grammar
问候,
Ovanes
Obviously, if you take the question verbatim, nearly all languages with identifiers are context sensitive.
One need to know if an identifier is a type name (a class name, a name introduced by typedef, a typename template parameter), a template name or some other name to be able to correctly some of the use of identifier. 例如:
x = (name)(expression);
is a cast if name
is a type name and a function call if name
is a function name. Another case is the so called "most vexing parse" where it isn't possible to differentiate variable definition and function declaration (there is a rule saying it is a function declaration).
That difficulty has introduced the need of typename
and template
with dependent names. The rest of C++ isn't context sensitive as far as I know (ie it is possible to write a context free grammar for it).
Meta-S" is a context-sensitive parsing engine by Quinn Tyler Jackson. I've not used it, but he tells an impressive story. Check out his comments in comp.compilers, and see rnaparse.com/MetaS%20defined.htm – Ira Baxter Jul 25 at 10:42
The correct link is parsing enigines
Meta-S was the property of a defunct company called Thothic. I can send a free copy of the Meta-S to anyone interested and I've used it in rna parsing research. Please note the "pseudoknot grammar" included in the examples folders was written by an non-bioinformatics, amature programmer and basically doesn't work. My grammars take a different approach and work quite well.
This answer says C++ is not context-free… there's an implication (not by the answerer) that it can't be parsed, and the answer offers a difficult code example which produces an invalid C++ program if a certain constant is not a prime number.
As others have observed, the question about whether the language is context-sensitive/free is different than the same question about a specific grammar.
To set the question about parseability to rest, I offer empirical evidence that there are context-free grammars for C++, that can be used to produce an AST for a context-free parse of the source text by in fact parsing it with an existing GLR-parser-based tool that is driven by an explicit grammar.
Yes, it succeeds by "accepting too much"; not everything it accepts is a valid C++ program, which is why it's followed up with additional checks (type checks). And yes, the type checker may run into computability problems. In practice tools don't have this problem; if people wrote programs like that, none of them would compile. (I think the standard actually puts a limit on the amount of computation you can do unfolding a template, so in fact the computation is actually finite but probably pretty big).
If what you mean is, determine if the source program is a member of the set of valid C++ source programs , then I will agree the problem is a lot harder. But it isn't parsing that is the problem.
The tool resolves this issue by isolating parsing from type-checking the parsed program. (Where there are multiple interpretations in the absence of context, it records an ambiguity node in the parse tree with several possible parses; the type checking decides which one is correct and eliminates the invalid subtrees). You can see a (partial) parse tree in the example below; the whole tree is too large to fit in an SO answer. Note you get a parse tree whether the value 234797 or 234799 is used.
Running the tool's name/type resolver over the AST with the original value 234799 succeeds. With the value 234797 the name resolver fails (as expected) with the error message, "typen is not a type." and thus that version is not a valid C++ program.
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