function readTagExp(parser) {
  let inSingleQuotes = false;
  let inDoubleQuotes = false;
  let i;
  let EOE = false;

  for (i = 0; parser.source.canRead(i); i++) {
    const char = parser.source.readChAt(i);

    if (char === "'" && !inDoubleQuotes) {
      inSingleQuotes = !inSingleQuotes;
    } else if (char === '"' && !inSingleQuotes) {
      inDoubleQuotes = !inDoubleQuotes;
    } else if (char === '>' && !inSingleQuotes && !inDoubleQuotes) {
      // If not inside quotes, stop reading at '>'
      EOE = true;
      break;
    }

  }
  if(inSingleQuotes || inDoubleQuotes){
    throw new Error("Invalid attribute expression. Quote is not properly closed");
  }else if(!EOE) throw new Error("Unexpected closing of source. Waiting for '>'");


  const exp = parser.source.readStr(i);
  parser.source.updateBufferBoundary(i + 1);
  return buildTagExpObj(exp, parser)
}
Read XML tag and build attributes map
This function can be used to read normal tag, pi tag.
This function can't be used to read comment, CDATA, DOCTYPE.
Eg <tag attr = ' some"' attr= ">" bool>
@param {string} xmlDoc
@param {number} startIndex starting index
@returns tag expression includes tag name & attribute string