1-24 chk_paren.c
テーブルだらけだなぁ、なんか。
/* * P42 演習1-24 * カッコ、中カッコ、大カッコのつりあいがとれていないといった * プログラムの基本的な構文エラーのチェックを行うプログラムを書け。 * 引用符・2重引用符・コメントなどの処理も忘れないこと。(このプログラム * を完全に汎用的にしようとすると、これを書くのは難しくなる。) * * 2007/06/17 arikui */ #include <stdio.h> #define PAREN 0 #define BRACE 1 #define BRACKET 2 #define NUM_OF_KINDS_OF_PAREN 3 #define NUM_OF_CHARSET 128 #define TRUE 1 #define FALSE 0 #define BUFF_EMPTY -64 int buff = BUFF_EMPTY; int readchar(void){ int c; if (buff == BUFF_EMPTY){ c = getchar(); }else{ c = buff; buff = BUFF_EMPTY; } return c; } void unreadchar(int c){ buff = c; } void flush_comment_rest(int print_p){ int c, t; while((c = readchar()) != EOF){ if (print_p) putchar(c); if (c == '*'){ t = readchar(); if (t == '/') break; else unreadchar(t); } } if (c == EOF) unreadchar(c); } void flush_quotation_rest(int print_p, int q){ int c; while((c = readchar()) != EOF){ if (print_p) putchar(c); if (c == '\\'){ c = readchar(); if (c == EOF) break; if (print_p) putchar(c); }else if (c == q) break; } if (c == EOF) unreadchar(c); } int main(void){ int c, t, i, fl_error, count[NUM_OF_KINDS_OF_PAREN] = {0}; int paren_index_table[NUM_OF_CHARSET] = {0}; char *index_paren_desc_table[NUM_OF_KINDS_OF_PAREN]; paren_index_table['('] = paren_index_table[')'] = PAREN; paren_index_table['{'] = paren_index_table['}'] = BRACE; paren_index_table['['] = paren_index_table[']'] = BRACKET; index_paren_desc_table[PAREN] = "parenthesis"; index_paren_desc_table[BRACE] = "brace"; index_paren_desc_table[BRACKET] = "bracket"; while((c = readchar()) != EOF){ if (c == '\\'){ if ((t = readchar()) == EOF) unreadchar(t); }else if (c == '\'' || c == '"'){ flush_quotation_rest(FALSE, c); }else if (c == '/'){ t = readchar(); if (t == '*') flush_comment_rest(FALSE); else unreadchar(t); }else if (c == '(' || c == '{' || c == '['){ ++count[paren_index_table[c]]; }else if (c == ')' || c == '}' || c == ']'){ --count[paren_index_table[c]]; } } for(fl_error = FALSE, i = 0; i < NUM_OF_KINDS_OF_PAREN; ++i){ if (count[i] != 0){ printf("Syntax error: %s not balanced -- left %s %d\n", index_paren_desc_table[i], index_paren_desc_table[i], count[i]); fl_error = TRUE; } } if (!fl_error) printf("Syntax OK\n"); return 0; }