正文

2007\05\192007-05-19 23:21:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/flyprogram/26009.html

分享到:

3.8  理解所有分析过程的代码段
    编写一个程序,把C语言的声明翻译成通俗的语言:
      主要的数据结构是一个stack,我们从左向右读取,把各个标记依次压入stack,直到读到标示符为止。然后我们继续向右读入一个标记,也就是标示符右边的那个标记。接着,观察标示符左边的那个标记(需要从stack中弹出)。
      数据结构大致如下:
          struct token{
                      char type;
                      char string[MAXTOKENLEN];}
      /* 保存第一个标示符之前的所有标记 */
       struct token stack[MAXTOKENS];
      /* 保存刚读入的那个标记 */
       struct token this;
     伪代码如下:
     实用程序---------
     classify_string(字符串分类)
         查看当前的标记,
         通过this.type返回一个值,内容为"type(类型)","gualifier(限定符)"或"indentifier(标示         符)"
     gettoken(取标记)
     把下一个标记读入this.string
         如果是字母数字组合,调用classify_string
         否则,它必须是一个单字符标记,this.type 该标记用一个NUL结束this.string
     read_to_first_identifier(读至第一个标示符)
         调用getoken,并把标记压入到stack中,直到遇见第一个标示符。
         Print"identifier is ",this.string;
         继续调用gettoken.
   解析程序--------
     deal_with_function_args(处理函数参数)
           当读取越过右括号')'后,打印"函数返回"
     deal_with_arrays(处理函数数组)
           当读取"[size]"后,将其打印并继续向右读取。
     deal_with_any_pointers(处理任何指针)
           当你从stack中读取'*'时,打印"指向...的指针"并将其弹出stack.
     deal_with_declarator(处理声明器)
           if this.type is '['   deal_with_arrays;
           if this.type is '{'   deal_with_function_args;
           deal_with_any_pointers;
           while stack里还有东西
           if 它是一个左括号'('
              将其弹出,并调用gettoken;应该获得右括号')'
              deal_with_declarator
           else 将其弹出stack并打印它。

   主程序---------
     main
        read_to_first_identifier
        deal_with_declarator   

code:

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

enum tyoe_tag{ IDENTIFIER,QUALIFIER,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;
void deal_with_declarator();
enum tyoe_tag classify_string(void);
void gettoken(void);
void read_to_first_identifier();
void deal_with_arrays();

enum tyoe_tag classify_string(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,"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)
{/* 读取下一个标记到"this" */
    
     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_string();
        return;
     }
    
     if(*p=='*'){
         strcpy(this.string,"pointer to");
         this.type = '*';
         return;
     }
     this.string[1] = '\0';
     this.type = *p;
     return;
}
/* 理解所有分析过程的代码 */
void read_to_first_identifier(){
    gettoken();
    while(this.type != IDENTIFIER){
                    push(this);
                    gettoken();
    }
    printf("%sis ",this.string);
    gettoken();                          
}      

void deal_with_arrays(){
     while(this.type=='['){
          printf("array ");
          gettoken(); /* 数字或']' */
          if(isdigit(this.string[0])){
                printf("0..%d",atof(this.string-1));
                gettoken();  /* 读取']' */                          
          }
          gettoken();   /*  读取']'之后的再一个标记  */ 
          printf("of ");                     
     }                  
}

void deal_with_function_args(){
     while(this.type != '|'){
           gettoken();           
     }
     gettoken();
     printf("function returning ");                    
}
void deal_with_pointers(){
     while(stack[top].type=='*'){
            printf("%s ",pop.string);                           
     }    
}
void deal_with_declarator(){
     /* 处理标识符之后可能存在的数组/函数 */
     switch(this.type){
         case '[': deal_with_arrays();break;
         case '(': deal_with_function_args();
     }
    
     deal_with_pointers();
    
     /* 处理在读入到标识符之前压入stack中的符号 */
     while(top >= 0){
         if(stack[top].type=='('){
             pop;
             gettoken();  /* 读取')'之后的符号*/
             deal_with_declarator();                        
         }
         else{
             printf("%s ",pop.string);    
         }     
     }                     
}
int main()
{
    /* 将标记压入stack中,直到遇见标识符 */
    read_to_first_identifier();
    deal_with_declarator();
    printf("\n");
    system("pause");
    return 0;
   
}

阅读(1952) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册