K&Rを読もう(18) 演習 1-24 括弧の釣合(2)

相当自信無し。

#include <stdio.h>
#include <stdlib.h>

#define MAX_BUFFER 1024

enum {OUT, COMMENT_IN, SQ_IN, DQ_IN};

void err_exit(void)
{
    fprintf(stderr, "釣合が取れてません。\n");
    exit(EXIT_FAILURE);
}

int main(void)
{
    int c,d,next;
    int i = 0;
    int status = OUT;
    char buffer[MAX_BUFFER];
    
    c = getchar(); /* 現在の文字 */

    while (c != EOF) {
        next = getchar();
        /* コメントの無視 */
        if (c == '/' && next == '*' && status == OUT)
            status = COMMENT_IN;
        else if (c == '*' && next == '/' && status == COMMENT_IN) {
            next = getchar();
            status = OUT;
        }
        
        /* エスケープ無視 */
        else if (c == '\\' && next == '\'' ||
                 c == '\\' && next == '\"') {
            next = getchar();
            c = next;
            next = getchar();
        }

        /* クオート無視 */
        else if (c == '\'') {
            if (status == OUT)
                status = SQ_IN;
            else if (status == SQ_IN)
                status = OUT;
        } else if (c == '\"') {
            if (status == OUT)
                status = DQ_IN;
            else if (status == DQ_IN)
                status = OUT;
        }

        /* 括弧のチェック */
        if (status == OUT) {
            if(c == '(' || c == '{' || c == '[')
                buffer[i++] = c;
            else if (c == ')' || c == '}' || c == ']') {
                if (i <= 0)
                    err_exit();

                d = buffer[--i];
                printf("level %2d : [%c:%c]\n", i + 1, d, c);
                if ( d == '(' && c != ')' ||
                     d == '{' && c != '}' ||
                     d == '[' && c != ']')
                    err_exit();
            }
        }
        c = next;
    }
    if (i != 0)
        err_exit();
    else
        printf("OK\n");

    exit(EXIT_SUCCESS);
}

とりあえずチェックは成功するが、あんまりうまくない。

フラグを使わず関数に分けた方が断然良かった(汗

構想段階で、エスケープの処理が頭に入ってなかったのが不味かった。後で書き直すかな・・・。