html编译器,初识编译原理最佳实践!

通过最简单的html编译成json对象

了解词法分析和语法分析,对编译原理有初步认识

理论性的东西太多还不如实践一下

代码

跪求star

 

const html =
    `<node>
        hello
        <a>这是一个a标签
        </a>
     </node>`

// 任务:将html String转化为AST 抽象语法树 虚拟DOM 对象数组
const tokens = tokenizer(html)
console.log('tokens:', tokens)

const ast = parser(tokens)
console.log('ast:', ast)

/**词法分析*/
function tokenizer(input) {
    // 分词单元数组
    let tokens = []
    // 指针
    let index = 0

    while (index < input.length) {
        let char = input[index]

        if (char === '<') {
            // 这是个标签
            // 跳过<
            char = input[++index]
            let type
            if (char !== '/') {
                // 这是个标签头
                type = 'tagStart'
            } else {
                // 这是个标签尾
                // 跳过/
                char = input[++index]
                type = 'tagEnd'
            }
            // 提取标签名字
            let value = ''
            while (char !== '>') {
                value += char
                char = input[++index]
            }
            // 添加一个token
            tokens.push({
                type,
                value
            })
            // 跳过>
            index++
        } else {
            // 这是个文本
            let value = ''
            while (char && char !== '<') {
                value += char
                char = input[++index]
            }
            value = value.trim()
            if (value) {
                tokens.push({
                    type: "text",
                    value
                })
            }
        }
    }

    return tokens
}

/**语法分析*/
function parser(tokens) {
    // 抽象语法树 Abstract Syntax Tree
    let ast = []
    let index = 0

    function walk() {
        let token = tokens[index]

        let node
        if (token.type === 'tagStart') {
            // 标签
            let tagName = token.value
            node = {
                type: 'tag',
                value: {
                    name: tagName,
                    children: []
                }
            }
            // 解析子元素
            // 跳过左标签
            token = tokens[++index]
            while (token && !(token.type === 'tagEnd' && token.value === tagName)) {
                node.value.children.push(walk())
                token = tokens[index]
            }
        } else {
            // 文本
            node = {
                type: 'text',
                value: token.value
            }
        }

        index++
        return node
    }

    while (index < tokens.length) {
        ast.push(walk())
    }

    return ast
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值