現状では、これはパーサーとして非常に理にかなっているため、少し単純化されています。全体は単純な正規表現 "[ab]?c" で記述できます。どうしてもパーサーとして書きたい場合、コードは次のようになります。
Boolean parseA() {
// an A is a B followed by a `c`:
return parseB() && (get_token() == Token.c);
}
Boolean parseB {
// Get a token.
// If it's an `a` or a `b`, consume it.
// Otherwise, throw it back (match null string by consuming nothing).
// Either way, return true (successful match).
//
token current_token = get_token();
if (token != Token.a && token != Token.b)
push_back(current_token);
return true;
}
編集(別の回答に対するコメントへの回答):いいえ、Bに一致する場合は、Token.cを探すべきではありません。B が気にする限り、「a」に一致する、「b」に一致する、またはまったく一致しないという 3 つの可能性があります。次に、A を解析して、B の後に Token.c が続くことを確認する部分に任せます。
たとえば、文法を次のように変更するとします。
あ ::= 紀元前
B ::= a | b | ε
C ::= c | d
'B' の定義は同じなので、他の定義が変更されたからといって変更する必要はありません。同様に、(たとえば) B の後に C が続く任意の文字列を許可するように文法に追加することもできます。