Sektion Angewandte Informationsverarbeitung

Übungen zu Systemnahe Software I, Wintersemester 1996/97

Blatt 5

Beispiellösung zu Aufgabe 7 (5 Punkte)

#include<stdio.h>

#define MAXWORDLEN 16
char c;
char word[MAXWORDLEN] = "";

#define GANZ_GEMEIN "\\\\\"Ganz gemein\""

void fatal_error( char *s )
{
  fprintf( stderr, "Fatal error: %s\n", s );
  exit( 1 );
}

char filtered_getchar( void )
{
  char tmp;

  tmp = getchar();
  while( tmp == '\\' ){
    getchar(); tmp = getchar();
  }
  return tmp;
}

/* read from stdin until the combination star-slash is read.
   beware of star-star-slash and it's likes */
void read_to_comment_end( void )
{
  /* syntactic correct means we need'nt check for EOF
     within a comment. good. :-) */
  while( 1 ){
    if( c == '*' ){
      c = filtered_getchar();
      if( c == '/' )
        break;
    }else{
      c = filtered_getchar();
    }
  }
  c = filtered_getchar();
}

/* read from stdin until the wanted character is read, or
   EOF reached. sounds simple enough ... */
void read_up_to( char wanted )
{
  while( (c != EOF) && (c != wanted) )
    c = filtered_getchar();
  c = filtered_getchar();
}

/* returns 0 if c is NOT [a-zA-Z0-9_], !=0 else */
int is_word_char( char c )
{
  if( ((c < 'a') || (c > 'z')) &&
      ((c < 'A') || (c > 'Z')) &&
      ((c < '0') || (c > '9')) &&
      ( c != '_' ) ) 
    return 0;
  else
    return 1;
}

/* this procedure reads the next word into "word", discarding any 
   characters that exceed MAXWORDLEN. the word in "word" is then 
   '\0'-terminated. */
void in_word( void )
{
  int ccount = 0;

  if( !is_word_char(c) ) 
    return;
  word[ ccount ] = c; ccount++; c = filtered_getchar();
  while( (c != EOF) && is_word_char( c ) ){
    if( ccount < MAXWORDLEN ){
      word[ ccount ] = c; ccount++;
    }
    c = filtered_getchar();
  }
  if( ccount < MAXWORDLEN )
    word[ ccount ] = '\0';
  else
    word[ MAXWORDLEN-1 ] = '\0';

  printf( "%s\n", word );
}

#define QUOTE1 '"'
#define QUOTE2 '\''
void out_word( void )
{
  while( c != EOF ){
    if( is_word_char(c) )
      in_word();
    else if( c == QUOTE1 ){
      c = filtered_getchar();
      read_up_to( QUOTE1 );
    }else if( c == QUOTE2 ){
      c = filtered_getchar();
      read_up_to( QUOTE2 );
    }else if( c == '/' ){
      c = filtered_getchar();
      if( c == '*' ){
        c = filtered_getchar(); 
        read_to_comment_end();
      }
    }else
      c = filtered_getchar();
  }
}

int main( void )
{
  c = filtered_getchar();
  out_word();
  return 0;
}


Beispiellösung zu Aufgabe 8 (10 Punkte)

#include<stdio.h>

#define MAXWORDLEN 16
char c;
char word[MAXWORDLEN] = "";
long vG;

#define GANZ_GEMEIN "\\\\\"Ganz gemein\""

void fatal_error( char *s )
{
  fprintf( stderr, "Fatal error: %s\n", s );
  exit( 1 );
}

char filtered_getchar( void )
{
  char tmp;

  tmp = getchar();
  while( tmp == '\\' ){
    getchar(); tmp = getchar();
  }
  return tmp;
}

/* read from stdin until the combination star-slash is read.
   beware of star-star-slash and it's likes */
void read_to_comment_end( void )
{
  /* syntactic correct means we need'nt check for EOF
     within a comment. good. :-) */
  while( 1 ){
    if( c == '*' ){
      c = filtered_getchar();
      if( c == '/' )
        break;
    }else{
      c = filtered_getchar();
    }
  }
  c = filtered_getchar();
}

/* read from stdin until the wanted character is read, or
   EOF reached. sounds simple enough ... */
void read_up_to( char wanted )
{
  while( (c != EOF) && (c != wanted) )
    c = filtered_getchar();
  c = filtered_getchar();
}

/* returns 0 if c is NOT [a-zA-Z0-9_], !=0 else */
int is_word_char( char c )
{
  if( ((c < 'a') || (c > 'z')) &&
      ((c < 'A') || (c > 'Z')) &&
      ((c < '0') || (c > '9')) &&
      ( c != '_' ) ) 
    return 0;
  else
    return 1;
}

int word_value( void )
{
  if( (strcmp( word, "if" ) == 0) ||
      (strcmp( word, "while" ) == 0) ||
      (strcmp( word, "for" ) == 0) ||
      (strcmp( word, "case" ) == 0) )
    return 1;
  else
    return 0;
}

/* this procedure reads the next word into "word", discarding any 
   characters that exceed MAXWORDLEN. the word in "word" is then 
   '\0'-terminated. */
void in_word( void )
{
  int ccount = 0;
  long value;

  if( !is_word_char(c) ) 
    return;
  word[ ccount ] = c; ccount++; c = filtered_getchar();
  while( (c != EOF) && is_word_char( c ) ){
    if( ccount < MAXWORDLEN ){
      word[ ccount ] = c; ccount++;
    }
    c = filtered_getchar();
  }
  if( ccount < MAXWORDLEN )
    word[ ccount ] = '\0';
  else
    word[ MAXWORDLEN-1 ] = '\0';

  value = word_value();
  vG += value;
/*
  if( value )
    printf( "%s: %ld; v(G) = %ld\n", word, value, vG );
*/
}

#define QUOTE1 '"'
#define QUOTE2 '\''
void out_word( void )
{
  while( c != EOF ){
    if( is_word_char(c) )
      in_word();
    else if( c == QUOTE1 ){
      c = filtered_getchar();
      read_up_to( QUOTE1 );
    }else if( c == QUOTE2 ){
      c = filtered_getchar();
      read_up_to( QUOTE2 );
    }else if( c == '/' ){
      c = filtered_getchar();
      if( c == '*' ){
        c = filtered_getchar(); 
        read_to_comment_end();
      }
    }else
      c = filtered_getchar();
  }
}

int main( void )
{
  printf( "Berechnung der zyklomatischen Komplexitaet v(G)\n" );
  vG = 0;
  c = filtered_getchar();
  out_word();
  printf( "v(G) = %ld\n", vG );
  return 0;
}

/*
turing$ make
gcc     mccabe.c   -o mccabe
turing$ mccabe < mccabe.c 
Berechnung der zyklomatischen Komplexitaet v(G)
v(G) = 17
turing$ mccabe < parse_esc.c 
Berechnung der zyklomatischen Komplexitaet v(G)
v(G) = 16
turing$ mccabe < ../blatt4/parse.c 
Berechnung der zyklomatischen Komplexitaet v(G)
v(G) = 15
*/

Beispiellösung zu Aufgabe 9 (5 Punkte)

Name: atl
parse.c:15
parse_esc.c:16
mccabe.c:17