2010-04-19 6 views
2

je cherche le manuscrit dans l'awk qui vérifiera s'il a le placement approprié de parenthèse. les parenthèses utilisées sont {} [] et() chaque parenthèse doit être fermée et les parenthèses ne peuvent pas être mélangées, exemple illégal: ([)]awk - parenthèses vérifiant

+1

vous devriez vraiment utiliser un vérificateur de syntaxe d'une sorte. – ghostdog74

Répondre

1

Vous devrez lire le fichier caractère par caractère. Construire une pile de parenthèses ouvertes vues. Lorsque vous voyez un crochet fermé, vous pouvez soit ouvrir le support ouvert correspondant de la pile, soit enregistrer une erreur que les parenthèses ne correspondent pas.

awk n'est pas l'outil idéal pour ce travail. J'utiliserais un langage de script généraliste (Perl/Tcl/etc).

+1

à moins que vous ne parliez d'un module quelconque qui fait ce genre de choses, utiliser awk est toujours l'un des bons outils si vous parlez de l'analyse pure des fichiers. Il ne perdra pas Perl ou d'autres langages de script à cet égard. – ghostdog74

2

Si ce que vous essayez de faire s'applique à un langage à usage général, il s'agit d'un problème non trivial.

Pour commencer, vous aurez à vous soucier des commentaires et des chaînes. Si vous voulez vérifier cela sur un langage de programmation qui utilise des expressions régulières, cela rendra votre quête encore plus difficile. Donc, avant de pouvoir vous donner des conseils sur votre question, j'ai besoin de connaître les limites de votre problème. Si vous pouvez garantir qu'il n'y a pas de chaînes, pas de commentaires et pas d'expressions régulières à s'inquiéter - ou plus génériquement nulle part dans le code que les crochets peuvent être utilisés autrement que pour les utilisations pour lesquelles vous vérifiez qu'ils sont équilibrés - cela rendre la vie beaucoup plus simple. Connaître la langue que vous voulez vérifier serait utile.


Si je prends l'hypothèse qu'il n'y a pas de bruit, à savoir que tous les supports sont supports utiles, ma stratégie serait itérative:

Je regarderais simplement et enlever toutes les paires de support internes: ceux qui ne contient pas de crochets à l'intérieur. Pour ce faire, il est préférable de regrouper toutes les lignes sur une longue ligne (et de trouver un mécanisme permettant d'ajouter des références de ligne, au cas où vous auriez besoin de sortir cette information). Dans ce cas, la recherche et de remplacement est assez simple:

Il faut un tableau:

B["("]=")"; B["["]="]"; B["{"]="}" 

Et une boucle à travers ces éléments:

for (b in B) {gsub("[" b "][^][(){}]*[" B[b] "]", "", $0)} 

Mon fichier de test est la suivante:

#!/bin/awk 

($1 == "PID") { 
    fo (i=1; i<NF; i++) 
    { 
    F[$i] = i 
    } 
} 

($1 + 0) > 0 { 
    count("VIRT") 
    count("RES") 
    count("SHR") 
    count("%MEM") 
} 

END { 
    pintf "VIRT=\t%12d\nRES=\t%12d\nSHR=\t%12d\n%%MEM=\t%5.1f%%\n", C["VIRT"], C["RES"], C["SHR"], C["%MEM"] 
} 

function count(c[) 
{ 
    f=F[c]; 

    if ($f ~ /m$/) 
    { 
    $f = ($f+0) * 1024 
    } 

    C[c]+=($f+0) 
} 

Mon script complet (sans référence de ligne) est le suivant:

cat test-file-for-brackets.txt | \ 
    tr -d '\r\n' | \ 
    awk \ 
    ' 
    BEGIN { 
     B["("]=")"; 
     B["["]="]"; 
     B["{"]="}" 
    } 
    { 
     m=1; 
     while(m>0) 
     { 
     m=0; 
     for (b in B) 
     { 
      m+=gsub("[" b "][^][(){}]*[" B[b] "]", "", $0) 
     } 
     }; 
     print 
    } 
    ' 

La sortie de ce script s'arrête sur les utilisations les plus illégales des parenthèses. Mais attention: 1/ce script ne fonctionnera pas entre crochets dans les commentaires, les expressions régulières ou les chaînes, 2/il ne signale pas où se trouve le problème dans le fichier original, 3/bien qu'il enlève toutes les paires équilibrées il s'arrête au conditions d'erreur les plus profondes et garde toutes les parenthèses englobantes.

Le point 3/est probablement un résultat exploitable, même si je ne suis pas sûr du mécanisme de rapport que vous aviez en tête.

Le point 2/est relativement facile à implémenter, mais cela prend plus de quelques minutes à produire, donc je vais vous laisser le soin de le déterminer.

point 1/est délicate parce que vous entrez dans un nouveau royaume de compétition parfois imbriqués débuts et fins, ou des règles spéciales Echéances des caractères spéciaux ...