Chinaunix首页 | 论坛 | 博客
  • 博客访问: 980097
  • 博文数量: 23
  • 博客积分: 10258
  • 博客等级: 上将
  • 技术积分: 2455
  • 用 户 组: 普通用户
  • 注册时间: 2005-03-10 17:09
文章分类

全部博文(23)

文章存档

2011年(1)

2009年(6)

2008年(16)

分类: C/C++

2008-09-24 11:48:10

 

 C语言的声明语句,一直是我的一个弱项。这两天读《Expert C  Programing》,发现一个读复杂的声明的方法,而且提供了伪代码,于是自己翻译成了一个完整的C程序。

  后来才发现,后面几页就是C源码,而且实现的也很像(一样的伪码嘛)。

  不过反正也写了,就贴出来显摆一下吧!

 

/*
 * This is a cdecl, translate C definetion to nature setence
 *
 * Author: Alf
 * Email: naihe2010@gmail.com
 * Blog: http://naihe2010.cublog.cn
 * */


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

#define MAXTOKENLEN 0x10
#define MAXTOKENS 0x20

enum { TYPE, QUAILITER, IDENTIFIER };

struct token
{
  char type;
  char string[MAXTOKENLEN];
};

struct token stack[MAXTOKENS];
struct token this;
static int top;

static char *p, *e;

static void
classify_string (void)
{
  static char *types[] = {
      "signed", "unsigned", "char", "int", "short", "long", "float", "double",
      "struct", "union", "enum"
  };
  static char *quailiters[] = { "const", "static", "volatile" };
  unsigned int i;

  for (i=0; i<sizeof (types) / sizeof (types[0]); ++i)
    {
      if (strcmp (this.string, types[i]) == 0)
        {
          this.type = TYPE;
          return;
        }
    }

  for (i=0; i<sizeof (quailiters) / sizeof (quailiters[0]); ++i)
    {
      if (strcmp (this.string, quailiters[i]) == 0)
        {
          this.type = QUAILITER;
          return;
        }
    }

  this.type = IDENTIFIER;
}

static void
gettoken (void)
{
  int len = 0;

  while (isspace (*p))
    p ++;

  if (isalnum (*p))
    {
      while (isalnum (*p))
        {
          this.string[len ++] = *p;
          p ++;
        }

      this.string[len] = '\0';
      classify_string ();
    }
  else
    {
      this.type = *p;
      this.string[len] = '\0';
      if (*p == '*')
        {
          strcpy (this.string, "pointer to ");
        }
      p ++;
    }
}

static void
read_to_first_identifier (void)
{
  gettoken ();
  while (this.type != IDENTIFIER)
    {
      stack[++ top] = this;
      gettoken ();
      if (p >= e)
        break;
    }

  printf ("%s is ", this.string);

  gettoken ();
}

static void
deal_with_func_args (void)
{
  while (this.type != ')')
    {
      gettoken ();
    }

  printf ("function returning ");

  gettoken ();
}

static void
deal_with_arrays (void)
{
  while (this.type == '[')
    {
      printf ("array ");
      gettoken ();
      if (isdigit (this.string[0]))
        {
          printf ("0 .. %d ", atoi (this.string) - 1);
          gettoken ();
        }
      gettoken ();
      printf ("of ");
    }
}

static void
deal_with_any_pointers (void)
{
  while (stack[top].type == '*')
    {
      printf ("%s ", stack[top].string);
      top --;
    }
}

static void
deal_with_declarator (void)
{
  if (this.type == '[')
    {
      deal_with_arrays ();
    }
  if (this.type == '(')
    {
      deal_with_func_args ();
    }

  deal_with_any_pointers ();

  while (top > -1)
    {
      if (stack[top].type == '(')
        {
          top --;
          gettoken ();
          deal_with_declarator ();
        }
      else
        {
          printf ("%s ", stack[top].string);
          top --;
        }
    }
}

static void
usage (void)
{
  fprintf (stderr, "cdecl setence\n");
}

int
main (int argc, char *argv[])
{
  if (argc < 2)
    {
      usage ();
      return -1;
    }

  p = argv[1];
  e = p + strlen (p);

  printf ("\n\n");
  read_to_first_identifier ();
  deal_with_declarator ();
  printf ("\n\n\n");

  return 0;
}

阅读(1967) | 评论(0) | 转发(0) |
0

上一篇:yum使用方法(转)

下一篇:突破远程桌面

给主人留下些什么吧!~~