Cela dépend de la perversité de vos propos. J'ai un programme scc
pour dépouiller les commentaires C et C++. J'ai également un fichier de test pour cela, et j'ai essayé GCC (4.2.1 sur MacOS X) avec les options de la réponse actuellement sélectionnée - et GCC ne semble pas faire un travail parfait sur certains des commentaires horriblement massacrés dans le cas de test.
NB : Il ne s'agit pas d'un problème réel - les gens n'écrivent pas un code aussi épouvantable.
Considérons le (sous-ensemble - 36 des 135 lignes au total) du scénario de test :
/\
*\
Regular
comment
*\
/
The regular C comment number 1 has finished.
/\
\/ This is not a C++/C99 comment!
This is followed by C++/C99 comment number 3.
/\
\
\
/ But this is a C++/C99 comment!
The C++/C99 comment number 3 has finished.
/\
\* This is not a C or C++ comment!
This is followed by regular C comment number 2.
/\
*/ This is a regular C comment *\
but this is just a routine continuation *\
and that was not the end either - but this is *\
\
/
The regular C comment number 2 has finished.
This is followed by regular C comment number 3.
/\
\
\
\
* C comment */
Sur mon Mac, la sortie de GCC ( gcc -fpreprocessed -dD -E subset.c
) est :
/\
*\
Regular
comment
*\
/
The regular C comment number 1 has finished.
/\
\/ This is not a C++/C99 comment!
This is followed by C++/C99 comment number 3.
/\
\
\
/ But this is a C++/C99 comment!
The C++/C99 comment number 3 has finished.
/\
\* This is not a C or C++ comment!
This is followed by regular C comment number 2.
/\
*/ This is a regular C comment *\
but this is just a routine continuation *\
and that was not the end either - but this is *\
\
/
The regular C comment number 2 has finished.
This is followed by regular C comment number 3.
/\
\
\
\
* C comment */
La sortie de 'scc' est :
The regular C comment number 1 has finished.
/\
\/ This is not a C++/C99 comment!
This is followed by C++/C99 comment number 3.
/\
\
\
/ But this is a C++/C99 comment!
The C++/C99 comment number 3 has finished.
/\
\* This is not a C or C++ comment!
This is followed by regular C comment number 2.
The regular C comment number 2 has finished.
This is followed by regular C comment number 3.
La sortie de 'scc -C' (qui reconnaît les commentaires à double barre oblique) est la suivante :
The regular C comment number 1 has finished.
/\
\/ This is not a C++/C99 comment!
This is followed by C++/C99 comment number 3.
The C++/C99 comment number 3 has finished.
/\
\* This is not a C or C++ comment!
This is followed by regular C comment number 2.
The regular C comment number 2 has finished.
This is followed by regular C comment number 3.
Les sources de la SCC sont désormais disponibles sur GitHub
La version actuelle de SCC est 6.60 (datée du 2016-06-12), bien que les versions Git aient été créées le 2017-01-18 (dans le fuseau horaire US/Pacifique). Le code est disponible sur GitHub à l'adresse suivante https://github.com/jleffler/scc-snapshots . Vous pouvez également trouver des instantanés des versions précédentes (4.03, 4.04, 5.05) et deux préversions (6.16, 6.50) - ils sont tous étiquetés release/x.yz
.
Le code est encore principalement développé sous RCS. Je suis encore en train de travailler sur la façon dont je veux utiliser les sous-modules ou un mécanisme similaire pour gérer les fichiers de la bibliothèque commune tels que stderr.c
et stderr.h
(que l'on peut également trouver dans https://github.com/jleffler/soq ).
La version 6.60 de SCC tente de comprendre les constructions C++11, C++14 et C++17 telles que les constantes binaires, la ponctuation numérique, les chaînes de caractères brutes et les flottants hexadécimaux. Il fonctionne par défaut en mode C11. (Notez que la signification de la balise -C
le drapeau - mentionné ci-dessus - a basculé entre la version 4.0x décrite dans le corps de la réponse et la version 6.60 qui est actuellement la dernière version).
5 votes
Il s'agit en fait d'un bon exercice pour utiliser un lexer et un analyseur syntaxique simples !
0 votes
Devons-nous nous attendre à des astuces comme
/*
dans des commentaires ou des chaînes de caractères ?59 votes
Il s'agit en fait d'un bon exercice pour utiliser un lexer et un analyseur syntaxique très compliqués.
0 votes
@pascal oui, je m'attends à beaucoup d'astuces. Je ne veux pas avoir à faire de suppositions.
0 votes
@Neil : c'est ce qui en fait un bon exercice. :)
0 votes
Si drdobbs.com/cpp/184401344 est à croire, vous ne pouvez pas supprimer les commentaires (en attendant les astuces) sans développer les macros.
0 votes
@Mike, tu es sérieusement en train de descendre les gens qui essaient de t'aider ?
0 votes
@stacker non, je n'ai rétrogradé qu'un seul commentaire jusqu'à présent et il était lié à un code terrible.
4 votes
@Pascal : Je ne crois pas le Dr Dobbs, et gcc est d'accord :
error: pasting "/" and "/" does not give a valid preprocessing token
-ce qui est normal, puisque la suppression des commentaires a lieu avant le prétraitement.1 votes
@Neil:en fait, cela ne nécessite qu'un lexer, pas du tout un parser. Et même si un lexer C++ est plus complexe que la plupart des autres, ce n'est pas terriblement difficile. Ne vous méprenez pas : je ne le recommande pas particulièrement par rapport à l'utilisation d'un outil existant -- mais si l'analyse syntaxique était nécessaire, elle serait radicalement plus difficile qu'elle ne l'est en réalité.
0 votes
@Jerry Le préprocesseur a une sémantique, notamment en ce qui concerne les commentaires. Le prétraitement nécessite donc un analyseur syntaxique. C'est pourquoi tous les compilateurs C et C++ modernes intègrent le préprocesseur dans le compilateur.
2 votes
@Neil:désolé, mais non. Un analyseur syntaxique traite de la structure des déclarations. Du point de vue de la langue, un commentaire est un simple jeton qui ne participe pas à une structure plus large. Il n'est pas différent d'un caractère espace (en fait, dans la phase trois de la traduction, chaque commentaire doit être remplacé par un seul caractère espace). Quant à l'intégration du préprocesseur dans le compilateur, l'explication est beaucoup plus simple : le préprocesseur produit souvent des commentaires très complexes. grand site donc la communiquer au compilateur de manière efficace améliore considérablement la vitesse de compilation.
0 votes
@Jerry Je vous réfute ainsi - /* ... */ ne peuvent pas être traités par un simple lexer. Vous semblez confondre le langage avec l'implémentation.
1 votes
@Neil:Désolé, mais non. Oui, les commentaires de style C peuvent être gérés par un lexer. Je ne fais pas l'amalgame entre le langage et l'implémentation : Je vous dis simplement ce que je sais par expérience - j'ai écrit sur un lexer pour C et C++ qui traite les deux styles de commentaires parfaitement bien. Bien que cela ne soit pas trivial selon la plupart des standards, comparé à un analyseur C++, "trivial" est exactement ce que c'est.
0 votes
Jerry Comme vous, j'ai écrit un lexer (et un compilateur) pour le C. Et comme vous, je sais ce que fait un lexer - il produit un flux de tokens (ou lexèmes, si l'on veut être pédant). Ce qu'un lexeur ne fait pas, c'est effectuer une analyse sémantique, ce qui est nécessaire pour gérer les commentaires de bloc. C'est mon dernier message sur ce sujet.
7 votes
@Neil : C'est peut-être mieux ainsi. Vous semblez simplement répéter la même affirmation, sans preuve à l'appui. Vous n'avez même pas indiqué une seule fois quelle analyse sémantique est, selon vous, nécessaire pour analyser correctement les commentaires, vous avez juste répété qu'elle l'est (ce que la norme non seulement n'exige pas, mais ne permet même pas). Vous substituez des trigraphes, vous coupez des lignes, puis vous décomposez la source en mots et en séquences d'espaces blancs (y compris les commentaires). Si vous essayez de prendre en compte plus de sémantique que cela, vous vous y prenez mal...
0 votes
Notre objectif n'est-il pas habituellement d'obtenir plus de commentaires dans le code ?
0 votes
ma réponse gère tous les cas pratiques. Il fonctionne parfaitement, à condition que
/*
,//
,*/
ne se divisent pas en deux lignes. Ce qui est essentiellement une machine à état avec des états : 1 partie de chaîne littérale, 2 partie de commentaire de style C, 3 partie de commentaire de style C++, 4 autre. Gère aussi la continuation de ligne.0 votes
Voir stackoverflow.com/a/13062682/1745001 pour savoir comment le faire de manière robuste (et simple).