開発環境
- OS X Lion - Apple(OS)
- Emacs、BBEdit - Bare Bones Software, Inc. (Text Editor)
- プログラミング言語: C
- Clang (コンパイラ)
プログラミング言語C 第2版 ANSI規格準拠 (B.W. カーニハン D.M. リッチー (著)、 石田 晴久 (翻訳)、共立出版)の第5章(ポインタと配列)、5.12(複雑な宣言)、演習5-20を解いてみる。
その他参考書籍
- プログラミング言語Cアンサー・ブック 第2版 (クロビス・L.トンド、スコット・E.ギンペル(著)、矢吹 道郎(翻訳))
演習 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 コメント:
コメントを投稿