A parser can move through named phases and enter an error state when input fails.

Parser Phase

parser_phase.c
#include <stdio.h>

enum ParsePhase {
    PARSE_HEADER,
    PARSE_BODY,
    PARSE_DONE,
    PARSE_ERROR
};

enum ParsePhase readLine(enum ParsePhase phase, int lineOk) {
    if (!lineOk) {
        return PARSE_ERROR;
    }
    if (phase == PARSE_HEADER) {
        return PARSE_BODY;
    }
    if (phase == PARSE_BODY) {
        return PARSE_DONE;
    }
    return phase;
}

int main(void) {
    int secondLineOk = ;
    enum ParsePhase phase = PARSE_HEADER;

    phase = readLine(phase, 1);
    phase = readLine(phase, secondLineOk);

    printf("secondLineOk=%d phase=%d\n", secondLineOk, phase);
    return 0;
}
#include <stdio.h>

enum ParsePhase {
    PARSE_HEADER,
    PARSE_BODY,
    PARSE_DONE,
    PARSE_ERROR
};

enum ParsePhase readLine(enum ParsePhase phase, int lineOk) {
    if (!lineOk) {
        return PARSE_ERROR;
    }
    if (phase == PARSE_HEADER) {
        return PARSE_BODY;
    }
    if (phase == PARSE_BODY) {
        return PARSE_DONE;
    }
    return phase;
}

int main(void) {
    int secondLineOk = ;
    enum ParsePhase phase = PARSE_HEADER;

    phase = readLine(phase, 1);
    phase = readLine(phase, secondLineOk);

    printf("secondLineOk=%d phase=%d\n", secondLineOk, phase);
    return 0;
}
phase Phases make a parser's progress visible and testable.
error An error transition can override the normal path and preserve the failure state.