源码--函数申明分析
时间:2010-12-02 来源:bluesky2254
/*
摘自C专家编程
function name:declaration.c
description:函数申明分析
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define MAXTOKENS 100
#define MAXTOKENLEN 64 enum type_tag {IDENTIFIER,QUALIFER,TYPE}; struct token {
char type;
char string[MAXTOKENLEN];
};
int top = -1;
struct token stack[MAXTOKENS];
struct token this; #define pop stack[top--]
#define push(s) stack[++top] = s /*推断标识符的类型*/
enum type_tag classify_string(void)
{
char *s = this.string;
if(!strcmp(s,"const")){
strcpy(s,"read-only");
return QUALIFER;
}
if(!strcmp(s,"volatile")) return QUALIFER;
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;
} /*读取下一个标记到"this"*/
void gettoken(void)
{
char *p = this.string;
/*略过空白字符*/
while((*p = getchar()) == ' '); //自解读:略过开始的空格符
if(isalnum(*p)){ /*读入的标识符以字母或数字开头*/
while(isalnum(*++p = getchar())); //自解读:输入字符逐字符拷贝,遇到不是字母或数字就返回,意味着遇到空格就返回了。
ungetc(*p,stdin); //自解读:将当前字符退回stdin字符流
*p = '\0';
this.type = classify_string();
return;
}
if(*p == '*'){
strcpy(this.string,"pointer to");
this.type = '*';
return;
}
this.string[1]='\0'; //自解读:用于存储'('或'['
this.type = *p;
return;
} /*理解所有分析过程的代码段*/
read_to_first_identifer(){
gettoken();
while(this.type != IDENTIFIER){
push(this);
gettoken();
}
printf("%s is ",this.string);
gettoken(); } deal_with_arrays(){
while(this.type == '['){
printf("array ");
gettoken(); /*数字或?*/
if(isdigit(this.string[0])){
printf("0..%d ",atoi(this.string)-1);
gettoken(); /*读取']'*/
}
gettoken(); /*读取']'之后的再一个标记*/
printf("of ");
} } deal_with_function_args(){
while(this.type != ')'){
gettoken();
}
gettoken();
printf("function returning ");
} deal_with_pointers(){
while(stack[top].type == '*'){
printf("%s ",pop.string);
}
} /*处理标识符之后可能存在的数组/函数*/
deal_with_declarator(){
switch(this.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);
}
}
}
main()
{
int i;
/*将标记压入堆栈中,直到遇见标识符*/
read_to_first_identifer();
i=top;
while(i)
printf("%s",stack[i--].string);
printf("%s",stack[i].string);
printf("\n");
deal_with_declarator();
printf("\n");
return 0;
}
function name:declaration.c
description:函数申明分析
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define MAXTOKENS 100
#define MAXTOKENLEN 64 enum type_tag {IDENTIFIER,QUALIFER,TYPE}; struct token {
char type;
char string[MAXTOKENLEN];
};
int top = -1;
struct token stack[MAXTOKENS];
struct token this; #define pop stack[top--]
#define push(s) stack[++top] = s /*推断标识符的类型*/
enum type_tag classify_string(void)
{
char *s = this.string;
if(!strcmp(s,"const")){
strcpy(s,"read-only");
return QUALIFER;
}
if(!strcmp(s,"volatile")) return QUALIFER;
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;
} /*读取下一个标记到"this"*/
void gettoken(void)
{
char *p = this.string;
/*略过空白字符*/
while((*p = getchar()) == ' '); //自解读:略过开始的空格符
if(isalnum(*p)){ /*读入的标识符以字母或数字开头*/
while(isalnum(*++p = getchar())); //自解读:输入字符逐字符拷贝,遇到不是字母或数字就返回,意味着遇到空格就返回了。
ungetc(*p,stdin); //自解读:将当前字符退回stdin字符流
*p = '\0';
this.type = classify_string();
return;
}
if(*p == '*'){
strcpy(this.string,"pointer to");
this.type = '*';
return;
}
this.string[1]='\0'; //自解读:用于存储'('或'['
this.type = *p;
return;
} /*理解所有分析过程的代码段*/
read_to_first_identifer(){
gettoken();
while(this.type != IDENTIFIER){
push(this);
gettoken();
}
printf("%s is ",this.string);
gettoken(); } deal_with_arrays(){
while(this.type == '['){
printf("array ");
gettoken(); /*数字或?*/
if(isdigit(this.string[0])){
printf("0..%d ",atoi(this.string)-1);
gettoken(); /*读取']'*/
}
gettoken(); /*读取']'之后的再一个标记*/
printf("of ");
} } deal_with_function_args(){
while(this.type != ')'){
gettoken();
}
gettoken();
printf("function returning ");
} deal_with_pointers(){
while(stack[top].type == '*'){
printf("%s ",pop.string);
}
} /*处理标识符之后可能存在的数组/函数*/
deal_with_declarator(){
switch(this.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);
}
}
}
main()
{
int i;
/*将标记压入堆栈中,直到遇见标识符*/
read_to_first_identifer();
i=top;
while(i)
printf("%s",stack[i--].string);
printf("%s",stack[i].string);
printf("\n");
deal_with_declarator();
printf("\n");
return 0;
}
相关阅读 更多 +