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

やはり気になるので修正を加えた。

引用符'\\'の処理でかなりハマった。

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

void next(int *cp, int *np)
{
    *cp = *np;
    *np = getchar();
}

void quote(char q, int *cp, int *np)
{
    while (*cp != EOF) {
        next(cp, np);
        if (*cp == '\\') {
            next(cp, np);
        } else if (*cp == q) {
            break;
        }
    }
}

void comment(int *cp, int *np)
{
    while (*cp != EOF) {
        next(cp, np);
        if (*cp == '*' && *np == '/') {
            next(cp, np);
            break;
        }
    }
}

void err_exit(const char s[])
{
    fprintf(stderr, s);
    exit(EXIT_FAILURE);
}

int main(void)
{
    int c,n;
    int d;
    int i = 0;
    const int stack_size = 1024;
    char stack[stack_size];
    
    c = getchar(); /* 現在の文字 */
    n = c;

    while (c != EOF) {
        next(&c, &n);

        if (c == '/' && n == '*') {
            next(&c, &n);
            comment(&c, &n);
        }
        else if (c == '\'')
            quote('\'', &c, &n);
        else if (c == '\"')
            quote('\"', &c, &n);

        if(c == '(' || c == '{' || c == '[')
            stack[i++] = c;
        else if (c == ')' || c == '}' || c == ']') {
            if (i <= 0)
                err_exit("閉じすぎですよ。\n");

            d = stack[--i];
            printf("level %2d : [%c:%c]\n", i + 1, d, c);
            if ( d == '(' && c != ')' ||
                 d == '{' && c != '}' ||
                 d == '[' && c != ']')
                err_exit("同じので閉じよう。\n");
        }
        /* putchar(c); */
    }
    if (i != 0)
       err_exit("たぶん開きすぎです。\n");
    else
        printf("OK\n");

    exit(EXIT_SUCCESS);
}

イメージに近い感じになった。

  • コメントや引用符は別関数でスキップさせるようにした。
  • //コメントには対応してません。
  • バックスラッシュがあったら全部無視の方向で(汗

もっと抽象化出来そうな予感。同じような処理が3箇所もある。