// lexer.mjs import { token } from './token.mjs'; export class Lexer { constructor(string) { this.string = string; this.pos = 0; } advance() { return this.string[this.pos++]; } lookAhead() { return this.string[this.pos]; } trimQuotes(str) { return str.replace(/^['"]|['"]$/g, ''); // Remove surrounding quotes } lex() { let text = ''; while (true) { let t = this.advance(); let tokenResult = ''; // Renamed to avoid conflict with outer token variable switch (t) { case '<': if (this.lookAhead() === '/') { tokenResult = this.handleEndTag(); } else { tokenResult = this.handleStartTag(); } break; case '\n': break; case ' ': if (text !== '') { text += t; } else { break; } break; case undefined: if (this.pos >= this.string.length) { tokenResult = [token.eof, 'eof', []]; break; } break; default: text += t; tokenResult = this.handleTextTag(text); break; } this.string = this.string.slice(this.pos); this.pos = 0; if (tokenResult !== '') { return tokenResult; } } } handleStartTag() { let idx = this.string.indexOf('>'); if (idx === -1) { throw new Error('parse err! miss match ' + '>'); } let str = this.string.slice(this.pos, idx); let s = ''; if (str.includes(' ')) { s = str.split(' ')[0]; // Fixed splitting logic } else { s = str; } let type = s.slice(1); this.pos += type.length; let props = this.handlePropTag(); this.advance(); return [token.startTag, type, props]; } handlePropTag() { let idx = this.string.indexOf('>'); if (idx == -1) { throw new Error('parse err! miss match ' + '>'); } let string = this.string.slice(this.pos, idx); let pm = []; if (string.trim() != '') { // Checking if string is not empty let props = string.split(' '); pm = props.filter((prop) => { return prop != ''; }).map((prop) => { let kv = prop.split('='); let o = {}; // Ensure kv[1] exists before calling trimQuotes if (kv[1]) { o[kv[0]] = this.trimQuotes(kv[1]); } else { o[kv[0]] = ''; // Or assign a default value } return o; }); this.pos += string.length; } return pm; } handleEndTag() { this.advance(); let idx = this.string.indexOf('>'); let type = this.string.slice(this.pos, idx); this.pos += type.length; if (this.advance() !== '>') { throw new Error('parse err! miss match ' + '>'); } return [token.endTag, type, []]; } handleTextTag(text) { let t = text.trim(); if (this.lookAhead() === '<') { return [token.text, t, []]; } else { return ''; } } }