J'entends souvent des affirmations selon lesquelles le C ++ est un langage contextuel. Prenons l'exemple suivant:
a b(c);
S'agit-il d'une définition de variable ou d'une déclaration de fonction? Cela dépend de la signification du symbole c
. Si c
est une variable , a b(c);
définit alors une variable nommée b
de type a
. Il est directement initialisé avec c
. Mais si c
est un type , alors a b(c);
déclare une fonction nommée b
qui prend un c
et retourne un a
.
Si vous recherchez la définition de langages sans contexte, cela vous indiquera essentiellement que toutes les règles de grammaire doivent avoir des côtés gauches constitués d'exactement un symbole non terminal. Les grammaires contextuelles, en revanche, autorisent des chaînes arbitraires de symboles terminaux et non terminaux sur le côté gauche.
En parcourant l'annexe A de "Le langage de programmation C ++", je n'ai pas pu trouver une seule règle de grammaire qui avait autre chose qu'un seul symbole non terminal sur son côté gauche. Cela impliquerait que C ++ est sans contexte. (Bien sûr, chaque langue sans contexte est également contextuelle en ce sens que les langues sans contexte forment un sous-ensemble des langues contextuelles, mais ce n'est pas le but.)
Alors, le C ++ est-il sans contexte ou sensible au contexte?
la source
Réponses:
Ci-dessous est ma démonstration préférée (actuelle) de la raison pour laquelle l'analyse C ++ est (probablement) Turing-complète , car elle montre un programme qui est syntaxiquement correct si et seulement si un entier donné est premier.
J'affirme donc que C ++ n'est ni sans contexte ni sensible au contexte .
Si vous autorisez des séquences de symboles arbitraires des deux côtés d'une production, vous produisez une grammaire de type 0 ("sans restriction") dans la hiérarchie Chomsky , qui est plus puissante qu'une grammaire contextuelle; les grammaires libres sont Turing-complete. Une grammaire contextuelle (Type-1) autorise plusieurs symboles de contexte sur le côté gauche d'une production, mais le même contexte doit apparaître sur le côté droit de la production (d'où le nom "context-sensitive"). [1] Les grammaires contextuelles sont équivalentes aux machines de Turing à limites linéaires .
Dans l'exemple de programme, le calcul principal pourrait être effectué par une machine de Turing linéaire, donc cela ne prouve pas tout à fait l'équivalence de Turing, mais l'important est que l'analyseur doit effectuer le calcul afin d'effectuer une analyse syntaxique. Il aurait pu s'agir de n'importe quel calcul exprimable sous forme d'instanciation de modèle et il y a tout lieu de croire que l'instanciation de modèle C ++ est Turing-complete. Voir, par exemple, l'article de Todd L. Veldhuizen de 2003 .
Quoi qu'il en soit, C ++ peut être analysé par un ordinateur, il pourrait donc certainement être analysé par une machine de Turing. Par conséquent, une grammaire illimitée pourrait le reconnaître. En fait, écrire une telle grammaire ne serait pas pratique, c'est pourquoi la norme n'essaie pas de le faire. (Voir ci-dessous.)
Le problème de «l'ambiguïté» de certaines expressions est principalement un hareng rouge. Pour commencer, l'ambiguïté est une caractéristique d'une grammaire particulière, pas une langue. Même s'il peut être prouvé qu'une langue n'a pas de grammaires sans ambiguïté, si elle peut être reconnue par une grammaire sans contexte, elle est sans contexte. De même, si elle ne peut pas être reconnue par une grammaire hors contexte mais qu'elle peut être reconnue par une grammaire contextuelle, elle est contextuelle. L'ambiguïté n'est pas pertinente.
Mais de toute façon, comme la ligne 21 (ie
auto b = foo<IsPrime<234799>>::typen<1>();
) dans le programme ci-dessous, les expressions ne sont pas du tout ambiguës; ils sont simplement analysés différemment selon le contexte. Dans l'expression la plus simple du problème, la catégorie syntaxique de certains identificateurs dépend de la façon dont ils ont été déclarés (types et fonctions, par exemple), ce qui signifie que le langage formel devrait reconnaître le fait que deux chaînes de longueur arbitraire dans les mêmes programmes sont identiques (déclaration et utilisation). Cela peut être modélisé par la grammaire "copie", qui est la grammaire qui reconnaît deux copies exactes consécutives du même mot. C'est facile à prouver avec le lemme de pompageque cette langue n'est pas sans contexte. Une grammaire contextuelle pour cette langue est possible, et une grammaire de type 0 est fournie dans la réponse à cette question: /math/163830/context-sensitive-grammar-for-the- copie-langue .Si l'on tentait d'écrire une grammaire contextuelle (ou non restreinte) pour analyser le C ++, cela remplirait très probablement l'univers de gribouillages. Écrire une machine de Turing pour analyser le C ++ serait une entreprise tout aussi impossible. Même l'écriture d'un programme C ++ est difficile, et pour autant que je sache, aucun n'a été prouvé correct. C'est pourquoi la norme n'essaie pas de fournir une grammaire formelle complète, et pourquoi elle choisit d'écrire certaines des règles d'analyse en anglais technique.
Ce qui ressemble à une grammaire formelle dans la norme C ++ n'est pas la définition formelle complète de la syntaxe du langage C ++. Ce n'est même pas la définition formelle complète de la langue après le prétraitement, qui pourrait être plus facile à formaliser. (Ce ne serait pas le langage, cependant: le langage C ++ tel que défini par la norme inclut le préprocesseur, et le fonctionnement du préprocesseur est décrit de manière algorithmique car il serait extrêmement difficile à décrire dans n'importe quel formalisme grammatical. C'est dans cette section de la norme où la décomposition lexicale est décrite, y compris les règles où elle doit être appliquée plus d'une fois.)
Les différentes grammaires (deux grammaires qui se chevauchent pour l'analyse lexicale, l'une qui a lieu avant le prétraitement et l'autre, si nécessaire, par la suite, plus la grammaire "syntaxique") sont rassemblées dans l'annexe A, avec cette note importante (non souligné dans l'original):
Enfin, voici le programme promis. La ligne 21 est syntaxiquement correcte si et seulement si N in
IsPrime<N>
est premier. Sinon, iltypen
s'agit d'un entier et non d'un modèle, iltypen<1>()
est donc analysé comme(typen<1)>()
étant syntaxiquement incorrect car il()
ne s'agit pas d'une expression syntaxiquement valide.[1] Pour le dire plus techniquement, chaque production dans une grammaire contextuelle doit être de la forme:
αAβ → αγβ
où
A
est un non-terminal etα
,β
sont éventuellement des séquences vides de symboles de grammaire, etγ
est une séquence non-vide. (Les symboles de grammaire peuvent être terminaux ou non terminaux).Cela peut être lu
A → γ
uniquement dans le contexte[α, β]
. Dans une grammaire sans contexte (Type 2),α
etβ
doit être vide.Il s'avère que vous pouvez également restreindre les grammaires avec la restriction "monotone", où chaque production doit être de la forme:
α → β
où|α| ≥ |β| > 0
(|α|
signifie "la longueur deα
")Il est possible de prouver que l'ensemble des langues reconnues par les grammaires monotones est exactement le même que l'ensemble des langues reconnues par les grammaires contextuelles, et il arrive souvent qu'il soit plus facile de baser les preuves sur des grammaires monotones. Par conséquent, il est assez courant de voir «sensible au contexte» utilisé comme s'il signifiait «monotone».
la source
0
intérieur()
, pour un simple), mais je pense que c'est plus intéressant de cette façon, car cela démontre que vous avez besoin de l'instanciation du modèle même pour reconnaître si une chaîne est un programme C ++ syntaxiquement correct. Si les deux branches se compilent, je devrais travailler plus fort pour contester l'argument selon lequel la différence est "sémantique". Curieusement, bien que je sois souvent mis au défi de définir "syntaxique", personne n'a jamais proposé une définition de "sémantique" autre que "des choses que je ne pense pas être syntaxiques" :)Tout d'abord, vous avez observé à juste titre qu'il n'y a pas de règles contextuelles dans la grammaire à la fin de la norme C ++, de sorte que la grammaire est hors contexte.
Cependant, cette grammaire ne décrit pas précisément le langage C ++, car elle produit des programmes non C ++ tels que
ou
Le langage C ++ défini comme "l'ensemble des programmes C ++ bien formés" n'est pas dépourvu de contexte (il est possible de montrer que le simple fait de demander des variables à déclarer le rend possible). Étant donné que vous pouvez théoriquement écrire des programmes complets de Turing dans des modèles et rendre un programme mal formé en fonction de leur résultat, il n'est même pas sensible au contexte.
Maintenant, les gens (ignorants) (généralement pas les théoriciens du langage, mais les concepteurs d'analyseurs) utilisent généralement "non context-free" dans certaines des significations suivantes
La grammaire à l'arrière de la norme ne satisfait pas ces catégories (c'est-à-dire qu'elle est ambiguë, pas LL (k) ...) donc la grammaire C ++ n'est "pas sans contexte" pour eux. Et dans un sens, ils ont raison, il est sacrément difficile de produire un analyseur C ++ fonctionnel.
Notez que les propriétés utilisées ici ne sont que faiblement connectées aux langages sans contexte - l'ambiguïté n'a rien à voir avec la sensibilité au contexte (en fait, les règles contextuelles aident généralement à lever l'ambiguïté des productions), les deux autres ne sont que des sous-ensembles de contexte -langues libres. Et l'analyse des langages sans contexte n'est pas un processus linéaire (bien que l'analyse des langages déterministes le soit).
la source
ambiguity doesn't have anything to do with context-sensitivity
C'était aussi mon intuition, donc je suis heureux de voir quelqu'un (a) d'accord, et (b) l'expliquer là où je ne pouvais pas. Je crois que cela disqualifie tous les arguments qui sont basés sura b(c);
, et satisfont partiellement la question originale dont la prémisse était des affirmations "souvent entendues" de sensibilité au contexte étant dues à l'ambiguïté ... surtout quand pour la grammaire il n'y a en fait aucune ambiguïté même dans le MVP.Oui. L'expression suivante a un ordre d'opérations différent selon le type de contexte résolu :
Edit: Lorsque l'ordre réel des opérations varie, il est extrêmement difficile d'utiliser un compilateur "normal" qui analyse un AST non décoré avant de le décorer (propagation des informations de type). D'autres éléments sensibles au contexte mentionnés sont "plutôt faciles" par rapport à cela (pas que l'évaluation du modèle soit du tout facile).
Suivi par:
la source
Pour répondre à votre question, vous devez distinguer deux questions différentes.
La simple syntaxe de presque tous les langages de programmation est sans contexte. Typiquement, il est donné sous forme de Backus-Naur étendu ou de gramme sans contexte.
Cependant, même si un programme est conforme à la grammaire sans contexte définie par le langage de programmation, ce n'est pas nécessairement un programme valide . Il existe de nombreuses propriétés non contextuelles qu'un programme doit satisfaire pour être un programme valide. Par exemple, la propriété la plus simple est l'étendue des variables.
Pour conclure, que le C ++ soit ou non dépendant du contexte dépend de la question que vous posez.
la source
VARDECL : TYPENAME IDENTIFIER
, mais vous ne pouvez pas l' avoir, car vous ne pouvez pas distinguer les noms de type des autres identificateurs au niveau CF. Autre exemple: au niveau CF, vous ne pouvez pas décider si vous souhaitez analysera*b
une déclaration de variable (b
de type pointeur versa
) ou une multiplication.Vous voudrez peut-être jeter un œil à La conception et l'évolution du C ++ , par Bjarne Stroustrup. Dans ce document, il décrit ses problèmes en essayant d'utiliser yacc (ou similaire) pour analyser une version antérieure de C ++, et souhaitant qu'il ait plutôt utilisé une descente récursive.
la source
Ouais C ++ est sensible au contexte, très sensible au contexte. Vous ne pouvez pas construire l'arborescence de syntaxe en analysant simplement le fichier à l'aide d'un analyseur sans contexte, car dans certains cas, vous devez connaître le symbole à partir des connaissances précédentes pour décider (c'est-à-dire créer une table de symboles pendant l'analyse).
Premier exemple:
Est-ce une expression de multiplication?
OU
Est-ce une déclaration de
B
variable pour être un pointeur de typeA
?Si A est une variable, alors c'est une expression, si A est de type, c'est une déclaration de pointeur.
Deuxième exemple:
Est-ce un prototype de fonction prenant un argument de
bar
type?OU
Est-ce que déclarer variable
B
de typeA
et appelle le constructeur de A avecbar
constante comme initialiseur?Vous devez savoir à nouveau si
bar
s'agit d'une variable ou d'un type de la table des symboles.Troisième exemple:
C'est le cas lorsque la construction d'une table de symboles pendant l'analyse n'aide pas car la déclaration de x et y vient après la définition de la fonction. Donc, vous devez d'abord parcourir la définition de classe et regarder les définitions de méthode dans un deuxième passage, pour dire que x * y est une expression, et non une déclaration de pointeur ou autre.
la source
A B();
est une déclaration de fonction même dans une définition de fonction. Recherchez la plupart desC ++ est analysé avec l'analyseur GLR. Cela signifie que lors de l'analyse du code source, l'analyseur peut rencontrer une ambiguïté mais il doit continuer et décider quelle règle de grammaire utiliser plus tard .
regarde aussi,
Pourquoi C ++ ne peut pas être analysé avec un analyseur LR (1)?
N'oubliez pas que la grammaire sans contexte ne peut pas décrire TOUTES les règles d'une syntaxe de langage de programmation. Par exemple, la grammaire des attributs est utilisée pour vérifier la validité d'un type d'expression.
Vous ne pouvez pas décrire la règle suivante avec une grammaire sans contexte: le côté droit de l'affectation doit être du même type que le côté gauche.
la source
J'ai l'impression qu'il y a une certaine confusion entre la définition formelle de "contextuelle" et l'utilisation informelle de "contextuelle". Le premier a un sens bien défini. Ce dernier est utilisé pour dire "vous avez besoin de contexte pour analyser l'entrée".
Cette question est également posée ici: sensibilité au contexte vs ambiguïté .
Voici une grammaire sans contexte:
C'est ambigu, donc pour analyser l'entrée "x", vous avez besoin d'un peu de contexte (ou vivre avec l'ambiguïté, ou émettre "Avertissement: E8271 - L'entrée est ambiguë à la ligne 115"). Mais ce n'est certainement pas une grammaire contextuelle.
la source
Aucun langage de type algol n'est sans contexte, car il a des règles qui contraignent les expressions et les instructions dans lesquelles les identifiants peuvent apparaître en fonction de leur type, et parce qu'il n'y a pas de limite au nombre d'instructions qui peuvent se produire entre la déclaration et l'utilisation.
La solution habituelle consiste à écrire un analyseur sans contexte qui accepte réellement un surensemble de programmes valides et à mettre les parties contextuelles en ad hoc code "sémantique" attaché aux règles.
C ++ va bien au-delà, grâce à son système de templates Turing-complete. Voir question de dépassement de pile 794015 .
la source
Vrai :)
J. Stanley Warford. Systèmes informatiques . Pages 341-346.
la source
Parfois, c'est pire: que veulent dire les gens quand ils disent que C ++ a une "grammaire indécidable"?
la source
Il est sensible au contexte, tout comme
a b(c);
deux déclarations et variable d'analyse valides. Lorsque vous dites "sic
c'est un type", c'est le contexte, juste là, et vous avez décrit exactement comment C ++ y est sensible. Si vous n'aviez pas ce contexte de "ce qui estc
?" vous ne pouviez pas analyser cela sans ambiguïté.Ici, le contexte est exprimé dans le choix des jetons - l'analyseur lit un identifiant comme un jeton de nom de type s'il nomme un type. Il s'agit de la résolution la plus simple et évite une grande partie de la complexité d'être sensible au contexte (dans ce cas).
Edit: Il y a, bien sûr, plus de problèmes de sensibilité au contexte, je me suis simplement concentré sur celui que vous avez montré. Les modèles sont particulièrement désagréables pour cela.
la source
a<b<c>>d
, non? (Votre exemple est en fait un classique de C , où c'est le seul obstacle à être hors contexte.)Les productions dans la norme C ++ sont écrites sans contexte, mais comme nous le savons tous, ne définissent pas vraiment le langage avec précision. Une partie de ce que la plupart des gens considèrent comme une ambiguïté dans la langue actuelle pourrait (je crois) être résolue sans ambiguïté avec une grammaire contextuelle.
Pour exemple le plus évident, considérons le plus contrariant Parse:
int f(X);
. SiX
est une valeur, celle-ci se définitf
comme une variable qui sera initialisée avecX
. SiX
est un type, il se définitf
comme une fonction prenant un seul paramètre de typeX
.En regardant cela d'un point de vue grammatical, nous pourrions le voir comme ceci:
Bien sûr, pour être tout à fait correct, nous aurions besoin d'ajouter des "trucs" supplémentaires pour tenir compte de la possibilité d'intervenir sur des déclarations d'autres types (c'est-à-dire que A et B devraient tous deux être réellement des "déclarations comprenant la déclaration de X comme ..." , ou quelque chose sur cet ordre).
C'est encore assez différent d'un CSG typique (ou du moins ce que je me souviens d'eux). Cela dépend de la construction d'une table de symboles - la partie qui reconnaît spécifiquement
X
comme un type ou une valeur, pas seulement un type de déclaration qui précède, mais le type de déclaration correct pour le bon symbole / identificateur.En tant que tel, je devrais faire quelques recherches pour en être sûr, mais ma supposition immédiate est que cela ne se qualifie pas vraiment en tant que CSG, du moins comme le terme est normalement utilisé.
la source
Le cas le plus simple de la grammaire non contextuelle implique l'analyse des expressions impliquant des modèles.
Cela peut analyser comme
Ou
Les deux AST ne peuvent être désambiguïsés qu'en examinant la déclaration de «a» - l'ancienne AST si «a» est un modèle, ou la seconde sinon.
la source
<
doivent être une parenthèse si cela est possible (par exemple, il suit un identifiant qui nomme un modèle). C ++ 11 a ajouté l'exigence selon laquelle>
le premier caractère doit>>
être interprété comme des crochets si cette utilisation est plausible. Cela affecte l'analyse de l'a<b>c>
emplacement d'a
un modèle mais n'a aucun effet sura<b<c>
.a();
(qui est soitexpr.call
ouexpr.type.conv
)?Il a été démontré que les modèles C ++ sont puissants de Turing. Bien qu'il ne s'agisse pas d'une référence officielle, voici un endroit où chercher à cet égard:
http://cpptruths.blogspot.com/2005/11/c-templates-are-turing-complete.html
Je vais tenter une supposition (aussi ancienne qu'une preuve CACM folkorique et concise montrant qu'ALGOL dans les années 60 ne pouvait pas être représenté par un CFG) et dire que C ++ ne peut donc pas être correctement analysé uniquement par un CFG. CFG, en conjonction avec divers mécanismes de TP dans une passe d'arbre ou lors d'événements de réduction - c'est une autre histoire. Dans un sens général, en raison du problème d'arrêt, il existe un programme C ++ qui ne peut pas être démontré comme étant correct / incorrect mais qui est néanmoins correct / incorrect.
{PS- En tant qu'auteur de Meta-S (mentionné par plusieurs personnes ci-dessus) - Je peux très certainement dire que Thothic n'est ni disparu, ni le logiciel disponible gratuitement. J'ai peut-être rédigé cette version de ma réponse de manière à ne pas me faire supprimer ou voter à -3.}
la source
C ++ n'est pas sans contexte. Je l'ai appris il y a quelque temps lors d'une conférence sur les compilateurs. Une recherche rapide a donné ce lien, où la section "Syntaxe ou sémantique" explique pourquoi C et C ++ ne sont pas sans contexte:
Wikipédia Talk: Grammaire sans contexte
Cordialement,
Ovanes
la source
De toute évidence, si vous prenez la question mot pour mot, presque toutes les langues avec des identificateurs sont sensibles au contexte.
Il faut savoir si un identifiant est un nom de type (un nom de classe, un nom introduit par typedef, un paramètre de modèle de nom de type), un nom de modèle ou un autre nom pour pouvoir correctement utiliser une partie de l'identifiant. Par exemple:
est un cast si
name
est un nom de type et un appel de fonction siname
est un nom de fonction. Un autre cas est ce que l'on appelle "l'analyse la plus dérangeante" où il n'est pas possible de différencier la définition de variable et la déclaration de fonction (il existe une règle disant qu'il s'agit d'une déclaration de fonction).Cette difficulté a introduit le besoin de
typename
ettemplate
avec des noms dépendants. Le reste de C ++ n'est pas sensible au contexte pour autant que je sache (c'est-à-dire qu'il est possible d'écrire une grammaire sans contexte pour cela).la source
Le lien correct est l' analyse des énigines
Meta-S était la propriété d'une ancienne société appelée Thothic. Je peux envoyer une copie gratuite du Meta-S à toute personne intéressée et je l'ai utilisée dans la recherche d'analyse d'ARN. Veuillez noter que la "grammaire pseudoknot" incluse dans les dossiers d'exemples a été écrite par un programmeur non bioinformatique et amateur et ne fonctionne pas. Mes grammaires ont une approche différente et fonctionnent assez bien.
la source
Un gros problème ici est que les termes «sans contexte» et «sensible au contexte» sont un peu peu intuitifs en informatique. Pour C ++, la sensibilité au contexte ressemble beaucoup à l'ambiguïté, mais ce n'est pas nécessairement vrai dans le cas général.
En C / ++, une instruction if n'est autorisée qu'à l'intérieur d'un corps de fonction. Cela semblerait le rendre contextuel, non? Et bien non. Les grammaires sans contexte n'ont pas réellement besoin de la propriété où vous pouvez extraire une ligne de code et déterminer si elle est valide. Ce n'est pas vraiment ce que signifie sans contexte. C'est vraiment juste une étiquette qui implique vaguement quelque chose de lié à ce à quoi ça ressemble.
Maintenant, si une instruction dans un corps de fonction est analysée différemment selon quelque chose défini en dehors des ancêtres grammaticaux immédiats (par exemple, si un identifiant décrit un type ou une variable), comme dans le
a * b;
cas, alors, il est, en fait, contextuel. Il n'y a aucune ambiguïté réelle ici; il sera analysé comme une déclaration d'un pointeur sia
est un type et une multiplication sinon.Être sensible au contexte ne signifie pas nécessairement «difficile à analyser». C n'est en fait pas si difficile car la fameuse
a * b;
"ambiguïté" peut être résolue avec une table de symboles contenanttypedef
s rencontrés précédemment. Il ne nécessite aucune instanciation de modèle arbitraire (qui s'est avéré être Turing Complete) pour résoudre ce cas comme le fait C ++ à l'occasion. Il n'est en fait pas possible d'écrire un programme C qui ne se compilera pas en un temps limité, même s'il a la même sensibilité au contexte que C ++.Python (et d'autres langages sensibles aux espaces blancs) est également dépendant du contexte, car il nécessite un état dans le lexer pour générer des jetons de retrait et de retrait, mais cela ne rend pas l'analyse plus difficile qu'une grammaire LL-1 typique. Il utilise en fait un générateur d'analyseur syntaxique, ce qui explique pourquoi Python a de tels messages d'erreur de syntaxe non informative. Il est également important de noter ici qu'il n'y a pas "d'ambiguïté" comme le
a * b;
problème en Python, donnant un bon exemple concret d'un langage contextuel sans grammaire "ambiguë" (comme mentionné dans le premier paragraphe).la source
Cette réponse dit que C ++ n'est pas sans contexte ... il y a une implication (pas par le répondeur) qu'il ne peut pas être analysé, et la réponse offre un exemple de code difficile qui produit un programme C ++ invalide si une certaine constante n'est pas un nombre premier.
Comme d'autres l'ont observé, la question de savoir si la langue est contextuelle / libre est différente de la même question concernant une grammaire spécifique.
Pour poser la question de la paralysie, je propose des preuves empiriques qu'il existe des grammaires sans contexte pour C ++, qui peuvent être utilisées pour produire un AST pour une analyse sans contexte du texte source en analysant en fait celui-ci avec un GLR existant -un outil basé sur l'analyseur qui est piloté par une grammaire explicite.
Oui, elle réussit en «acceptant trop»; tout ce qu'il accepte n'est pas un programme C ++ valide, c'est pourquoi il est suivi de vérifications supplémentaires (vérifications de type). Et oui, le vérificateur de type peut rencontrer des problèmes de calculabilité. Dans la pratique, les outils n'ont pas ce problème; si les gens écrivaient des programmes comme ça, aucun ne compilerait. (Je pense que la norme limite en fait la quantité de calcul que vous pouvez faire en dépliant un modèle, donc en fait le calcul est en fait fini mais probablement assez gros).
Si vous voulez dire, déterminez si le programme source est membre de l'ensemble des programmes source C ++ valides , je conviendrai que le problème est beaucoup plus difficile. Mais ce n'est pas l' analyse qui est le problème.
L'outil résout ce problème en isolant l'analyse de la vérification de type du programme analysé. (Lorsqu'il y a plusieurs interprétations en l'absence de contexte, il enregistre un nœud d' ambiguïté dans l'arbre d'analyse avec plusieurs analyses possibles; la vérification de type décide laquelle est correcte et élimine les sous-arbres invalides). Vous pouvez voir un arbre d'analyse (partiel) dans l'exemple ci-dessous; l'arbre entier est trop grand pour tenir dans une réponse SO. Notez que vous obtenez un arbre d'analyse, que la valeur 234797 ou 234799 soit utilisée.
L'exécution du résolveur de nom / type de l'outil sur l'AST avec la valeur d'origine 234799 réussit. Avec la valeur 234797, le résolveur de nom échoue (comme prévu) avec le message d'erreur "typen n'est pas un type". et donc cette version n'est pas un programme C ++ valide.
la source