Monday, August 29, 2011

Exercise 1-23 (continued)

Exercise 1-23  Write a program to remove all comments from a C program.  Don't forget to handle quoted strings and character constants properly.  C comments do not nest.

#include <stdio.h>
#include <stdlib.h>

/* For simplicity, this program doesn't deal with this case:
                  '\''                   */

enum states { NORMAL = 0, FORWARD_SLASH = 1, IN_COMMENT = 2,
              CLOSING_ASTERISK = 3, IN_QUOTE = 4, ESCAPING = 5,
              SINGLE_QUOTE = 6 };

void print(int c)
{
  if (c!=EOF)
    putchar(c);
}

enum states single_quote(int c)
{
  enum states state = SINGLE_QUOTE;

  switch(c)
  {
  default:
    state = SINGLE_QUOTE;
    print(c);
    break;

  case '\'':
    state = NORMAL;
    print(c);
    break;
  }

  return state;
}

enum states escaping(int c)
{
  print(c);  /* Regardless of what it is. */
  return NORMAL;
}

enum states in_quote(int c)
{
  enum states state = IN_QUOTE;

  switch(c)
  {
  case '\"':
    state = NORMAL;
    break;

  default:
    state = IN_QUOTE;
    break;
  }

  print(c);

  return state;
}

enum states closing_asterisk(int c)
{
  enum states state = IN_COMMENT;

  switch(c)
  {
  case '/':
    state = NORMAL;
    break;

  case '*':
    state = CLOSING_ASTERISK;
    break;

  default:
    state = IN_COMMENT;
    break;
  }

  return state;
}

enum states in_comment(int c)
{
  enum states state = IN_COMMENT;

  switch(c)
  {
  case '*':
    state = CLOSING_ASTERISK;
    break;

  default:
    state = IN_COMMENT;
    break;
  }

  return state;
}

enum states forward_slash(int c)
{
  enum states state = NORMAL;

  switch(c)
  {
  case '\'':
    state = SINGLE_QUOTE;
    break;

  case '/':
    print('/');
    state = FORWARD_SLASH;
    break;

  case '*':
    state = IN_COMMENT;
    break;

  default:
    state = NORMAL;
    print('/');
    print(c);
    break;
  }

  return state;
}

enum states normal(int c)
{
  enum states state = NORMAL;

  switch(c)
  {
  case '\'':
    state = SINGLE_QUOTE;
    print(c);
    break;

  case '\\':
    state = ESCAPING;
    print(c);
    break;

  case '\"':
    state = IN_QUOTE;
    print(c);
    break;

  case '/':
    state = FORWARD_SLASH;
    break;

  default:
    state = NORMAL;
    print(c);
    break;
  }

  return state;
}

enum states parse(int c, enum states state)
{
  enum states return_state = NORMAL;

  switch(state)
  {
  case SINGLE_QUOTE:
    return_state = single_quote(c);
    break;

  case IN_QUOTE:
    return_state = in_quote(c);
    break;

  case CLOSING_ASTERISK:
    return_state = closing_asterisk(c);
    break;

  case IN_COMMENT:
    return_state = in_comment(c);
    break;

  case FORWARD_SLASH:
    return_state = forward_slash(c);
    break;

  case NORMAL:
  default:
    return_state = normal(c);
    break;
  }

  return return_state;
}

int main(void)
{
  enum states state = NORMAL;
  int c;

  do
    state = parse(c = getchar(), state);
  while (c!=EOF);

  return EXIT_SUCCESS;
}

No comments:

Post a Comment