类型解释器——C专家编程读书笔记

对于声明,应该按下面的步骤来进行解释:

1) 声明从它的名字开始读取,然后按照优先级顺序依次读取

2) 优先级顺序

a) 括号括起来的部分

b) 后缀操作符,()表示函数,[]表示数组

c) 前缀操作符,*表示指针

3) 如果const或volatile关键字后面紧跟类型说明符,那么他作用于类型说明符,其他情况下,作用于其左边紧邻的指针星号。

 

根据这个原则,我们可以得到下面的代码

 

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define MAXTOKENS 100
#define MAXTOKENLEN 64

enum type_tag { IDENTIFIER, QUALIFIER, TYPE };

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

int top = -1;
struct token stack[MAXTOKENS];
struct token that;

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


enum type_tag classify_string(void)

{
 char *s = that.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, "signed")) return TYPE;
 if (!strcmp(s, "unsigned")) return TYPE;
 if (!strcmp(s, "short")) 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, "struct")) return TYPE;
 if (!strcmp(s, "union")) return TYPE;
 if (!strcmp(s, "enum")) return TYPE;
 return IDENTIFIER;
}

void gettoken (void)
{
 char *p = that.string;

 
 while ((*p = getchar()) == ' ');

 if (isalnum(*p)){
  
  while (isalnum(*++p = getchar()));
  ungetc(*p, stdin);
  *p = '\0';
  that.type = classify_string();
  return;
 }

 if (*p == '*') {
  strcpy(that.string, "pointer to");
  that.type = *p;
  return;
 }
 that.string[1] = '\0';
 that.type = *p;
 return;
}

void read_to_first_identifier (){
 gettoken();
 while (that.type != IDENTIFIER) {
  push(that);
  gettoken();
 }
 printf("%s is ", that.string);
 gettoken();
}

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

void deal_with_function_args() {
 while (that.type != ')') {
  gettoken();
 }
 gettoken();
 printf("function returning ");
}

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

void deal_with_declarator() {
 
 switch(that.type){
 case '[' :deal_with_arrays();break;
 case '(' :deal_with_function_args();
 }

 deal_with_pointers();

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

 

int (*a)()

结果:

a is pointer to function returning int

过程:
读入int
读入(
读入*
读入a
a是标识符,退出开始的循环
输出a is
读入),由于有)暂不读入后面字符,弹出*,输出pointer to,
一直弹出,直到(则继续读取后面的字符(,
因为读到(,输出function returning.


int *a()

结果:

a is function returning pointer to int

过程:

读入int
读入*
读入a
a是标识符,退出开始的循环
输出a is
读入(判断出a是个函数输出function returning
读取*,输出pointer to
读取int,输出int

 

posted @ 2013-11-29 14:52  Jingle Guo  阅读(275)  评论(0编辑  收藏  举报