C //练习 5-20 扩展dcl程序的功能,使它能够处理包含其他成分的声明,例如带有函数参数类型的声明、带有类似于const限定符的声明等。

发布时间:2024年01月14日

C程序设计语言 (第二版) 练习 5-20

练习 5-20 扩展dcl程序的功能,使它能够处理包含其他成分的声明,例如带有函数参数类型的声明、带有类似于const限定符的声明等。

注意:代码在win32控制台运行,在不同的IDE环境下,有部分可能需要变更。
IDE工具:Visual Studio 2010

?

代码块:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXTOKEN 100

enum { NAME, PARENS, BRACKETS };
enum { ERR_YES, ERR_NO };

void dcl(void);
void dirdcl(void);

int gettoken(void);
int tokentype; 
char token[MAXTOKEN]; 
char name[MAXTOKEN]; 
char datatype[MAXTOKEN];
char out[1000];
int errtoken = ERR_NO;

int main() {
    while (gettoken() != EOF) {
        strcpy(datatype, token);
        out[0] = '\0';
        dcl(); 
        if (tokentype != '\n')
            printf("syntax error\n");
        printf("%s: %s %s\n", name, out, datatype);
    }
    return 0;
}

void dcl(void) {
    int ns;

    for (ns = 0; gettoken() == '*'; ) 
        ns++;
    dirdcl();
    while (ns-- > 0)
        strcat(out, " pointer to");
}

void paramdcl(void);

void dirdcl(void) {
    int type;

    if (tokentype == '(') { 
        dcl();
        if (tokentype != ')') {
            printf("missing )\n");
            errtoken = ERR_YES;
        }
    } else if (tokentype == NAME) 
        strcpy(name, token);
    else {
        printf("error: expected name or (dcl)\n");
        errtoken = ERR_YES;
    }

    while ((type=gettoken()) == PARENS || type == BRACKETS || type == '(')
        if (type == PARENS)
            strcat(out, " function returning");
        else if (type == '(') {
            strcat(out, " function expecting");
            paramdcl();
            strcat(out, " and returning");
        } else {
            strcat(out, " array");
            strcat(out, token);
            strcat(out, " of");
        }
}

void dclspec(void);

void paramdcl(void) {
    do {
        dclspec();
    } while (tokentype == ',');

    if (tokentype != ')')
        printf("error: missing ) in parameter declaration");
}

int typespecifier(void);
int typequalifier(void);

void dclspec(void) {
    char temp[MAXTOKEN];
    temp[0] = '\0';
    gettoken();

    do {
        if (tokentype != NAME) {
            errtoken = ERR_YES;
            dcl();
        } else if (typespecifier() || typequalifier()) {
            strcat(temp, " ");
            strcat(temp, token);
            gettoken();
        } else {
            printf("error: unknown type in param list\n");
            errtoken = ERR_YES;
        }
    } while (tokentype != ',' && tokentype != ')');

    strcat(out, temp);
    if (tokentype == ',')
        strcat(out, ",");
}

int compare(const void *s, const void *t);

int typespecifier(void) {
    static char *type[] = { "char", "int", "void" };
    char *pt = token;

    if (bsearch(&pt, type, sizeof(type)/sizeof(char *), sizeof(char *), compare) == NULL)
        return 0;
    return 1;
}

int typequalifier(void) {
    static char *type[] = { "const", "volatile" };
    char *pt = token;

    if (bsearch(&pt, type, sizeof(type)/sizeof(char *), sizeof(char *), compare) == NULL)
        return 0;
    return 1;
}

int compare(const void *s, const void *t) {
    char **chs;
    char **cht;
    chs = (char **) s;
    cht = (char **) t;
    return strcmp(*chs, *cht);
}

int getch(void);
void ungetch(int);

int gettoken(void) {
    int c;
    char *p = token;

    if (errtoken == ERR_YES) {
        errtoken = ERR_NO;
        return tokentype;
    }

    while ((c = getch()) == ' ' || c == '\t')
        ;

    if (c == '(') {
        if ((c = getch()) == ')') {
            strcpy(token, "()");
            return tokentype = PARENS;
        } else {
            ungetch(c);
            return tokentype = '(';
        }
    } else if (c == '[') {
        for (*p++ = c; (*p++ = getch()) != ']'; )
            ;
        *p = '\0';
        return tokentype = BRACKETS;
    } else if (isalpha(c)) {
        for (*p++ = c; isalnum(c = getch()); )
            *p++ = c;
        *p = '\0';
        ungetch(c);
        return tokentype = NAME;
    }

    return tokentype = c;
}

#define BUFSIZE 100

char buf[BUFSIZE]; 
int bufp = 0; 

int getch(void) {
    return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(int c) { 
    if (bufp >= BUFSIZE)
        printf("ungetch: too many characters\n");
    else
        buf[bufp++] = c;
}
文章来源:https://blog.csdn.net/navicheung/article/details/135581470
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。