/* tree syntax parser and display program */
/*
tree := digit digits ( tree ) ( tree ) | * | <null>
digit := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
digits := digit digits | <null>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct tree tree;
typedef struct tree {
unsigned int id;
tree *left, *right;
} tree;
typedef struct {
unsigned int width, height, pos;
char grid[1];
} ascii_t;
int match( const char **s, char c ) {
if ( s == 0 || *s == 0 || **s != c ) return 0;
return ++*s, 1;
}
int digit( const char **s ) {
return match( s, '0' ) || match( s, '1' ) || match( s, '2' ) ||
match( s, '3' ) || match( s, '4' ) || match( s, '5' ) ||
match( s, '6' ) || match( s, '7' ) || match( s, '8' ) ||
match( s, '9' );
}
tree * create( const char **s ) {
char c;
unsigned int value;
tree *node, *left, *right;
if ( s == 0 || *s == 0 ) return 0;
if ( match( s, '*' ) ) return 0;
if ( c= **s, !digit( s ) ) return 0;
for ( value= c - '0'; c= **s, digit( s ); ) value= 10*value + c - '0';
if ( !match( s, '(' ) ) return 0;
left= create( s );
if ( !match( s, ')' ) || !match( s, '(' ) ) return 0;
right= create( s );
if ( !match( s, ')' ) ) return 0;
node
= (tree
*) malloc( sizeof( tree
) ); node->id= value;
node->left= left;
node->right= right;
return node;
}
void destroy( tree * t ) {
if ( t == 0 ) return;
destroy( t->left );
destroy( t->right );
return;
}
void display( ascii_t *r ) {
unsigned int i, j;
for ( i= 0; i < r->height; ++i ) {
for ( j= 0; j < r->width; ++j )
putchar( r
->grid
[ i
*r
->width
+j
] ); }
return;
}
void sidedisplay( ascii_t *r ) {
unsigned int i, j;
for ( j= 0; j < r->width; ++j ) {
for ( i= 0; i < r->height; ++i )
putchar( r
->grid
[ i
*r
->width
+j
] ); }
return;
}
ascii_t * ascii( tree *t ) {
char digits[10];
ascii_t *result, *left, *right;
unsigned int i, j, lh, rh, lw, rw, h, w, id, count;
if ( t == 0 ) {
result
= (ascii_t
*) malloc( sizeof( ascii_t
) ); result->height= result->width= 1;
result->pos= 0;
result->grid[0]= '*';
return result;
}
id= t->id;
count= 0;
do {
digits[count++]= '0' + (id % 10);
id /= 10;
} while ( id > 0 );
left= ascii( t->left );
right= ascii( t->right );
if ( left->width < 2 )
lh= lw= 2;
else {
lh= (left->width + 1) >> 1;
lh= left->width - left->pos;
lw= left->width;
}
if ( right->width < 2 )
rh= rw= 2;
else {
rh= (right->width + 1) >> 1;
rh= right->pos + 1;
rw= right->width;
}
w= 1 + lw + rw;
h= lh + left->height >= rh + right->height? lh + left->height : rh + right->height;
if ( count > h ) h= count;
result
= (ascii_t
*) malloc( sizeof( ascii_t
) + w
*h
- 1 ); result->height= h;
result->width= w;
result->pos= lw;
for ( i= 0; i < w*h; ++i )
result->grid[i]= ' ';
for ( i= 0; i < count; ++i )
result->grid[ i*w + lw ]= digits[count-i-1];
for ( i= 0; i < left->height; ++i )
for ( j= 0; j < left->width; ++j )
result->grid[ (lh+i)*w+j ]= left->grid[ i*left->width+j ];
for ( i= 0; i < right->height; ++i )
for ( j= 0; j < right->width; ++j )
result->grid[ (rh+i)*w+lw+1+j+(right->width < 2) ]= right->grid[ i*right->width+j ];
for ( i= 1; i < lh; ++i )
result->grid[ i*w+lw-i ]= '/';
for ( i= 1; i < rh; ++i )
result->grid[ i*w+lw+i ]= '\\';
return result;
}
void print( tree * t, int tab ) {
if ( t
== 0 ) { printf( "%*s(%c)\n", tab
, "", '*' ); return; } printf( "%*s%d\n", tab
, "", t
->id
); print( t->left, tab+4 );
print( t->right, tab+4 );
return;
}
int main( int argc, char *argv[] ) {
tree *mytree;
char b[200], *p;
p
= fgets( b
, sizeof(b
), stdin
); if ( p == 0 ) return 0;
mytree= create( &p );
if ( *p == '\0' || *p == '\n' ) {
ascii_t *result= ascii( mytree );
printf( "Downward tree form:\n" ); display( result );
printf( "\nSideways tree form:\n" ); sidedisplay( result );
printf( "\nTabbed tree form:\n" ); print( mytree, 0 );
} else
printf( "Failed to parse correctly.\n" ); destroy( mytree );
return 0;
}
LyogdHJlZSBzeW50YXggcGFyc2VyIGFuZCBkaXNwbGF5IHByb2dyYW0gKi8KLyoKICAgICAgICB0cmVlIDo9IGRpZ2l0IGRpZ2l0cyAoIHRyZWUgKSAoIHRyZWUgKSB8ICogfCA8bnVsbD4KICAgICAgICBkaWdpdCA6PSAwIHwgMSB8IDIgfCAzIHwgNCB8IDUgfCA2IHwgNyB8IDggfCA5CiAgICAgICAgZGlnaXRzIDo9IGRpZ2l0IGRpZ2l0cyB8IDxudWxsPgoqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KdHlwZWRlZiBzdHJ1Y3QgdHJlZSB0cmVlOwp0eXBlZGVmIHN0cnVjdCB0cmVlIHsKICAgIHVuc2lnbmVkIGludCBpZDsKICAgIHRyZWUgKmxlZnQsICpyaWdodDsKfSB0cmVlOwp0eXBlZGVmIHN0cnVjdCB7CiAgICB1bnNpZ25lZCBpbnQgd2lkdGgsIGhlaWdodCwgcG9zOwogICAgY2hhciBncmlkWzFdOwp9IGFzY2lpX3Q7CmludCBtYXRjaCggY29uc3QgY2hhciAqKnMsIGNoYXIgYyApIHsKICAgIGlmICggcyA9PSAwIHx8ICpzID09IDAgfHwgKipzICE9IGMgKSByZXR1cm4gMDsKICAgIHJldHVybiArKypzLCAxOwp9CmludCBkaWdpdCggY29uc3QgY2hhciAqKnMgKSB7CiAgICByZXR1cm4gbWF0Y2goIHMsICcwJyApIHx8IG1hdGNoKCBzLCAnMScgKSB8fCBtYXRjaCggcywgJzInICkgfHwKICAgICAgICBtYXRjaCggcywgJzMnICkgfHwgbWF0Y2goIHMsICc0JyApIHx8IG1hdGNoKCBzLCAnNScgKSB8fAogICAgICAgIG1hdGNoKCBzLCAnNicgKSB8fCBtYXRjaCggcywgJzcnICkgfHwgbWF0Y2goIHMsICc4JyApIHx8CiAgICAgICAgbWF0Y2goIHMsICc5JyApOwp9CnRyZWUgKiBjcmVhdGUoIGNvbnN0IGNoYXIgKipzICkgewogICAgY2hhciBjOwogICAgdW5zaWduZWQgaW50IHZhbHVlOwogICAgdHJlZSAqbm9kZSwgKmxlZnQsICpyaWdodDsKICAgIGlmICggcyA9PSAwIHx8ICpzID09IDAgKSByZXR1cm4gMDsKICAgIGlmICggbWF0Y2goIHMsICcqJyApICkgcmV0dXJuIDA7CiAgICBpZiAoIGM9ICoqcywgIWRpZ2l0KCBzICkgKSByZXR1cm4gMDsKICAgIGZvciAoIHZhbHVlPSBjIC0gJzAnOyBjPSAqKnMsIGRpZ2l0KCBzICk7ICkgdmFsdWU9IDEwKnZhbHVlICsgYyAtICcwJzsKICAgIGlmICggIW1hdGNoKCBzLCAnKCcgKSApIHJldHVybiAwOwogICAgbGVmdD0gY3JlYXRlKCBzICk7CiAgICBpZiAoICFtYXRjaCggcywgJyknICkgfHwgIW1hdGNoKCBzLCAnKCcgKSApIHJldHVybiAwOwogICAgcmlnaHQ9IGNyZWF0ZSggcyApOwogICAgaWYgKCAhbWF0Y2goIHMsICcpJyApICkgcmV0dXJuIDA7CiAgICBub2RlPSAodHJlZSAqKSBtYWxsb2MoIHNpemVvZiggdHJlZSApICk7CiAgICBub2RlLT5pZD0gdmFsdWU7CiAgICBub2RlLT5sZWZ0PSBsZWZ0OwogICAgbm9kZS0+cmlnaHQ9IHJpZ2h0OwogICAgcmV0dXJuIG5vZGU7Cn0Kdm9pZCBkZXN0cm95KCB0cmVlICogdCApIHsKICAgIGlmICggdCA9PSAwICkgcmV0dXJuOwogICAgZGVzdHJveSggdC0+bGVmdCApOwogICAgZGVzdHJveSggdC0+cmlnaHQgKTsKICAgIGZyZWUoIHQgKTsKICAgIHJldHVybjsKfQp2b2lkIGRpc3BsYXkoIGFzY2lpX3QgKnIgKSB7CiAgICB1bnNpZ25lZCBpbnQgaSwgajsKICAgICAgICBmb3IgKCBpPSAwOyBpIDwgci0+aGVpZ2h0OyArK2kgKSB7CiAgICAgICAgICAgIGZvciAoIGo9IDA7IGogPCByLT53aWR0aDsgKytqICkKICAgICAgICAgICAgICAgIHB1dGNoYXIoIHItPmdyaWRbIGkqci0+d2lkdGgraiBdICk7CiAgICAgICAgICAgIHB1dGNoYXIoICdcbicgKTsKICAgICAgICB9CiAgICByZXR1cm47Cn0Kdm9pZCBzaWRlZGlzcGxheSggYXNjaWlfdCAqciApIHsKICAgIHVuc2lnbmVkIGludCBpLCBqOwogICAgICAgIGZvciAoIGo9IDA7IGogPCByLT53aWR0aDsgKytqICkgewogICAgICAgICAgICBmb3IgKCBpPSAwOyBpIDwgci0+aGVpZ2h0OyArK2kgKQogICAgICAgICAgICAgICAgcHV0Y2hhciggci0+Z3JpZFsgaSpyLT53aWR0aCtqIF0gKTsKICAgICAgICAgICAgcHV0Y2hhciggJ1xuJyApOwogICAgICAgIH0KICAgIHJldHVybjsKfQphc2NpaV90ICogYXNjaWkoIHRyZWUgKnQgKSB7CiAgICBjaGFyIGRpZ2l0c1sxMF07CiAgICBhc2NpaV90ICpyZXN1bHQsICpsZWZ0LCAqcmlnaHQ7CiAgICB1bnNpZ25lZCBpbnQgaSwgaiwgbGgsIHJoLCBsdywgcncsIGgsIHcsIGlkLCBjb3VudDsKICAgIGlmICggdCA9PSAwICkgewogICAgICAgIHJlc3VsdD0gKGFzY2lpX3QgKikgbWFsbG9jKCBzaXplb2YoIGFzY2lpX3QgKSApOwogICAgICAgIHJlc3VsdC0+aGVpZ2h0PSByZXN1bHQtPndpZHRoPSAxOwogICAgICAgIHJlc3VsdC0+cG9zPSAwOwogICAgICAgIHJlc3VsdC0+Z3JpZFswXT0gJyonOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgICBpZD0gdC0+aWQ7CiAgICBjb3VudD0gMDsKICAgIGRvIHsKICAgICAgICBkaWdpdHNbY291bnQrK109ICcwJyArIChpZCAlIDEwKTsKICAgICAgICBpZCAvPSAxMDsKICAgIH0gd2hpbGUgKCBpZCA+IDAgKTsKICAgIGxlZnQ9IGFzY2lpKCB0LT5sZWZ0ICk7CiAgICByaWdodD0gYXNjaWkoIHQtPnJpZ2h0ICk7CiAgICBpZiAoIGxlZnQtPndpZHRoIDwgMiApCiAgICAgICAgbGg9IGx3PSAyOwogICAgZWxzZSB7CiAgICAgICAgbGg9IChsZWZ0LT53aWR0aCArIDEpID4+IDE7CiAgICAgICAgbGg9IGxlZnQtPndpZHRoIC0gbGVmdC0+cG9zOwogICAgICAgIGx3PSBsZWZ0LT53aWR0aDsKICAgIH0KICAgIGlmICggcmlnaHQtPndpZHRoIDwgMiApCiAgICAgICAgcmg9IHJ3PSAyOwogICAgZWxzZSB7CiAgICAgICAgcmg9IChyaWdodC0+d2lkdGggKyAxKSA+PiAxOwogICAgICAgIHJoPSByaWdodC0+cG9zICsgMTsKICAgICAgICBydz0gcmlnaHQtPndpZHRoOwogICAgfQogICAgdz0gMSArIGx3ICsgcnc7CiAgICBoPSBsaCArIGxlZnQtPmhlaWdodCA+PSByaCArIHJpZ2h0LT5oZWlnaHQ/IGxoICsgbGVmdC0+aGVpZ2h0IDogcmggKyByaWdodC0+aGVpZ2h0OwogICAgaWYgKCBjb3VudCA+IGggKSBoPSBjb3VudDsKICAgIHJlc3VsdD0gKGFzY2lpX3QgKikgbWFsbG9jKCBzaXplb2YoIGFzY2lpX3QgKSArIHcqaCAtIDEgKTsKICAgIHJlc3VsdC0+aGVpZ2h0PSBoOwogICAgcmVzdWx0LT53aWR0aD0gdzsKICAgIHJlc3VsdC0+cG9zPSBsdzsKICAgIGZvciAoIGk9IDA7IGkgPCB3Kmg7ICsraSApCiAgICAgICAgcmVzdWx0LT5ncmlkW2ldPSAnICc7CiAgICBmb3IgKCBpPSAwOyBpIDwgY291bnQ7ICsraSApCiAgICAgICAgcmVzdWx0LT5ncmlkWyBpKncgKyBsdyBdPSBkaWdpdHNbY291bnQtaS0xXTsKICAgIGZvciAoIGk9IDA7IGkgPCBsZWZ0LT5oZWlnaHQ7ICsraSApCiAgICAgICAgZm9yICggaj0gMDsgaiA8IGxlZnQtPndpZHRoOyArK2ogKQogICAgICAgICAgICByZXN1bHQtPmdyaWRbIChsaCtpKSp3K2ogXT0gbGVmdC0+Z3JpZFsgaSpsZWZ0LT53aWR0aCtqIF07CiAgICBmb3IgKCBpPSAwOyBpIDwgcmlnaHQtPmhlaWdodDsgKytpICkKICAgICAgICBmb3IgKCBqPSAwOyBqIDwgcmlnaHQtPndpZHRoOyArK2ogKQogICAgICAgICAgICByZXN1bHQtPmdyaWRbIChyaCtpKSp3K2x3KzEraisocmlnaHQtPndpZHRoIDwgMikgXT0gcmlnaHQtPmdyaWRbIGkqcmlnaHQtPndpZHRoK2ogXTsKICAgIGZvciAoIGk9IDE7IGkgPCBsaDsgKytpICkKICAgICAgICByZXN1bHQtPmdyaWRbIGkqdytsdy1pIF09ICcvJzsKICAgIGZvciAoIGk9IDE7IGkgPCByaDsgKytpICkKICAgICAgICByZXN1bHQtPmdyaWRbIGkqdytsdytpIF09ICdcXCc7CiAgICBmcmVlKCBsZWZ0ICk7CiAgICBmcmVlKCByaWdodCApOwogICAgcmV0dXJuIHJlc3VsdDsKfQp2b2lkIHByaW50KCB0cmVlICogdCwgaW50IHRhYiApIHsKICAgIGlmICggdCA9PSAwICkgeyBwcmludGYoICIlKnMoJWMpXG4iLCB0YWIsICIiLCAnKicgKTsgcmV0dXJuOyB9CiAgICBwcmludGYoICIlKnMlZFxuIiwgdGFiLCAiIiwgdC0+aWQgKTsKICAgIHByaW50KCB0LT5sZWZ0LCB0YWIrNCApOwogICAgcHJpbnQoIHQtPnJpZ2h0LCB0YWIrNCApOwogICAgcmV0dXJuOwp9CmludCBtYWluKCBpbnQgYXJnYywgY2hhciAqYXJndltdICkgewogICAgdHJlZSAqbXl0cmVlOwogICAgY2hhciBiWzIwMF0sICpwOwogICAgcD0gZmdldHMoIGIsIHNpemVvZihiKSwgc3RkaW4gKTsKICAgIGlmICggcCA9PSAwICkgcmV0dXJuIDA7CiAgICBteXRyZWU9IGNyZWF0ZSggJnAgKTsKICAgIGlmICggKnAgPT0gJ1wwJyB8fCAqcCA9PSAnXG4nICkgewogICAgICAgIGFzY2lpX3QgKnJlc3VsdD0gYXNjaWkoIG15dHJlZSApOwogICAgICAgIHByaW50ZiggIkRvd253YXJkIHRyZWUgZm9ybTpcbiIgKTsKICAgICAgICBkaXNwbGF5KCByZXN1bHQgKTsKICAgICAgICBwcmludGYoICJcblNpZGV3YXlzIHRyZWUgZm9ybTpcbiIgKTsKICAgICAgICBzaWRlZGlzcGxheSggcmVzdWx0ICk7CiAgICAgICAgcHJpbnRmKCAiXG5UYWJiZWQgdHJlZSBmb3JtOlxuIiApOwogICAgICAgIHByaW50KCBteXRyZWUsIDAgKTsKICAgICAgICBmcmVlKCByZXN1bHQgKTsKICAgIH0gZWxzZQogICAgICAgIHByaW50ZiggIkZhaWxlZCB0byBwYXJzZSBjb3JyZWN0bHkuXG4iICk7CiAgICBkZXN0cm95KCBteXRyZWUgKTsKICAgIHJldHVybiAwOwp9