Skip to content

Instantly share code, notes, and snippets.

@MystPi
Created September 19, 2023 13:57
Show Gist options
  • Save MystPi/ff40649653f6288ee471c208e4bec7bc to your computer and use it in GitHub Desktop.
Save MystPi/ff40649653f6288ee471c208e4bec7bc to your computer and use it in GitHub Desktop.
A base class for creating a recursive descent parser. Based on https://craftinginterpreters.com/parsing-expressions.html#the-parser-class
class RecursiveDescentParser<T extends { type?: string }> {
private readonly tokens: T[];
private current = 0;
constructor(tokens: T[]) {
this.tokens = tokens;
}
/**
* Check if the current token matches one of the given types
*/
match(...types: string[]) {
for (const type of types) {
if (this.check(type)) {
this.advance();
return true;
}
}
return false;
}
/**
* Expect the current token to be of the given type, then `advance`
*/
consume(type: string, message?: string) {
if (this.check(type)) return this.advance();
// Customize error handling to your liking
throw new SyntaxError(message);
}
/**
* Check if the current token is of the given type
*/
check(type: string) {
if (this.isAtEnd()) return false;
return this.peek().type === type;
}
/**
* Consume the current token and return it
*/
advance() {
if (!this.isAtEnd()) this.current++;
return this.previous();
}
/**
* Check if we have used up all of the tokens
*/
isAtEnd() {
return this.current >= this.tokens.length;
}
/**
* Return the current token without consuming it
*/
peek() {
return this.tokens[this.current];
}
/**
* Return the most recently consumed token
*/
previous() {
return this.tokens[this.current - 1];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment