Προς το περιεχόμενο

Αυτόματη μορφοποίηση κώδικα


babel47

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπέρα, υπαρχει κάποιο πρόγραμμα που μπορώ αν του εισάγω τον κώδικά μου και να τον μορφοποιεί?

Ευχαριστώ όποιον με βοηθήσει

Δημοσ.

τι είδους μορφοποίηση σε ενδιαφέρει? συνήθως με ένα text editor κάνεις τα περισσότερα, απο εκεί και πέρα μπορείς να φτιάξεις ένα προγραμματάκι που να κανει τη μορφοποίηση που θέλεις.. πες τι θέλεις να κάνεις και όλο και κάποια λύση θα βρεθεί

Δημοσ.

Οι editors προσφερουν μορφοποιηση αλλα δεν την χρησιμοποιησα καθως εγραφα το προγραμμα. Οταν λεω μορφοποιηση εννοω μια στοιχιση αναλογα με τις παρενθεσεις το κλασικο....

Δημοσ.

Αν θες να το παλέψεις μόνος σου, μπορείς να ξεκινήσεις από την αρχή ότι κάθε { αυξάνει +1 προς τα δεξιά την θέση του κέρσορα ενώ κάθε } την μειώνει κατά 1 προς τα αριστερά. Κάθε φορά που ξεκινά μια νέα γραμμή (\n) αυτή τοποθετείται στο περιθώριο που προκύπτει με βάση τον παραπάνω κανόνα. Ένα τρικ σημείο όσον αφορά το stdout (την έξοδο στην οθόνη) είναι ότι σε περίπτωση } οφείλεις να επιστρέψεις πίσω τον κέρσορα (προτείνω στην αρχή της γραμμής για ευκολία), πράγμα που γίνεται με την αποστολή του ASCII χαρακτήρα 8 (δηλαδή του backspace).

 

Ακολουθεί ένα μικρό πρόγραμμα σε ANSI-C, γραμμένο σε C++ Builder 2009, που δοκιμάζει να φορμάρει ένα απλό μη φορμαρισμένο αρχείο C καθώς μου άρεσε σαν θέμα:

 

>
/*-Lame Auto Formater (c) directx--------------------------------------------
* Release 2 (supports output to file via stdout redirection)
*/
#include <stdio.h>
#include <io.h>		/* POSIX */
#ifdef __BORLANDC__
#pragma hdrstop
#endif

#define _BACKSPACE 8
/*---------------------------------------------------------------------------*/
void _EchoTab(int, const char);

#ifdef __BORLANDC__
#pragma argsused
#endif
int main(int argc, char* argv[])
{
FILE *fStream = NULL;
unsigned char bToFile = 0;

/* Verify source existance */
if(access(argv[1], 0) == -1)
{
	printf("DOS Error: File not found - \"%s\"\n", argv[1]);
	return 1;
   }

/* Open file for read in text mode */
if((fStream = fopen(argv[1], "rt")) == NULL)
{
	printf("DOS Error: File read access denied - \"%s\"\n", argv[1]);
	return 1;
}
else
{
	int	nMargin = 0,
		nChar;
	/* R2+ Output to file or screen? */
	if(argc >= 3)
	{
		/* Redirect stdout to argv[2] */
		if(freopen(argv[2], "wt", stdout) == NULL)
			printf("I/O Error: File write access denied - \"%s\"\n", argv[2]);
		/* Redirection flag */
		bToFile = 1;
	}
	/* Read stream byte-byte until EOF */
	while((nChar = fgetc(fStream)) != EOF)
	{
		switch(nChar)
		{
			/* Open branch -> new code path */
			case '{':
				/* Increase margin */
				nMargin+=2;
			break;
			/* Close branch -> end of last opened code path */
			case '}':
				/* Decrease margin */
				if((nMargin-=2) < 0)
				/* Do not allow buffer underrun! (Should I stop here?) */
					nMargin = 0;
				/* R2+ If stdout to screen use _BACKSPACE to reset line */
				if(!bToFile)
				/* Reset cursor position to begin of line */
					_EchoTab(80, _BACKSPACE);
				else
					/* If stdout to file use fseek .. */
					fseek(stdout, -nMargin - 2, SEEK_END);
				/* Fill line with spaces */
				_EchoTab(nMargin, ' ');
			break;
			/* New line! */
			case '\n':
				/* Spit it on stdout! */
				putchar('\n');
				/* Apply current margin */
				_EchoTab(nMargin, ' ');
               /* putchar, no thx! */
			continue;
		}
		/* Echo char on stdout */
		putchar(nChar);
	}
	/* Close stream */
	fclose(fStream);
	/* R2+ If stdout redirected to file then close it also */
	if(bToFile)
       	fclose(stdout);
}
/* End of program */
return 0;
}
/*---------------------------------------------------------------------------*/
void _EchoTab(int nTimes, const char cCode)
{
/* Echo nTimes cCode on stdout */
while(nTimes-- > 0)
	putchar(cCode);
}

 

Είσοδος:

>
int main(int, char*)
{
if(a)
{
if(a)
{
if(a)
{
}
}
}
if(
{
}
}

 

Έξοδος:

>
int main(int, char*)
{
 if(a)
 {
   if(a)
   {
     if(a)
     {
     }
   }
 }
 if(
 {
 }
}

 

Προσοχή: Δεν έχω λάβει υπόψη μου όλες τις πιθανές περιπτώσεις, ούτε φυσικά ισχυρίζομαι ότι μπορεί να τα βγάλει πέρα με πολύπλοκο κώδικα (υποθέτω ότι έχεις κάθε { και } σε new line..), απλά το καταθέτω εδώ μπας και κάποια στιγμή (στο μέλλον) φανεί χρήσιμο (ποτέ δεν ξέρεις!).

 

Τεχνικά θεωρώ ότι το stdout οδηγεί προς την οθόνη και εκμεταλλεύομαι το backspace (8) για να μετακινήσω προς τα πίσω τον κέρσορα ώστε να ξεκινήσω μια νέα γραμμή, θεωρώ ότι δουλεύουμε σε κονσόλα διαστάσεων 80x25. Το μειονέκτημα είναι ότι σε περίπτωση ανακατεύθυνσης του stdout (>) τότε θα γραφθεί και το backspace στο stream, όμως για μια γρήγορη εφαρμογή της λογικής που προανέφερα (για να δεις τι περίπου κάνει) είναι μάλλον αρκετό.

 

--

Η έκδοση 2 διορθώνει το πρόβλημα της ανακατεύθυνσης σε αρχείο καθώς αν δοθεί δεύτερη παράμετρος-όνομα αρχείου ανακατευθύνει μέσο freopen το stdout σε αυτό κάνοντας το margin των γραμμών με την βοήθεια του fseek, πράγμα που δεν μπορεί να γίνει όταν το stdout οδηγεί προς την οθόνη οπότε η χρήση backspace εκεί είναι απαραίτητη.

--

 

Κατά τα άλλα, δες οπωσδήποτε τα links που σου παρέθεσε ο bxenos.

 

Καλή συνέχεια.

 

Υ.Γ.

Σε τι γλώσσα είναι γραμμένος ο κώδικας σου;

Δημοσ.
Πολύ καλή προσπάθεια directx. Ο κώδικάς μου είναι σε LISP

 

Χρησιμοποίησε τον XEmacs που έχει beautification για τις περισσότερες γλώσσες (μέχρι και VHDL και Verilog που γράφω εγώ!). Παρεμπιπτόντως ο XEmacs είναι γραμμένος σε Lisp και υποστηρίζει σιγουρα beautification Lisp κώδικα.

 

Επίσης έχω φτιάξει ένα scriptάκι σε Perl που κάνει μορφοποίηση σε VHDL code. Δεν είναι ολοκληρωμένο αλλά μπορείς να πάρεις μια ιδέα και να το τροποποιήσεις ανάλογα.

 

>
## Name:        nicerVHDL
## Author:      Dr. Fuzzy, [email protected]
## Description: Self-explanatory
## Version:     1.0.0

## Prepare IN/OUT Files ##
$vhdl_filename = $ARGV[0];
$report_filename = $ARGV[1];
open( FILE_IN, $vhdl_filename );
open( FILE_OUT, ">$report_filename" );

my $short_record = '  %6s %-12s : %-3s %15s';
my $long_record =  '  %6s %-12s : %-3s %-15s(%10s %6s %10s)';
my ($line, @buffer);
my $indent = "  ";        # Number of indent spaces
my $level = 0;            # init. nesting level
my $fh = FILE_IN;         # filehandle (FILE_IN)

# Read until ENTITY
print STDOUT "Format pass 1\n";
while ($line = <$fh>) {
   push @buffer, trim($line);
   last if $line =~ /entity/i;
}

# Format ENTITY
print STDOUT "Format pass 2\n";
while ($line = <$fh>) {
   if($line =~ /\s*port\s*\(\s*(.+)\s*$/) {
       my @temp = $1;
       my %print;
       while ( $line = <$fh> ) {
           last if $line =~ /^end \w+;\s*$/;
           push @temp, $line;
       }
       foreach my $i (@temp) {
           my ($key, $value) = trim(split /\s*:\s*/, $i);
           $value =~ s/;//;
           $print{$_} = $value for trim(split(/\s*,\s*/, $key));
       }
       my @keys = sort keys %print;
       
       for (my $i = 0; $i <= $#keys; $i++) {
           my $str;
           if ($print{$keys[$i]} =~ m/([^\(]+)\s*\(([^)]+)\s*\)/) {
               $str = sprintf $long_record, ($i == 0 ? 'port (' : ""),
                       $keys[$i], split(/\s+/, $1), split(/\s+/, $2);
           } else {
               $str = sprintf $short_record, ($i == 0 ? 'port (' : ""),
                       $keys[$i], split(/\s+/, $print{$keys[$i]});
           }   
           $str .= $i == $#keys ? ' );' : ';';
           push @buffer, $str;
       }
       push @buffer, trim($line);    # print 'end' message
       last;
   } else {
       push @buffer, trim($line);
   }
}

# Format Architecture
print STDOUT "Format pass 3\n";
while ($line = <$fh>) {
   if ($line =~ /^\s*architecture/i) {
       push @buffer, trim($line);
       $level++;
       while ($line = <$fh>) {
           if ($line =~ /begin/) {
               $level--;
               push @buffer, trim($line);
               $level++;
               last;
           } else {
               push @buffer, $indent x $level . trim($line);
           }
       }
       last;
   } else {
       push @buffer, trim($line);
   }
}

# Format Logic
print STDOUT "Format pass 4\n";
while ($line = <$fh>) {
   if ($line =~ m/\s*(\w+)/) {
       if ($1 eq 'begin') {
           push @buffer, $indent x $level . trim($line);
           $level++;
       } elsif ($1 eq 'if') {
           push @buffer, $indent x $level . trim($line);
           $level++;
       } elsif ($1 eq 'elsif' || $1 eq 'else') {
           $level--;
           push @buffer, $indent x $level . trim($line);
           $level++;
       } elsif ($1 eq 'end') {
           $level--;
           push @buffer, $indent x $level . trim($line);
       } else {
           push @buffer, $indent x $level . trim($line);
       }
   } else {
       push @buffer, $indent x $level . trim($line);
   }
}

# Grab anything that's left
print STDOUT "Format pass 5\n";
while ($line = <$fh>) {
   push @buffer, trim($line);
}

# PRINT!
foreach (@buffer) {
   #print "$_\n";
   print FILE_OUT "$_\n";
}

close (FILE_IN);
close (FILE_OUT);

sub trim {
 my @out = @_;
 for (@out) {
   s/^\s+//;
   s/\s+$//;
 }
 return wantarray ? @out : $out[0];
}

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...