2009-06-15 6 views
1

J'essaie d'extraire les espaces de noms définis dans les fichiers C++.
En gros, si mon fichier C++ contient:Utilisation de regex python pour extraire des espaces de noms à partir de sources C++

 
namespace n1 { 
    ... 
    namespace n2 { ... } // end namespace n2 
    ... 
    namespace n3 { ...} //end namespace n3 
    ... 
} //end namespace n1 

Je veux être en mesure de récupérer: n1, n1 :: n2, n1 :: n3.

Quelqu'un at-il une suggestion sur la façon dont je pourrais faire cela en utilisant python-regex?

Merci.

Répondre

6

La recherche des noms d'espace de nom est assez facile avec une expression régulière. Toutefois, pour déterminer le niveau d'imbrication, vous devez suivre le niveau d'imbrication des accolades dans le fichier source. C'est un problème d'analyse, qui ne peut pas être résolu (sainement) avec des expressions régulières. En outre, vous devrez peut-être gérer toutes les directives du préprocesseur C dans le fichier, ce qui peut certainement affecter l'analyse.

C++ est un langage notoirement difficile à analyser complètement, mais vous pouvez vous en sortir avec un tokeniser et un compteur de parenthèses.

+0

Cela confirme ce que j'étais inquiet. Je crois que je vais suivre votre suggestion: en utilisant regex pour extraire les noms d'espaces de noms et une autre façon de gérer le niveau de parenthèse bouclés. À ce stade, j'ignorerai les directives du préprocesseur C. Merci pour la réponse. –

+1

Notez que vous pouvez exécuter votre source via cpp (le préprocesseur) et gérer uniquement le code C++ comme le compilateur le verra, mais cela signifie que vous verrez également les déclarations d'espace de noms #include à travers les fichiers d'en-tête (par exemple std). –

1

Vous ne pouvez pas ignorer complètement les directives de préprocesseur, car elles peuvent introduire des espaces de noms supplémentaires. J'ai vu beaucoup de code comme:

#define __NAMESPACE_SYSTEM__ namespace system 

__NAMESPACE_SYSTEM__ { 
    // actual code here... 
} 

Pourtant, je ne vois aucune raison d'utiliser ces directives, autre que de vaincre la stratégie analyse d'expression régulière ...

0

La plupart du temps quand quelqu'un demande comment faire quelque chose avec regex, ils font quelque chose de très mal. Je ne pense pas que ce cas soit différent.

Si vous souhaitez analyser C++, vous devez utiliser un analyseur C++. Il y a beaucoup de choses qui peuvent être faites qui vaincre une regex mais qui restent valides en C++.

1

Vous pouvez écrire un lexeur de base pour cela. Ce n'est pas si dur.

2

Le besoin est assez simple pour que vous n'ayez pas besoin d'un analyseur complexe. Vous devez:

  • extrait les noms d'espace de noms
  • compter les accolades d'ouverture/fermeture de garder une trace de l'endroit où votre espace de noms est défini.

Cette approche simple fonctionne si les autres conditions sont remplies:

  • vous ne recevez pas l'espace de noms fallacieux comme des chaînes à l'intérieur des commentaires ou des chaînes à l'intérieur
  • vous ne sont pas inégalés accolades ouvertes/closeing à l'intérieur des commentaires ou des chaînes

Je ne pense pas que cela demande trop de votre source.

0

Ce que j'ai fait plus tôt aujourd'hui:

  • Extrait du commentaire sur les fichiers C++
  • Utilisez regex pour extraire la définition d'espace de noms
  • Utilisez une simple recherche de chaîne pour obtenir le & ouvrir fermer accolades positions

Les différents contrôle de santé mentale montrent ajouté que je suis en train de traiter avec succès 99,925% de mes fichiers (5 échecs de 6678 fichiers ouf). Les problèmes sont dus à des incompatibilités dans les nombres de {et} cause par quelques '{' ou '}' dans les chaînes, et à une utilisation non propre de l'instruction du préprocesseur.

Cependant, je ne traite que les fichiers d'en-tête, et je possède le code. Cela limite le nombre de scénarios qui pourraient causer des problèmes et je peux modifier manuellement ceux que je ne couvre pas.

Bien sûr, je sais qu'il y a beaucoup de cas où cela échouerait mais c'est probablement suffisant pour ce que je veux réaliser.

Merci pour vos réponses.

Questions connexes