演習5-19 K&R プログラミング言語C
2010年02月20日
演習5-19
type
が *
の場合は pre_type
に *
を保存してから次のループに移る。
pre_type
が *
かつ type
が PARENS
か BRACKETS
の場合には、それまでの出力文字列 out
をカッコでくくる。
#include <stdio.h> #include <string.h> #include <ctype.h> #define MAXTOKEN 100 #define BUFSIZE 100 char buf[BUFSIZE]; /* ungetch 用のバッファ */ int bufp = 0; /* buf 中の次の空き位置 */ int getch(void); void ungetch(int); enum { NAME, PARENS, BRACKETS }; int gettoken(void); int tokentype; /* 最後のトークンの型 */ char token[MAXTOKEN]; /* 最後のトークン文字列 */ char name[MAXTOKEN]; /* 識別名 */ char datatype[MAXTOKEN]; /* データ型 = char, int など */ char out[1000]; /* 出力文字列 */ /* undcl : ことばによる記述を宣言に変換する */ int main(void) { int type, pre_type; char temp[MAXTOKEN]; while (gettoken() != EOF) { strcpy(out, token); while ((type = gettoken()) != '\n') { if (pre_type == '*') { if (type == PARENS || type == BRACKETS) { sprintf(temp, "(*%s)", out); } else { sprintf(temp, "*%s", out); } strcpy(out, temp); } if (type == PARENS || type == BRACKETS) { strcat(out, token); } else if (type == '*') { /* type が * の場合はそのまま次のループヘ */ } else if (type == NAME) { sprintf(temp, "%s %s", token, out); strcpy(out, temp); } else { fprintf(stderr, "invalid input at %s\n", token); } pre_type = type; } printf("%s\n", out); } return 0; } int gettoken(void) /* 次のトークンを返す */ { int c, getch(void); void ungetch(int); 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) /* (押し戻された可能性もある) 1文字をとってくる */ { return (bufp > 0) ? buf[--bufp] : getchar(); } void ungetch(int c) /* 文字を入力に押し戻す */ { if (bufp > BUFSIZE) fprintf(stderr, "ungetch : too many characters\n"); else buf[bufp++] = c; }
K&R 第2版 149 ページの宣言と言葉による表現を元の undcl
と修正した undcl
とで実行してみる。
元の undcl
での実行結果
$ ./undcl argv * * char char (*(*argv)) daytab * [13] int int (*daytab)[13] daytab [13] * int int (*daytab[13]) comp () * void void (*comp()) comp * () void void (*comp)() x () * [] * () char char (*(*x())[])() x [3] * () * [5] char char (*(*x[3])())[5]
修正した undcl
での実行結果
$ ./undcl argv * * char char **argv daytab * [13] int int (*daytab)[13] daytab [13] * int int *daytab[13] comp () * void void *comp() comp * () void void (*comp)() x () * [] * () char char (*(*x())[])() x [3] * () * [5] char char (*(*x[3])())[5]
プログラミング言語C 第2版 ANSI規格準拠
posted with amazlet at 09.11.27
B.W. カーニハン D.M. リッチー
共立出版
売り上げランキング: 9726
共立出版
売り上げランキング: 9726