2013年4月8日月曜日

開発環境

プログラミング言語C 第2版 ANSI規格準拠 (B.W. カーニハン D.M. リッチー (著)、 石田 晴久 (翻訳)、共立出版)の第1章(やさしい入門)、1.10(外部変数と通用範囲)の演習 1-23、1-24を解いてみる。

その他参考書籍

演習 1-23.

コード

sample.c

#include <stdio.h>

void remove_comment(int c);
void comment();
void quote(int c);

/* コードからコメントを削除 */
int main()
{
    int c;
    while ((c = getchar()) != EOF) {
        remove_comment(c);
    }
    printf("/* \"これはコメントではない\" */\n");
    putchar('/');
    putchar('*');
    putchar('*');
    putchar('/');
    putchar('\n');
    return 0;
}

/* ただの文字列かコメントかを判断しながら 
 * コメントを見つける
 */
void remove_comment(int c)
{
    int d;
    if (c == '/')
        if ((d = getchar()) == '*')
            comment();
        else if (d == '/') {
            putchar('/');
            remove_comment(d);
        } else {
            putchar('/');
            putchar(d);
        }
    else if (c == '"' || c == '\'') {
        putchar(c);
        quote(c);
    }
    else
        putchar(c);
}

/* コメントの終わりを見つけてコメントを削除 */
void comment()
{
    int c, d;
    c = getchar();
    d = getchar();
    while(c != '*' || d != '/') {
        c = d;
        d = getchar();
    }
}

/* コメントではない文字列を削除するのを防ぐ */
void quote(int c)
{
    int d;
    while ((d = getchar()) != c) {
        putchar(d);
        if (d == '\\') {
            d = getchar();
            putchar(d);
        }
    }
}

入出力結果(Terminal)

$ cat sample.c | ./a.out
#include <stdio.h>

void remove_comment(int c);
void comment();
void quote(int c);


int main()
{
    int c;
    while ((c = getchar()) != EOF) {
        remove_comment(c);
    }
    printf("/* \"これはコメントではない\" */\n);
    putchar('/);
    putchar('*);
    putchar('*);
    putchar('/);
    putchar('\n);
    return 0;
}


void remove_comment(int c)
{
    int d;
    if (c == '/)
        if ((d = getchar()) == '*)
            comment();
        else if (d == '/) {
            putchar('/);
            remove_comment(d);
        } else {
            putchar('/);
            putchar(d);
        }
    else if (c == '" || c == '\') {
        putchar(c);
        quote(c);
    }
    else
        putchar(c);
}


void comment()
{
    int c, d;
    c = getchar();
    d = getchar();
    while(c != '* || d != '/) {
        c = d;
        d = getchar();
    }
}


void quote(int c)
{
    int d;
    while ((d = getchar()) != c) {
        putchar(d);
        if (d == '\\) {
            d = getchar();
            putchar(d);
        }
    }
}
/* "これはコメントではない" */
/**/
$

演習 1-24.

コード

sample.c

#include <stdio.h>

int parentheses, brackets, braces; /* () [] {} */
void find_error(int c);
void skip_comment();
void quote(int c);

int main()
{
    int c;
    extern int parentheses, brackets, braces;
    
    while ((c = getchar()) != EOF) {
        if (c == '/')
            if((c = getchar()) == '*')
                skip_comment();
            else
                find_error(c);
        else if (c == '"' || c == '\'')
            quote(c);
        else
            find_error(c);
        if (parentheses < 0) {
            printf("エラー「(」\n");
            parentheses = 0;
        }
        if (brackets < 0) {
            printf("エラー「[」\n");
            brackets = 0;
        }
        if (braces < 0) {
            printf("エラー「{」\n");
            braces = 0;
        }
    }
    if (parentheses > 0)
        printf("エラー「)」\n");
    if (brackets > 0)
        printf("エラー「]」\n");
    if (braces > 0)
        printf("エラー「}」\n");
    return 0;
}

/* 釣り合いがとれてない括弧を探す */
void find_error(int c)
{
    extern int parentheses, brackets, braces;
    if (c == '(')
        ++parentheses;
    else if (c == '[')
        ++brackets;
    else if (c == '{')
        ++braces;
    else if (c == ')')
        --parentheses;
    else if (c == ']')
        --brackets;
    else if (c == '}')
        --braces;
}

/* コメント内の括弧は無視するためにコメントは探さない
 * ([[ }
 */
void skip_comment()
{
    int c, d;
    c = getchar();
    d = getchar();
    while(c != '*' || d != '/') {
        c = d;
        d = getchar();
    }
}

/* シングルクォートやダブルクォートで囲まれた括弧は無視 */
void quote(int c)
{
    int d;
    while ((d = getchar()) != c) {
        if (d == '\\')
            getchar();
    }
}

入出力結果(Terminal)

$ cat sample.c|./a.out
$ cat tmp.c
#include <stdio.h>

int main()
{
    printf("(");
    putchar('(');
    printf("]");
    putchar(']');
    /* { */
    printf(}]];
    return 0;
}
$ cat tmp.c|./a.out
エラー「[」
エラー「[」
エラー「{」
エラー「)」
$

0 コメント:

コメントを投稿