Exercise 1.24 - Check rudimentary Syntax Errors in a C Program

Question

Write a program to check a C program for rudimentary syntax errors like unmatched parentheses,brackets and braces. Don’t forget about quotes, both single and double, escape sequences, and comments. (This program is hard if you do it in full generality.)

Solution

/**
 *
 * Exercise 1.24 - Syntax Errors.
 *
 * Program to check rudimentary syntax errors like un-match braces,
 * brackets or parenthesis.
 *
 **/

#include <stdio.h>

int brace, brack, paren;

void incomment();

void inquote(int c);

void search(int c);

int main(void) {
    int c;

    extern int brace, brack, paren;

    while ((c = getchar()) != EOF)
        if (c == '/')
            if ((c = getchar()) == '*')
                incomment();
            else
                search(c);
        else if (c == '\'' || c == '"')
            inquote(c);
        else
            search(c);

    if (brace < 0) {
        printf("Unmatched Braces\n");
        brace = 0;
    } else if (brack < 0) {
        printf("Unmatched brackets\n");
        brack = 0;
    } else if (paren < 0) {
        printf("Unmatched parenthesis\n");
        paren = 0;
    }

    if (brace > 0)
        printf("Unmatched braces\n");
    else if (brack > 0)
        printf("Unmatched brackets\n");
    else if (paren > 0)
        printf("Unmatched parenthesis\n");

    return 0;
}

void incomment() {
    int c, d;

    c = getchar();
    d = getchar();

    while (c != '*' || d != '/') {
        c = d;
        d = getchar();
    }
}

void inquote(int c) {
    int d;

    putchar(c);

    while ((d = getchar()) != c)
        if (d == '\\')
            getchar();
}

void search(int c) {
    extern int brace, brack, paren;

    if (c == '{')
        --brace;
    else if (c == '}')
        ++brace;
    else if (c == '[')
        --brack;
    else if (c == ']')
        ++brack;
    else if (c == '(')
        --paren;
    else if (c == ')')
        ++paren;
}

Explanation

We divide the program up into 3 parts. The text of the program when it is in- comment, in-quote and rest of the program text. We don’t to have worry about the part when we are in-comment or in-quote because we can find non-matching brankets or braces in those parts. It is only the rest that we care about.

When a two sequence characters starts with /* we enter in-comment block and continue till we end up with */

When a single quote ' or a double quote " character is found, we do the same and continue till we find it’s match.

For the rest of the program, when we first match a brace, bracket or parenthesis, we mark it as -1 and when we find it’s match, we negate it back to 0. If these values end up being anythign other than 0, we say that we found a mismatch.