cdecl程序,用于分析C语言的声明

来源:互联网 发布:大数据发展面临的问题 编辑:程序博客网 时间:2024/05/16 09:51

#include <stdio.h>

#include <ctype.h>

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

#define STRCMP(a, R, b) (strcmp(a, b) R 0)
#define MAXTOKENS 100
#define MAXTOKENLEN 64

enum type_tag{ Identifer, Qualifier, Type };

struct token
{
  char type;
  char string[MAXTOKENLEN];
};
struct token stack[MAXTOKENS];
struct token this;
int top = -1;

#define pop stack[top--]
#define push(s) stack[++top] = s

void Read_to_first_identifer(void);
enum type_tag Classify_str(void); /*推断标识符的类型*/
void Gettoken(void);/*读取下一个标记到this*/
void Deal_with_declarator(void);
void Deal_with_arrays(void);
void Deal_with_function_args(void);
void Deal_with_pointers(void);
void Deal_wirh_declarator(void);


int main(void)
{
  char next = 0;
  printf("输入一个C语言声明,cdecl程序会把声明转化成通俗文字:/n");
  do{
    /*将标记压入堆栈,直至遇到标识符*/
    Read_to_first_identifer();
    Deal_with_declarator();
    printf("/n是否进行下一个声明的推断(y//n)?");
  }while('Y' == toupper( next = getchar() ));
  return 0;
}

void Read_to_first_identifer(void)
{
  Gettoken();
  while(Identifer != this.type)
  {
    push(this);
    Gettoken();
  }
  printf("%s is ", this.string);
  Gettoken();
  return;
}

void Gettoken(void)
{
  char *p = this.string;
 
  while( ' ' == (*p = getchar()) );/*忽略空格*/
 
  if(isalnum(*p))/*A~z,0~9*/
  {
    while(isalnum( *++p = getchar() ));
    ungetc(*p, stdin);
    *p = '/0';
    this.type = Classify_str();
    return;
  }
 
  if('*' == *p)
  {
    strcpy(this.string, "pointer to");
    this.type = '*';
    return;
  }
  this.string[1] = '/0';
  this.type = *p;
  return;
}

enum type_tag Classify_str(void)
{
  char *s = this.string;
  if(STRCMP(s, ==, "const")){ strcpy(s, "read-only");  return Qualifier; }
  if(STRCMP(s, ==, "volatile"))  return Qualifier;
  if(STRCMP(s, ==, "void"))  return Type;
  if(STRCMP(s, ==, "char"))  return Type;
  if(STRCMP(s, ==, "int"))  return Type;
  if(STRCMP(s, ==, "long"))  return Type;
  if(STRCMP(s, ==, "float"))  return Type;
  if(STRCMP(s, ==, "double"))  return Type;
  if(STRCMP(s, ==, "signed"))  return Type;
  if(STRCMP(s, ==, "unsigned"))  return Type;
  if(STRCMP(s, ==, "struct"))  return Type;
  if(STRCMP(s, ==, "union"))  return Type;
  if(STRCMP(s, ==, "enum"))  return Type;
  return Identifer;
}

void Deal_with_declarator(void)
{
  /*处理标识符之后可能存在的函数或数组*/
  switch(this.type)
  {
    case '[':  Deal_with_arrays();  break;
    case '(':  Deal_with_function_args();  break;
    default:  break;
  }
 
  Deal_with_pointers();
 
  /*处理在读入标识符之前压入堆栈的符号*/
  while(-1 < top)
  {
    if('(' == stack[top].type)
    {
      pop;
      Gettoken();
      Deal_with_declarator();
    }
    else
      printf("%s ", pop.string);
  }
  return;
}

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 ");
  }
  return;
}

void Deal_with_function_args(void)
{
  while(')' != this.type)
    Gettoken();
  Gettoken();
  printf("function returning ");
  return;
}

void Deal_with_pointers(void)
{
  while('*' == stack[top].type)
    printf("%s ", pop.string);
  return;
}

 

 

farsight@farsight-ubuntu:~/chendan/link$ ./cdecl
输入一个C语言声明,cdecl程序会把声明转化成通俗文字:
int *p
p is pointer to int
是否进行下一个声明的推断(y/n)?y
char *const *(*next)()   
next is pointer to function returning pointer to read-only pointer to char

 

 

原创粉丝点击