private void IdList(LexemeSet stopSet) { bool complete; do { // we expect an identifier if (CheckOrSkip(LexemeSet.From(LexemeType.Identifier), stopSet + LexemeType.Semicolon + LexemeType.Comma)) { // we got an identifier add it to the symbol table // adding a duplicate symbol outputs a warning, this is really semantic analysis // but we do that in this phase for convinience symbolTable.Declare(currentLexeme.Value.ToString()); NextLexeme(); } // move past the training comma or the terminating semi colon CheckOrSkip(LexemeSet.From(LexemeType.Semicolon, LexemeType.Comma), stopSet + LexemeType.Identifier + LexemeType.Comma); // were are complete if the next token _isn't_ a comma or another identifier complete = currentLexeme.Type is not(LexemeType.Comma or LexemeType.Identifier); // if we are on a comma step over it StepOverCurrentLexemeIfItsA(LexemeType.Comma); } while (!complete); StepOverCurrentLexemeIfItsA(LexemeType.Semicolon); }