2013年5月17日金曜日

開発環境

プログラミング言語C 第2版 ANSI規格準拠 (B.W. カーニハン D.M. リッチー (著)、 石田 晴久 (翻訳)、共立出版)の第5章(ポインタと配列)、5.12(複雑な宣言)、演習5-20を解いてみる。

その他参考書籍

演習 5-20.

コード

sample.c

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define MAXTOKEN 100
#define BUFSIZE 100

enum { NAME, PARENS, BRACKETS };
enum { NO, YES};

void dcl(void);
void dirdcl(void);
void pardcl(void);
int gettoken(void);
int getch(void);
void ungetch(int);
int tokentype;
char token[MAXTOKEN];
char name[MAXTOKEN];
char datatype[MAXTOKEN];
char out[1000];
char buf[BUFSIZE];
int bufp = 0;
int pretokentype = 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 dirdcl(void)
{
    int type;

    if (tokentype == '(') {
        dcl();
        if (tokentype != ')') {
            printf("error: missing )\n");
            pretokentype = YES;
        }
    } else if (tokentype == NAME) {
        strcpy(name, token);
    } else {
        pretokentype = YES;
    }
    while ((type = gettoken()) == PARENS || type == BRACKETS || type == '(')
        if (type == PARENS)
            strcat(out, " function returning");
        else if (type == '(') {
            strcat(out, " function expecting");
            pardcl();
            strcat(out, " and returning");
        } else {
            strcat(out, " array");
            strcat(out, token);
            strcat(out, " of");
        }
}

void pardcl(void)
{
    char tmp[MAXTOKEN];
    tmp[0] = '\0';
    do {
        gettoken();
        do {
            if (tokentype != NAME) {
                pretokentype = YES;
                dcl();
            } else if (strcmp(token, "char") == 0 ||
                       strcmp(token, "int") == 0 ||
                       strcmp(token, "float") == 0 ||
                       strcmp(token, "double") == 0 ||
                       strcmp(token, "void") == 0) {
                strcat(tmp, " ");
                strcat(tmp, token);
                gettoken();             
            } else if (strcmp(token, "const")) {
                strcat(tmp, " ");
                strcat(tmp, token);
                gettoken();
            }
        } while (tokentype != ',' && tokentype != ')');
        strcat(out, tmp);
        if (tokentype == ',')
            strcat(out, ",");
    } while (tokentype == ',');
}

int gettoken(void)
{
    if (pretokentype == YES) {
        pretokentype = NO;
        return tokentype;
    }
    int c;
    char *p = token;
    
    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;
    } else
        return tokentype = c;
}

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;
}

入出力結果(Terminal)

$ cat tmp.txt
char **argv
int (*daytab)[13]
void *cmp()
void (*cmp)()
char (*(*x())[])()
char (*(*x[3])())[5]
void f(int)
void (**(**f))(char *, int *, float, double, g(), h(int))
$ cat tmp.txt | ./a.out
argv:  pointer to pointer to char
daytab:  pointer to array[13] of int
cmp:  function returning pointer to void
cmp:  pointer to function returning void
x:  function returning pointer to array[] of pointer to function returning char
x:  array[3] of pointer to function returning pointer to array[5] of char
f:  function expecting int and returning void
int:  pointer to pointer to pointer to pointer to function expecting pointer to char, pointer to char int, char int float, char int float double, function returning char int float double g, char int float double g h and returning void
$

0 コメント:

コメントを投稿