¿C++ es libre de contexto o sensible al contexto?


A menudo escucho afirmaciones de que C++ es un lenguaje sensible al contexto. Tomemos el siguiente ejemplo:

a b(c);

¿Es una definición de variable o una declaración de función? Eso depende del significado del símbolo c. Si ces una variable , entonces a b(c); define una variable llamada b de tipo a. Se inicializa directamente con c. Pero si c es a tipo, entonces a b(c); declara una función denominada b que toma un c y devuelve un a.

Si busque la definición de lenguajes libres de contexto, básicamente le dirá que todas las reglas gramaticales deben tener lados izquierdos que consistan en exactamente un símbolo no terminal. Las gramáticas sensibles al contexto, por otro lado, permiten cadenas arbitrarias de símbolos terminales y no terminales en el lado izquierdo.

Navegando a través del Apéndice A de " El Lenguaje de Programación C++", no pude encontrar una sola regla gramatical que tuviera nada más que un solo símbolo no terminal en su mano izquierda lado. Eso implicaría que C++ está libre de contexto. (Por supuesto, cada lenguaje libre de contexto también es sensible al contexto en el sentido de que los lenguajes libres de contexto forman un subconjunto de los lenguajes sensibles al contexto, pero ese no es el punto.)

Entonces, ¿C++ es libre de contexto o sensible al contexto?

Author: Core Xii, 2013-01-29

19 answers

A continuación se muestra mi (actual) demostración favorita de por qué parsing C++ es (probablemente) Turing-complete, ya que muestra un programa que es sintácticamente correcto si y solo si un entero dado es primo.

Así que afirmo que C++ no es ni libre de contexto ni sensible al contexto.

Si permite secuencias de símbolos arbitrarias en ambos lados de cualquier producción, produce una gramática de Tipo-0 ("sin restricciones") en la jerarquía de Chomsky, que es más poderosa que una gramática sensible al contexto; gramáticas sin restricciones son Turing-completo. Una gramática contextual (Tipo-1) permite múltiples símbolos de contexto en el lado izquierdo de una producción, pero el mismo contexto debe aparecer en el lado derecho de la producción (de ahí el nombre "context-sensitive"). [1] Las gramáticas sensibles al contexto son equivalentes a máquinas de Turing con límites lineales .

En el programa de ejemplo, el cómputo primo podría ser realizado por un Turing linear-acotado máquina, por lo que no prueba la equivalencia de Turing, pero la parte importante es que el analizador necesita realizar el cálculo con el fin de realizar el análisis sintáctico. Podría haber sido cualquier cálculo expresable como una instanciación de plantilla y hay muchas razones para creer que la instanciación de plantilla de C++ es Turing-completa. Véase, por ejemplo, El documento de Todd L. Veldhuizen de 2003 .

A pesar de todo, C++ puede ser analizado por un equipo, por lo que sin duda podría ser analizado por un Máquina de Turing. En consecuencia, una gramática sin restricciones podría reconocerlo. En realidad, escribir tal gramática sería poco práctico, por lo que el estándar no intenta hacerlo. (Véase más adelante.)

El problema con la "ambigüedad" de ciertas expresiones es principalmente una pista falsa. Para empezar, la ambigüedad es una característica de una gramática en particular, no de un idioma. Incluso si se puede demostrar que un lenguaje no tiene gramáticas inequívocas, si puede ser reconocido por una gramática libre de contexto, es libre de contexto. Del mismo modo, si no puede ser reconocido por una gramática libre de contexto, pero puede ser reconocido por una gramática sensible al contexto, es sensible al contexto. La ambigüedad no es relevante.

Pero en cualquier caso, como la línea 21 (es decir, auto b = foo<IsPrime<234799>>::typen<1>();) en el siguiente programa, las expresiones no son ambiguas en absoluto; simplemente se analizan de manera diferente dependiendo del contexto. En la expresión más simple del problema, la categoría sintáctica de ciertos identificadores depende de cómo se han declarado (tipos y funciones, por ejemplo), lo que significa que el lenguaje formal tendría que reconocer el hecho de que dos cadenas de longitud arbitraria en el mismo programa son idénticas (declaración y uso). Esto puede ser modelado por la gramática "copia", que es la gramática que reconoce dos copias exactas consecutivas de la misma palabra. Es fácil demostrar con el lema pumping que este lenguaje no está libre de contexto. Una gramática sensible al contexto para este idioma es posible, y una gramática de Tipo 0 es proporcionado en la respuesta a esta pregunta: https://math.stackexchange.com/questions/163830/context-sensitive-grammar-for-the-copy-language .

Si uno intentara escribir una gramática sensible al contexto (o sin restricciones) para analizar C++, posiblemente llenaría el universo con garabatos. Escribir una máquina de Turing para analizar C++ sería una tarea igualmente imposible. Incluso escribir un programa C++ es difícil, y por lo que sé, ninguno ha sido probado correcto. Esto es por qué el estándar no intenta proporcionar una gramática formal completa, y por qué elige escribir algunas de las reglas de análisis en inglés técnico.

Lo que parece una gramática formal en el estándar C++ no es la definición formal completa de la sintaxis del lenguaje C++. Ni siquiera es la definición formal completa del lenguaje después del preprocesamiento, lo que podría ser más fácil de formalizar. (Ese no sería el lenguaje, sin embargo: el lenguaje C++ definido por el estándar incluye el preprocesador, y la operación del preprocesador se describe algorítmicamente, ya que sería extremadamente difícil de describir en cualquier formalismo gramatical. Es en esa sección de la norma donde se describe la descomposición léxica, incluyendo las reglas donde debe aplicarse más de una vez.)

Las diversas gramáticas (dos gramáticas superpuestas para el análisis léxico, una que tiene lugar antes del preprocesamiento y la otra, si es necesario, después, más la gramática "sintáctica" ) se recogen en el Apéndice A, con esta importante nota (énfasis añadido):

Este resumen de la sintaxis de C++ pretende ser una ayuda para la comprensión. No es una declaración exacta del lenguaje. En particular, la gramática descrita aquí acepta un superconjunto de construcciones válidas de C++ . Las reglas de desambiguación (6.8, 7.1, 10.2) deben aplicarse para distinguir expresiones de declaraciones. Además, el control de acceso, la ambigüedad y las reglas de tipo deben usarse para eliminar construcciones sintácticamente válidas pero sin sentido.

Finalmente, aquí está el programa prometido. La línea 21 es sintácticamente correcta si y solo si la N en IsPrime<N> es prima. De lo contrario, typen es un entero, no una plantilla, por lo que typen<1>() se analiza como (typen<1)>() que es sintácticamente incorrecto porque () no es una expresión sintácticamente válida.

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] Para decirlo más técnicamente, cada producción en una gramática sensible al contexto debe ser de la formulario:

αAβ &rightarrow; αγβ

Donde A es un no terminal y α, β son posiblemente secuencias vacías de símbolos gramaticales, y γ es una secuencia no vacía. (Los símbolos gramaticales pueden ser terminales o no terminales).

Esto se puede leer como A &rightarrow; γ solo en el contexto [α, β]. En una gramática libre de contexto (Tipo 2), α y β deben estar vacíos.

Resulta que también puede restringir gramáticas con la restricción "monótona", donde cada producción debe ser de la forma:

α &rightarrow; β donde |α| ≥ |β| > 0 (|α| significa "la longitud de α")

Es posible probar que el conjunto de lenguajes reconocidos por las gramáticas monótonas es exactamente el mismo que el conjunto de lenguajes reconocidos por las gramáticas sensibles al contexto, y a menudo es más fácil basar las pruebas en gramáticas monótonas. En consecuencia, es bastante común ver que" sensible al contexto "se usa como si significara"monótono".

 315
Author: rici,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-13 12:19:19

Primero, observaste correctamente que no hay reglas sensibles al contexto en la gramática al final del estándar de C++, por lo que la gramática es libre de contexto.

Sin embargo, esa gramática no describe con precisión el lenguaje C++, porque produce programas no C++ como

int m() { m++; }

O

typedef static int int;

El lenguaje C++ definido como "el conjunto de programas C++ bien formados" no está libre de contexto (es posible demostrar que las variables meramente exigentes para ser declaradas lo hacen así). Dado que teóricamente puede escribir programas Turing-completos en plantillas y hacer un programa mal formado basado en su resultado, ni siquiera es sensible al contexto.

Ahora, las personas (ignorantes) (generalmente no teóricos del lenguaje, sino diseñadores de analizadores) suelen usar "no libre de contexto" en algunos de los siguientes significados

  • ambiguo
  • no se puede analizar con Bisonte
  • no LL(k), LR(k), LALR (k) o cualquier clase de lenguaje definida por el analizador que hayan elegido

El la gramática en la parte posterior del estándar no satisface estas categorías (es decir, es ambigua, no LL(k)...) así que la gramática de C++ "no está libre de contexto" para ellos. Y en cierto sentido, tienen razón, es muy difícil producir un analizador de C++ que funcione.

Tenga en cuenta que las propiedades aquí utilizadas solo están débilmente conectadas a lenguajes libres de contexto: la ambigüedad no tiene nada que ver con la sensibilidad al contexto (de hecho, las reglas sensibles al contexto típicamente ayudan a desambiguar las producciones), las otras dos son simplemente subconjuntos de lenguajes libres de contexto. Y analizar lenguajes libres de contexto no es un proceso lineal (aunque analizar lenguajes deterministas sí lo es).

 110
Author: jpalecek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-19 19:14:22

Sí. La siguiente expresión tiene un orden de operaciones diferente dependiendo del tipo contexto resuelto :

Editar: Cuando el orden real de operación varía, hace que sea increíblemente difícil usar un compilador "regular" que analiza a un AST sin decorar antes de decorarlo (propagando información de tipo). Otras cosas sensibles al contexto mencionadas son "bastante fáciles" en comparación con esto (no es que la evaluación de plantillas sea del todo fácil).

#if FIRST_MEANING
   template<bool B>
   class foo
   { };
#else
   static const int foo = 0;
   static const int bar = 15;
#endif

Seguido by:

static int foobar( foo < 2 ? 1 < 1 : 0 > & bar );
 60
Author: Sam Harwell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-23 17:08:08

Para responder a tu pregunta, necesitas distinguir dos preguntas diferentes.

  1. La mera sintaxis de casi todos los lenguajes de programación está libre de contexto. Típicamente, se da como una forma extendida de Backus-Naur o gramar libre de contexto.

  2. Sin embargo, incluso si un programa se ajusta al gramar libre de contexto definido por el lenguaje de programación, no es necesariamente un programa válido. Hay muchas poperties sin contexto que un programa tiene que satisfacer en para ser un programa válido. Por ejemplo, la propiedad más simple es el alcance de las variables.

Para concluir, si C++ está libre de contexto o no depende de la pregunta que se haga.

 22
Author: Dan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-29 23:13:56

C++ se analiza con GLR parser. Eso significa que durante el análisis del código fuente, el analizador puede encontrar ambigüedad, pero debe continuar y decidir qué regla gramatical usar más tarde.

Mira también,

¿Por qué C++ no se puede analizar con un analizador LR (1)?


Recuerde que la gramática libre de contexto no puededescribir TODAS las reglas de una sintaxis de lenguaje de programación. Por ejemplo, la gramática de atributos se utiliza para comprobar la validez de un tipo de expresión.

int x;
x = 9 + 1.0;

Usted no puede describir la siguiente regla con gramática libre de contexto : El Lado derecho de la asignación debe ser del mismo tipo que el lado izquierdo.

 10
Author: AraK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:59

Sí, C++ es sensible al contexto, muy sensible al contexto. No puede construir el árbol de sintaxis simplemente analizando el archivo usando un analizador sin contexto porque en algunos casos necesita conocer el símbolo del conocimiento previo para decidir (es decir. construir una tabla de símbolos mientras se analiza).

Primer ejemplo:

A*B;

¿Es esta una expresión de multiplicación?

O

¿Es esta una declaración de variable B para ser un puntero de tipo A?

Si A es a variable, entonces es una expresión, si A es tipo, es una declaración de puntero.

Segundo ejemplo:

A B(bar);

¿Es este un prototipo de función que toma un argumento de tipo bar?

O

¿Se trata de declarar la variable B de tipo A y llama al constructor de A con la constante bar como inicializador?

Necesita saber de nuevo si bar es una variable o un tipo de la tabla de símbolos.

Tercer ejemplo:

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

Este es el caso cuando construir la tabla de símbolos mientras se analiza no ayuda porque la declaración de x e y viene después de la definición de la función. Por lo que necesita escanear a través de la definición de la clase primero, y mirar las definiciones de los métodos en una segunda pasada, para decir x*y es una expresión, y no una declaración de puntero o lo que sea.

 10
Author: Calmarius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-01 10:05:58

Es posible que desee echar un vistazo a El Diseño y la evolución de C++, por Bjarne Stroustrup. En él describe sus problemas tratando de usar yacc (o similar) para analizar una versión temprana de C++, y deseando que hubiera utilizado el descenso recursivo en su lugar.

 10
Author: Matthias Weiler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-05 08:44:55

Tengo la sensación de que hay cierta confusión entre la definición formal de "sensible al contexto" y el uso informal de "sensible al contexto". El primero tiene un significado bien definido. Este último se usa para decir "necesitas contexto para analizar la entrada".

Esto también se pregunta aquí: Sensibilidad al contexto vs Ambigüedad.

Aquí hay una gramática libre de contexto:

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

Es ambiguo, por lo que para analizar la entrada "x" necesita algún contexto (o vivir con ambiguity, or emit "Warning: E8271-Input is ambiguous in line 115"). Pero ciertamente no es una gramática sensible al contexto.

 8
Author: Omri Barel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:58

Ningún lenguaje similar a Algol está libre de contexto, porque tiene reglas que restringen las expresiones y declaraciones en las que los identificadores pueden aparecer en función de su tipo, y porque no hay límite en el número de declaraciones que pueden ocurrir entre la declaración y el uso.

La solución habitual es escribir un analizador sin contexto que realmente acepte un superconjunto de programas válidos y poner las porciones sensibles al contexto en ad hoc código "semántico" adjunto a las reglas.

C++ va mucho más allá de esto, gracias a su sistema de plantillas Turing-complete. Ver Pregunta de desbordamiento de pila 794015.

 5
Author: James Jones,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:37

El caso más simple de gramática sin contexto implica analizar expresiones que involucran plantillas.

a<b<c>()

Esto puede analizarse como

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

O

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

Los dos ASTs solo pueden ser desambiguados examinando la declaración de 'a' the la primera AST si 'a' es una plantilla, o la última si no.

 5
Author: Aaron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-31 08:41:26

Verdadero:)

J. Stanley Warford. sistemas Informáticos. Pages 341-346.
 4
Author: anno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-23 16:37:15

Es sensible al contexto, ya que a b(c); tiene dos parses válidos: declaración y variable. Cuando dices "Si c es un tipo", eso es contexto, justo ahí, y has descrito exactamente cómo C++ es sensible a él. Si no tuvieras ese contexto de " ¿Qué es c?"no se podía analizar esto sin ambigüedades.

Aquí, el contexto se expresa en la elección de tokens - el analizador lee un identificador como un token typename si nombra un tipo. Esta es la resolución más simple, y evita gran parte de la complejidad de ser sensible al contexto (en este caso).

Editar: Hay, por supuesto, más problemas de sensibilidad al contexto, simplemente me he centrado en el que has mostrado. Las plantillas son especialmente desagradables para esto.

 4
Author: Puppy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-29 18:18:35

Las producciones en el estándar C++ están escritas sin contexto, pero como todos sabemos realmente no definen el lenguaje con precisión. Algo de lo que la mayoría de la gente ve como ambigüedad en el lenguaje actual podría (creo) resolverse sin ambigüedades con una gramática sensible al contexto.

Para el ejemplo más obvio, consideremos el Análisis más Irritante: int f(X);. Si X es un valor, entonces esto define f como una variable que se inicializará con X. Si X es un tipo, define f como función que toma un único parámetro de tipo X.

Mirando eso desde un punto de vista gramatical, podríamos verlo así: {[10]]}

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]

Por supuesto, para ser completamente correctos, necesitaríamos agregar algunas "cosas" adicionales para tener en cuenta la posibilidad de intervenir declaraciones de otros tipos (es decir, A y B deberían ser realmente "declaraciones que incluyan la declaración de X como...", o algo en ese orden).

Esto sigue siendo bastante diferente de un CSG típico, aunque (o al menos lo que recuerdo de ellos). Esto depende de que se construya una tabla de símbolos the la parte que reconoce específicamente X como un tipo o valor, no solo algún tipo de instrucción anterior a esto, sino el tipo correcto de instrucción para el símbolo/identificador correcto.

Como tal, tendría que hacer algo para estar seguro, pero mi conjetura inmediata es que esto realmente no califica como CSG, al menos como el término se usa normalmente.

 4
Author: Jerry Coffin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-31 00:01:07
 3
Author: sdcvvc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:03:05

Se ha demostrado que las plantillas de C++ son potentes en Turing. Aunque no es una referencia formal, aquí hay un lugar para mirar en ese sentido:

Http://cpptruths.blogspot.com/2005/11/c-templates-are-turing-complete.html

Voy a aventurar una conjetura (tan antigua como una prueba de CACM folkórica y concisa que muestra que ALGOL en los años 60 no podía ser reproducido por un CFG) y decir que C++ no puede ser analizado correctamente solo por un CFG. CFGs, en conjunción con varios mecanismos de TP en cualquiera un pase de árbol o durante eventos de reducción this esta es otra historia. En un sentido general, debido al Problema de Detención, existe algún programa de C++ que no se puede demostrar que sea correcto/incorrecto, pero no obstante es correcto/incorrecto.

{PS - Como el autor de Meta-S (mencionado por varias personas anteriormente) can puedo decir con toda seguridad que Thothic no está extinto, ni el software está disponible de forma gratuita. Tal vez me he redactado esta versión de mi respuesta que yo no se eliminan o rechazada a -3.}

 3
Author: Quinn Tyler Jackson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-15 20:54:56

C++ no está libre de contexto. Lo aprendí hace algún tiempo en la conferencia de compiladores. Una búsqueda rápida dio este enlace, donde la sección" Sintaxis o semántica " explica por qué C y C++ no están libres de contexto:

Wikipedia Talk: Gramática libre de contexto

Saludos,
Ovanes

 2
Author: ovanes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-23 16:42:18

Obviamente, si se toma la pregunta textualmente, casi todos los idiomas con identificadores son sensibles al contexto.

Uno necesita saber si un identificador es un nombre de tipo (un nombre de clase, un nombre introducido por typedef, un parámetro de plantilla typename), un nombre de plantilla o algún otro nombre para poder usar correctamente el identificador. Por ejemplo:

x = (name)(expression);

Es un cast si name es un nombre de tipo y una llamada a función si name es un nombre de función. Otro caso es el llamado " más vexing parse " donde no es posible diferenciar la definición de variable y la declaración de función (hay una regla que dice que es una declaración de función).

Esa dificultad ha introducido la necesidad de typename y template con nombres dependientes. El resto de C++ no es sensible al contexto por lo que sé (es decir, es posible escribir una gramática libre de contexto para él).

 1
Author: AProgrammer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-23 17:02:05

Meta-S " es un motor de análisis sensible al contexto por Quinn Tyler Jackson. No lo he usado, pero cuenta una historia impresionante. Echa un vistazo a sus comentarios en comp.compiladores, y ver rnaparse.com/MetaS%20defined.htm -Ira Baxter 25 de julio a las 10: 42

El enlace correcto es analizando enigines

Meta-S era propiedad de una compañía extinta llamada Thothic. Puedo enviar una copia gratuita de los Meta-S a cualquier persona interesada y lo he utilizado en la investigación de análisis de arn. Tenga en cuenta la "gramática pseudoknot" incluida en las carpetas de ejemplos fue escrita por un programador no bioinformático y básicamente no funciona. Mis gramáticas tienen un enfoque diferente y funcionan bastante bien.

 1
Author: sth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-19 15:20:54

Esta respuesta dice que C++ no está libre de contexto... hay una implicación (no por parte del respondedor) de que no se puede analizar, y la respuesta ofrece un ejemplo de código difícil que produce un programa C++ no válido si una cierta constante no es un número primo.

Como otros han observado, la pregunta sobre si el lenguaje es sensible al contexto/libre es diferente a la misma pregunta sobre una gramática específica.

Para establecer la pregunta sobre la capacidad de análisis en reposo, I ofrecer evidencia empírica de que hay gramáticas libres de contexto para C++, que se pueden utilizar para producir un AST para un análisis libre de contexto del texto fuente de hecho, analizándolo con una herramienta existente basada en el analizador GLR que está impulsada por una gramática explícita.

Sí, tiene éxito al "aceptar demasiado"; no todo lo que acepta es un programa C++ válido, por lo que es seguido con comprobaciones adicionales (comprobaciones de tipo). Y sí, el comprobador de tipos puede encontrarse con problemas de computabilidad. En la práctica las herramientas no tienen este problema; si la gente escribiera programas como ese, ninguno de ellos compilaría. (Creo que el estándar realmente pone un límite en la cantidad de cómputo que puedes hacer desplegando una plantilla, así que de hecho el cómputo es en realidad finito pero probablemente bastante grande).

Si lo que quiere decir es, determinar si el programa fuente es un miembro del conjunto de programas válidos de código fuente de C++ , entonces el problema es mucho más difícil. Pero no es analizar que es el problema.

La herramienta resuelve este problema aislando el análisis de la comprobación de tipos el programa analizado. (Donde hay múltiples interpretaciones en ausencia de contexto, registra un nodo ambiguity en el árbol de análisis con varios análisis posibles; el tipo la comprobación decide cuál es correcto y elimina el inválido subárboles). Puede ver un árbol de análisis (parcial) en el siguiente ejemplo; el árbol entero es demasiado grande para caber en una respuesta SO. Tenga en cuenta que obtiene un árbol de análisis si se utiliza el valor 234797 o 234799.

Se ejecuta correctamente el solucionador de nombre/tipo de la herramienta sobre el AST con el valor original 234799. Con el valor 234797 el solucionador de nombres falla (como se esperaba) con el mensaje de error, "typen no es un tipo."y por lo tanto esa versión no es un programa válido de 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
 -4
Author: Ira Baxter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:03:05