Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

c专家编程学习总结——声明篇 #9

Open
maiff opened this issue Feb 11, 2018 · 0 comments
Open

c专家编程学习总结——声明篇 #9

maiff opened this issue Feb 11, 2018 · 0 comments
Labels

Comments

@maiff
Copy link
Owner

maiff commented Feb 11, 2018

cdecl的实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX_LEN 100
enum type_token {IDENTIFIER,QUALIFIER,TYPE};
typedef struct token{
    char string[100];
    char type;
}token;
token tmp_token;
typedef struct stack{
    token array[MAX_LEN];
    int top;
}stack;
struct stack token_stack;
void init(stack *sta)
{
    sta->top=-1;
}
int push(stack *sta,token s)
{
    if(sta->top>=254)
    {
        printf("the stack is full.\n");
        return 1;
    }
    else
    {
        sta->array[++(sta->top)]=s;
    }
    return 0;
}
token pop(stack *sta)
{
    
        return sta->array[(sta->top)--];
    
    
}
int stack_empty(const stack s)
{
    if(s.top==-1)
        return 0;
    else
        return 1;
}
token top_stack(const stack s)
{

        return s.array[s.top];
}
enum type_token classify_string(void);
void gettoken()
{//读取token函数,如果是字母,数字,下划线就一直读取,否则就停止存入tmp_token中处理
    memset(tmp_token.string,'\0',sizeof(tmp_token.string));//先把tmp_token清空
    char *p=tmp_token.string;
    while((*p=getchar())==' ');//略过空白字符
    if(isalnum(*p) || *p=='_'){
        //读入的标志符要是字母,数字或者下划线,表示是标志符
        while(1)
        {
            *(++p)=getchar();
            if(isalnum(*p) || *p=='_')
                continue;
            else
                break;
        }
        ungetc(*p,stdin);//把非满足的字符放回缓冲区,下次再用
        *p='\0';
        tmp_token.type=classify_string();
        return;
    }
    if(*p=='*'){
        strcpy(tmp_token.string,"pointer to ");
        tmp_token.type='*';
        return;
    }
    tmp_token.string[1]='\0';
    tmp_token.type=*p;
    return;
}
enum type_token classify_string()
{//推断标志符的类型
    char *s=tmp_token.string;
    if(!strcmp(s,"const")){
        strcpy(s,"read-only ");
        return QUALIFIER;
    }
    if(!strcmp(s,"volatile")) return QUALIFIER;
    if(!strcmp(s,"extern")) 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 read_first_identifier(){
    gettoken();
    while(tmp_token.type!=IDENTIFIER){
        push(&token_stack,tmp_token);
        gettoken();
    }
    printf("%s is ",tmp_token.string);
    gettoken();
}
void deal_with_array()
{
    while(tmp_token.type=='[')
    {
        printf("array");
        gettoken();
        if(isdigit(tmp_token.string[0]))
        {
            printf(" 0..%d ",atoi(tmp_token.string)-1);
            gettoken();
        }
        gettoken();//读取‘】’之后的token
        printf("of ");
    }
}
void deal_with_function()
{
    while(tmp_token.type != ')')
        gettoken();
    gettoken();
    printf(" function returning ");
}
void deal_with_pointer()
{
    token t;
    t=top_stack(token_stack);
    while(t.type=='*')
    {
        printf("%s",t.string);
        pop(&token_stack);
        t=top_stack(token_stack);
    }
}
void deal_with_declarator(){//递归处理的过程
    switch(tmp_token.type){
        case '[': deal_with_array();break;
        case '(': deal_with_function();
    }
    deal_with_pointer();
    while(stack_empty(token_stack)==1)
    {
        token t=top_stack(token_stack);
        if(t.type=='('){
            pop(&token_stack);
            gettoken();//读取‘)’之后的符号
            deal_with_declarator();
        }
        else
        {
            printf("%s",pop(&token_stack).string);
        }
    }
}



int main()
{
    init(&token_stack);
    read_first_identifier();
    deal_with_declarator();
    printf("\n");
    return 0;
}

我发现我在stdin里,getchar和ungetc的走向不是很熟悉。

然后

晓得union和struct的区别
还有struct里的位段(节省空间)

@maiff maiff added the blog label Feb 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant