Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

02 生成语法树 #3

Open
xwjie opened this issue Jan 5, 2018 · 1 comment
Open

02 生成语法树 #3

xwjie opened this issue Jan 5, 2018 · 1 comment

Comments

@xwjie
Copy link
Owner

xwjie commented Jan 5, 2018

采用了 jQuery 作者 John Resig 的 HTML Parser ,(VUE也是用了这个),然后生成语法树,非常少的代码,语法树的结构参考了VUE的,目前只用了几个字段,不够后面再加。

生成语法树就是生成一颗树,比较麻烦的是父节点的处理,这里用一个栈来存放(就是一个数组,采用push和pop方法),代码非常简单,自己写的话10行左右就生成了语法树。

type1 表示dom节点,2表示表达式(未实现)3表示文本/注释,

/* @flow */
import { log } from '../util'
import { HTMLParser, HTMLtoXML, HTMLtoDOM } from './htmlparser'

//D:\OutPut\VUE\vue\src\compiler\parser\index.js
function html2ast(templte: string, data: Object): ?ASTElement {
    let root: ?ASTElement;
    let parent: ASTElement;
    let parentStack = [];

    HTMLParser(templte, {
        start: function (tag, attrs, unary) {
            //
            if (false === unary && parent) {
                parentStack.push(parent);
            }

            let e = createASTElement(tag, attrs, parent);

            if (!root) {
                root = e;
            }

            if(false === unary){
                parent = e;
            }
        },
        end: function (tag) {
            parent = parentStack.pop();
        },
        chars: function (text) {
            createTextlement(text, parent);
        },
        comment: function (text) {
            createCommentlement(text, parent);
        }
    });

    log('htmlparser ast', root);
    log('htmlparser parentStack', parentStack);
    return root;
}

function createASTElement(
    tag: string,
    attrs: Array<Attr>,
    parent: ?ASTElement
): ASTElement {
    let e = {
        type: 1,
        tag,
        //attrsList: attrs,
        attrsMap: makeAttrsMap(attrs),
        //parent,
        children: []
    }

    if (parent) {
        parent.children.push(e);
    }

    return e;
}

function createTextlement(
    text: string,
    parent: ASTElement
): ASTText {
    let e = {
        type: 3,
        text,
        //parent
    }

    parent.children.push(e);

    return e;
}

function createCommentlement(
    text: string,
    parent: ASTElement
): ASTText {
    let e = {
        type: 3,
        text,
        isComment: true,
        //parent
    }

    parent.children.push(e);

    return e;
}

function makeAttrsMap(attrs: Array<Object>): Object {
    const map = {}
    for (let i = 0, l = attrs.length; i < l; i++) {
        map[attrs[i].name] = attrs[i].value
    }
    return map
}

export { html2ast }
@fhyoga
Copy link

fhyoga commented Feb 8, 2018

image

换行和空格的处理,有什么思路吗

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants