UNPKG

@adamsy/bhai-lang

Version:

<h1 align="center">Bhai Lang</h1> <p align="center"> <a href="https://lgtm.com/projects/g/DulLabs/bhai-lang/alerts/"><img alt="Total alerts" src="https://img.shields.io/lgtm/alerts/g/DulLabs/bhai-lang.svg?logo=lgtm&logoWidth=18"/></a> <a href="https://lgt

74 lines (57 loc) 1.66 kB
import { Spec } from "../../constants/bhaiLangSpec"; import InvalidStateException from "../../exceptions/invalidStateException"; import { Token, Tokenizer } from "./types"; export default class TokenizerImpl implements Tokenizer { private _spec: Spec; private _string: String | undefined = undefined; private _cursor: number; constructor(spec: Spec) { this._spec = spec; this._cursor = 0; } initTokenizer(stringToTokenize: String) { this._string = stringToTokenize; this._cursor = 0; } isEOF() { if (!this._string) return true; return this._cursor === this._string.length; } hasMoreTokens() { if (!this._string) return false; return this._cursor < this._string.length; } getNextToken(): Token | null { if (!this._string) throw new InvalidStateException( "Tokenizer is not initialized with string. " + "Please call initTokenizer method first." ); if (!this.hasMoreTokens()) { return null; } const string = this._string.slice(this._cursor); for (const { regex, tokenType } of this._spec) { const tokenValue = this._matched(regex, string); if (tokenValue === null) { continue; } if (tokenType === null) { return this.getNextToken(); } return { type: tokenType, value: tokenValue, }; } throw new SyntaxError(`Unexpected token: "${string[0]}"`); } _matched(regex: RegExp, string: string) { const matched = regex.exec(string); if (matched === null) { return null; } this._cursor += matched[0].length; return matched[0]; } }