Παράδειγμα: μορφοποίηση προγραμμάτων

Διομήδης Σπινέλλης
Τμήμα Διοικητικής Επιστήμης και Τεχνολογίας
Οικονομικό Πανεπιστήμιο Αθηνών
dds@aueb.gr

Ο κύκλος ζωής του λογισμικού

Ανεπίσημες προδιαγραφές

Να γραφεί ένα πρόγραμμα το οποίο να στοιχίζει σωστά προγράμματα γραμμένα σε C.

Επίσημες προδιαγραφές

Να γραφεί ένα πρόγραμμα το οποίο θα θέτει σωστά τα κενά στην αρχή των γραμμών. Παράδειγμα εισόδου:
#include <stdio.h>

/*
 * Play the bahm boom game:
 * - print ascending numbers;
 * - bahm's at 9 multiples;
 * - boom's at 7 multiples;
 */
main()
{
int i;
for (i = 0; i < 100; i++) {
if (i % 9 == 0) {
printf("{BAHM}\n");
if (i % 9 == 0) {
printf("{BAHM}\n");
} else if (i % 7 == 0) {
printf("{BOOM}\n");
} else {
printf("%d\n", i);
}
}
}
Παράδειγμα εξόδου:
#include <stdio.h>

/*
 * Play the bahm boom game:
 * - print ascending numbers;
 * - bahm's at 9 multiples;
 * - boom's at 7 multiples;
 */
main()
{
	int i;
	for (i = 0; i < 100; i++) {
		if (i % 9 == 0) {
			printf("{BAHM}\n");
			if (i % 9 == 0) {
				printf("{BAHM}\n");
			} else if (i % 7 == 0) {
				printf("{BOOM}\n");
			} else {
				printf("%d\n", i);
			}
		}
	}
}

Αρχιτεκτονική σχεδίαση

Λεπτομερής σχεδίαση

Κωδικοποίηση

#include <stdio.h>

/* States the system can be in */
enum states {
        NORMAL,
        HASH,
        SLASH,
        COMMENT,
        STAR,
        STRING,
        BACKSLASH_STRING,
        CHARACTER,
        BACKSLASH_CHARACTER,
        NEWLINE,
};

/* Current state */
int state = NORMAL;

/* Current level of indent (tabs to print at the beginning of a line) */
int indent_level = 0;

/*
 * Print tabs to indent the following character by indent_level
 */
void
indent(void)
{
        int i;

        for (i = 0; i < indent_level; i++)
                putchar('\t');
}

/*
 * State processing functions start here
 */
void
comment(char c)
{
        putchar(c);
        if (c == '*')
                state = STAR;
}

void
slash(char c)
{
        putchar(c);
        if (c == '*')
                state = COMMENT;
        else
                state = NORMAL;
}

void
string(char c)
{
        putchar(c);
        if (c == '"')
                state = NORMAL;
        else if (c == '\\')
                state = BACKSLASH_STRING;
}

void
backslash_string(char c)
{
        putchar(c);
        state = STRING;
}


void
character(char c)
{
        putchar(c);
        if (c == '\'')
                state = NORMAL;
        else if (c == '\\')
                state = BACKSLASH_CHARACTER;
}

void
backslash_character(char c)
{
        putchar(c);
        state = CHARACTER;
}

void
hash(char c)
{
        putchar(c);
        if (c == '\n')
                state = NORMAL;
}

void
normal(char c)
{
        putchar(c);
        switch (c) {
        case '#':
                state = HASH;
                break;
        case '/':
                state = SLASH;
                break;
        case '\'':
                state = CHARACTER;
                break;
        case '"':
                state = STRING;
                break;
        case '{':
                indent_level++;
                break;
        case '\n':
                state = NEWLINE;
                break;
        }
}

void
star(char c)
{
        putchar(c);
        if (c == '/')
                state = NORMAL;
        else
                state = COMMENT;
}

void
newline(char c)
{
        switch (c) {
        case ' ':
        case '\n':
        case '\t':
                break;
        case '}':
                indent_level--;
                /* FALLTRHOUGH */
        default:
                indent();
                state = NORMAL;
                normal(c);
                break;
        }
}

/*
 * Process a single character.
 * Call the appropriate state handling function
 */
void
process(char c)
{
        switch (state) {
        case NORMAL:
                normal(c);
                break;
        case COMMENT:
                comment(c);
                break;
        case HASH:
                hash(c);
                break;
        case SLASH:
                slash(c);
                break;
        case STAR:
                star(c);
                break;
        case STRING:
                string(c);
                break;
        case BACKSLASH_STRING:
                backslash_string(c);
                break;
        case NEWLINE:
                newline(c);
                break;
        case CHARACTER:
                character(c);
                break;
        case BACKSLASH_CHARACTER:
                backslash_character(c);
                break;
        }
}

main()
{
        int c;

        while ((c = getchar()) != EOF)
                process(c);
}

Έλεγχος μονάδων

Ασκήσεις

Η γλώσσα HTML

Εμφάνιση HTML

Παράδειγμα εισόδου


<h1> Κύρια επικεφαλίδα</h1>
<h2> Επικεφαλίδα επιπέδου 2 </h2>
<p>
Κείμενο το οποίο
πρέπει
να εμφανίζεται στοιχισμένο μέχρι τη στήλη 60.
Οι
λέξεις
αυτές
δεν
πρέπει
να
εμφανίζονται
σε ξεχωριστές
γραμμές.
<p>
Εδώ αλλάζουμε γραμμή, αλλά η γραμμή αυτή είναι πάρα πολύ μεγάλη και πρέπει να σπάσει
<h2> Άλλη επικεφαλίδα επιπέδου 2 </h2>
<p>
Λίστα με στοιχεία (ένα σε κάθε γραμμή):
<ul>
<li> Στοιχείο 1 <LI> Στοιχείο 2
<li> Στοιχείο 3
<li> Στοιχείο 4
</ul>

Παράδειγμα εξόδου


1.  Κύρια επικεφαλίδα 
1.1.  Επικεφαλίδα επιπέδου 2  
 Κείμενο το οποίο πρέπει να εμφανίζεται στοιχισμένο μέχρι τη στήλη
60. Οι λέξεις αυτές δεν πρέπει να εμφανίζονται σε ξεχωριστές γραμμές.

 Εδώ αλλάζουμε γραμμή, αλλά η γραμμή αυτή είναι πάρα πολύ μεγάλη
και πρέπει να σπάσει 
1.2.  Άλλη επικεφαλίδα επιπέδου 2  
 Λίστα με στοιχεία (ένα σε κάθε γραμμή):  
-  Στοιχείο 1 
-  Στοιχείο 2 
-  Στοιχείο 3 
-  Στοιχείο 4   

Βιβλιογραφία

Παράδειγμα HTML

Επικεφαλίδα επιπέδου 2

Κείμενο το οποίο πρέπει να εμφανίζεται στοιχισμένο μέχρι τη στήλη 60. Οι λέξεις αυτές δεν πρέπει να εμφανίζονται σε ξεχωριστές γραμμές.

Εδώ αλλάζουμε γραμμή, αλλά η γραμμή αυτή είναι πάρα πολύ μεγάλη και πρέπει να σπάσει

Άλλη επικεφαλίδα επιπέδου 2

Λίστα με στοιχεία (ένα σε κάθε γραμμή):

HTML example (english)

Heading level 2

Text that should appear wrapped at column 60. These words should not be spread on single lines.

A new paragraph begins at this point, but this line is quite long and should be split.

Another heading level 2

Element list (one per line):