코드스피츠 74 3회차


const textNode = (text, target) =>{
     if(text.length){
         target.push({type:'TEXT', text});
         return '';
     }
};

const parser = input =>{
    const result ={tag:{type:'ROOT', children:[]}, stacks=[]};
    let cursor = 0, stack = result;
    
    do{
        let text = '';
            while (cursor < input.length){
                const char = input[cursor++];
                if(char === '<'){
                    text = textNode(text, stack.tag.children);
                    if(input[cursor++] != '/'){
                        // 활당 연산자를 통해서 변수를 줄임
                        let name = input.substr(cursor -1, cursor = input.indexOf('>', cursor));
                        const isClose = input[cursor] === '/';
                        if(isClose){
                            name = name.substr(0, name.length - 1);
                        }
                        const tag = {name, type:'NODE', children: isClose ? null:[]};
                        cursor++;
                        stack.tag.children.push(tag);
                        if(!isClose){
                            stacks.push({tag, back: stack});
                            break;
                        }
                    }
                }else{
                    text += char;
                }
            }
    }while (stack = stacks.pop())
    
    return result;
};

함수로 변환


const elementNode = (input, cursor, text, stack, stacks) =>{
   
   const char = input[cursor++];
   let isBreak = false;
   
   if(char === '<'){
       text = textNode(text, stack.tag.children);
       if(input[cursor++] != '/'){
           // 활당 연산자를 통해서 변수를 줄임
           let name = input.substr(cursor -1, cursor = input.indexOf('>', cursor));
           const isClose = input[cursor] === '/';
           if(isClose){
               name = name.substr(0, name.length - 1);
           }
           const tag = {name, type:'NODE', children: isClose ? null:[]};
           cursor++;
           stack.tag.children.push(tag);
           if(!isClose){
               stacks.push({tag, back: stack});
               isBreak = true;
           }
       }
   }else{
       text += char;
   }
   return {cursor, text, isBreak}
};



const textNode = (text, target) =>{
     if(text.length){
         target.push({type:'TEXT', text});
         return '';
     }
};


const elementNode = (input, cursor, text, stack, stacks) =>{
   
   const char = input[cursor++];
   let isBreak = false;
   
   if(char === '<'){
       text = textNode(text, stack.tag.children);
       if(input[cursor++] != '/'){
           // 활당 연산자를 통해서 변수를 줄임
           let name = input.substr(cursor -1, cursor = input.indexOf('>', cursor));
           const isClose = input[cursor] === '/';
           if(isClose){
               name = name.substr(0, name.length - 1);
           }
           const tag = {name, type:'NODE', children: isClose ? null:[]};
           cursor++;
           stack.tag.children.push(tag);
           if(!isClose){
               stacks.push({tag, back: stack});
               isBreak = true;
           }
       }else if(stack.tag.name == input.substring(cursor, input.indexOf('>',cursor))){
           stack = stack.back;
       }
   }else{
       text += char;
   }
   return {cursor, text, isBreak}
};


const parser = input =>{
    const result ={tag:{type:'ROOT', children:[]}, stacks=[]};
    let cursor = 0, stack = result;
    
    do{
        let text = '';
        while (cursor < input.length){
            const v = elementNode(input, cursor, text, stack, stacks);
            ({cursor, text} = v);
            if(v.isBreak) break;
        }
    }while (stack = stacks.pop())
    
    return result;
};

잘만들자 ㅜㅜ

참조