diff --git a/src/lexer.ts b/src/lexer.ts index e0bc57f..6e948eb 100644 --- a/src/lexer.ts +++ b/src/lexer.ts @@ -9,8 +9,6 @@ const MESSAGES = { UNEXP_EOT: 'Unexpected end of template', }; -const BLOCK_COMMENT_REGEX = /\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\//g; -const SINGLE_LINE_COMMENT_REGEX = /\/\/[^\n\r]+?(?:\*\)|[\n\r])/g; export class JsonTemplateLexer { private readonly codeChars: string[]; @@ -18,10 +16,7 @@ export class JsonTemplateLexer { private idx = 0; constructor(template: string) { this.buf = []; - this.codeChars = template - .replace(BLOCK_COMMENT_REGEX, '') - .replace(SINGLE_LINE_COMMENT_REGEX, '') - .split(''); + this.codeChars = template.split(''); } init() { @@ -146,10 +141,62 @@ export class JsonTemplateLexer { return this.buf[steps]; } - private advance(): Token { - while (JsonTemplateLexer.isWhiteSpace(this.codeChars[this.idx])) { + private isLineCommentStart(): boolean { + return this.codeChars[this.idx] === '/' && this.codeChars[this.idx + 1] === '/'; + } + + private isLineCommentEnd(): boolean { + return this.codeChars[this.idx] === '\n'; + } + + private isBlockCommentStart(): boolean { + return this.codeChars[this.idx] === '/' && this.codeChars[this.idx + 1] === '*'; + } + + private isBlockCommentEnd(): boolean { + return this.codeChars[this.idx] === '*' && this.codeChars[this.idx + 1] === '/'; + } + + private skipLineComment() { + if (!this.isLineCommentStart()) { + return; + } + while (!this.isLineCommentEnd()) { ++this.idx; } + ++this.idx; + } + + private skipBlockComment() { + if (!this.isBlockCommentStart()) { + return; + } + while (!this.isBlockCommentEnd()) { + ++this.idx; + } + this.idx = this.idx + 2; + } + + private isWhiteSpace() { + return ' \r\n\t'.includes(this.codeChars[this.idx]); + } + + private skipWhitespace() { + while (this.isWhiteSpace()) { + ++this.idx; + } + } + + private skipInput() { + while (this.isWhiteSpace() || this.isBlockCommentStart() || this.isLineCommentStart()) { + this.skipWhitespace(); + this.skipLineComment(); + this.skipBlockComment(); + } + } + + private advance(): Token { + this.skipInput(); if (this.idx >= this.codeChars.length) { return { @@ -229,10 +276,6 @@ export class JsonTemplateLexer { return '0123456789'.indexOf(ch) >= 0; } - private static isWhiteSpace(ch: string) { - return ' \r\n\t'.indexOf(ch) > -1; - } - private static isIdStart(ch: string) { return ch === '$' || ch === '_' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); } diff --git a/test/scenarios/comments/data.ts b/test/scenarios/comments/data.ts new file mode 100644 index 0000000..ec02d3b --- /dev/null +++ b/test/scenarios/comments/data.ts @@ -0,0 +1,7 @@ +import { Sceanario } from '../../types'; + +export const data: Sceanario[] = [ + { + output: ["////", "/*** /// */"], + }, +]; diff --git a/test/scenarios/comments/template.jt b/test/scenarios/comments/template.jt new file mode 100644 index 0000000..ed2cf85 --- /dev/null +++ b/test/scenarios/comments/template.jt @@ -0,0 +1,6 @@ +// line comment +/** + //////////////// + * block comment + */ +["////", "/*** /// */"] \ No newline at end of file