2008-11-14 6 views
0

Actuellement, j'ai un certain code hérité, qui génère le code op. Si le code a plus de nombre de macros alors la génération de code prend tellement de temps (en termes d'heures !!). Je suis passé par la logique, ils manipulent la macro en la recherchant et en faisant un remplacement de chaque variable dans quelque chose comme inline.
Existe-t-il un moyen de l'optimiser sans manipuler la chaîne?Macro remplacement pendant la génération de code

+0

lol. De quoi diable parlez-vous? quelles macros, codes d'opération et quelle génération de code? et quelle chaîne? –

+0

Pouvez-vous poster un exemple pour rendre votre question plus facile à comprendre? –

+0

Quel compilateur utilisez-vous ou faites-vous référence à un pré-processeur interne? –

Répondre

1

Vous devez de marquer votre entrée avant de commencer ce type de processus. (Je ne peux pas recommander le fameux Dragon Book assez - même l'édition ancienne a résisté à l'épreuve du temps, la version mise à jour de 2006 semble bien).La compilation est le type de travail qui se divise le mieux en phases plus petites: si votre première phase exécute une analyse lexicale en jetons, divise des lignes en mots-clés, identifiants, constantes, etc., il est beaucoup plus simple de trouver les références aux macros. dans une table de symboles. (Il est également relativement plus facile d'utiliser un outil comme Lex ou Flex ou l'un de leurs équivalents modernes pour faire ce travail pour vous, que d'essayer de le faire à partir de zéro). Le 'indice' semble être si le code a plus de macros alors la génération du code prend tellement de temps. Cela semble que le processus est linéaire dans le nombre de macros, ce qui est certainement trop. Je suppose que ce processus se produit une ligne à la fois (si votre langage le permet, évidemment cela a une énorme valeur, puisque vous n'avez pas besoin de traiter le programme comme une énorme chaîne), et le pseudocode ressemble à

for(each line in the program) 
{ 
    for(each macro definition) 
    { 
     test if the macro appears; 
     perform replacement if needed; 
    } 
} 

Cela correspond clairement au nombre de définitions de macros.

Avec tokenization, il ressemble à ceci:

for(each line in the program) 
{ 
    tokenize the line; 
    for(each token in the line) 
    { 
     switch(based on the token type) 
     { 
      case(an identifier) 
       lookup the identifier in the table of macro names; 
       perform replacement as necessary; 
      .... 
     } 
    } 
} 

qui adapte la plupart du temps avec la taille du programme (et non le nombre de définitions) - la recherche de la table des symboles peut bien sûr être fait avec des données plus optimale structures que de boucler à travers eux tous, de sorte que ne devient plus le facteur significatif. Cette deuxième étape est quelque chose que les programmes comme yacc et bison (et leurs variantes plus modernes) peuvent générer du code.

après coup: lors de l'analyse des macro définitions, vous pouvez enregistrer en utilisant un flux jeton ainsi, et marquer les identifiants qui sont les noms « d'espace réservé » pour le remplacement des paramètres. Lorsque vous développez une macro, passez à ce flux de jetons. (Encore une fois, quelque chose que Flex peut facilement faire).

0

J'ai une application qui a son propre grammeur. Il supporte tous les types de types de données qu'un compilateur typique supporte (même les macros). Plus précisément, c'est un type de compilateur qui génère les opcodes en prenant un programme (qui est écrit en utilisant ce grammeur) comme entrée. Pour manipuler les macros, il utilise la logique de remplacement de texte Par exemple:

Ajouter Macro (a: int, b: int)

int c = a + b 

Fin Macro

// Programme Somme

int x = 10, y = 10;

Ajouter (x, y);

..

// Fin du programme

Après remplacement, il sera

// Programme Somme

..

int x = 10, y = dix;

int c = x + y

..

// Fin du programme

Ce remplacement de texte prend tellement de temps à savoir le remplacement de l'appel de macro avec la logique macro. Existe-t-il un moyen optimal de le faire?

+0

Si vous prenez votre fichier entier dans un fichier std :: String, il n'est pas étonnant que le remplacement de macros dans un fichier volumineux prenne du temps. peut-être avoir chaque ligne de code comme un élément dans une deque. le remplacement est beaucoup de facette alors je suppose –

0

Il est vraiment difficile de répondre sans connaître davantage votre processus de préprocesseur/analyse/compilation. Une idée serait de stocker les noms de macro dans une table de symboles. Lors de l'analyse syntaxique, vérifiez d'abord les jetons de texte sur cette table. Si vous trouvez une correspondance, écrivez le remplacement dans une nouvelle chaîne et exécutez-la dans l'analyseur, puis continuez l'analyse du texte original après la fermeture du macrto. En fonction de votre syntaxe de code d'opération, une autre idée pourrait être - lorsque vous rencontrez la définition de la macro lors de l'analyse, générer les opcodes, mais placez des espaces réservés à la place des arguments. Ensuite, lorsque l'analyseur rencontre des appels à la macro, générez le code pour évaluer les arguments et insérez ce code à la place des espaces réservés dans le code macro pré-généré.

+0

Il fait deux itérations. La première itération analyse les macros et effectue le remplacement du texte et construit l'arbre. Dans la deuxième itération, il génère l'opcode en prenant cet arbre comme entrée. – Vinay

Questions connexes