类型解释器——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

 

你可能感兴趣的:(读书笔记)