Table des matières
什么是AST
parse()
parseHTML()
parseStartTag()
handleStartTag()
Maison interface Web js tutoriel Qu'est-ce que l'AST ? Analyse de l'arbre de syntaxe AST dans le code source de Vue

Qu'est-ce que l'AST ? Analyse de l'arbre de syntaxe AST dans le code source de Vue

Aug 02, 2018 am 11:43 AM
vue.js

这篇文章给大家介绍的内容是关于什么是AST?Vue源码中AST语法树的解析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

什么是AST

AST是指抽象语法树(abstract syntax tree),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式。Vue在mount过程中,template会被编译成AST语法树。
然后,经过generate(将AST语法树转化成render function字符串的过程)得到render函数,返回VNode。VNode是Vue的虚拟DOM节点,里面包含标签名、子节点、文本等信息,关于VNode的学习来自:https://blog.csdn.net/qq_3626...

<p>
    请输入:<input><br>
</p>
Copier après la connexion

parse()

  var stack = [];
  var preserveWhitespace = options.preserveWhitespace !== false;
  var root;
  var currentParent;
  var inVPre = false;
  var inPre = false;
  var warned = false;

  function warnOnce (msg){
  }
  function closeElement (element){
  }
  //调用parseHTML,这里对options的内容省略
  parseHTML(template,options);
Copier après la connexion

定义一些变量,root用于存放AST树根节点,currentParent存放当前父元素,stack用来辅助树建立的栈。接着调用parseHTML函数进行转化,传入template和options。
options的结构如下:

Quest-ce que lAST ? Analyse de larbre de syntaxe AST dans le code source de Vue

parseHTML()

parseHTML内容大纲

Quest-ce que lAST ? Analyse de larbre de syntaxe AST dans le code source de Vue

last = html;
    //确认html不是类似<script>,<style>这样的纯文本标签
    if (!lastTag || !isPlainTextElement(lastTag)) {
      var textEnd = html.indexOf(&#39;<&#39;);//判断html字符串是否以<开头
      if (textEnd === 0) {
        // 这里的Comment是Vue定义的正则表达式,判断html是不是<!-- -->注释
        //var comment = /^<!\--/;
        if (comment.test(html)) {
          var commentEnd = html.indexOf(&#39;-->&#39;);

          if (commentEnd >= 0) {
            if (options.shouldKeepComment) {
              options.comment(html.substring(4, commentEnd));
            }
            advance(commentEnd + 3);
            continue
          }
        }
        //判断是否处理向下兼容的注释,类似<![if !IE]>
        //var conditionalComment = /^<!\[/;
        if (conditionalComment.test(html)) {
          var conditionalEnd = html.indexOf(&#39;]>&#39;);

          if (conditionalEnd >= 0) {
            advance(conditionalEnd + 2);
            continue
          }
        }

        //获取<!DOCTYPE开头的标签内容
        // var doctype = /^<!DOCTYPE [^>]+>/i;
        var doctypeMatch = html.match(doctype);
        if (doctypeMatch) {
          advance(doctypeMatch[0].length);
          continue
        }

        //判断此段html是否结束标签
        // var endTag = new RegExp(("^<\\/" + qnameCapture + "[^>]*>"));
        // var qnameCapture = "((?:" + ncname + "\\:)?" + ncname + ")";
        // var ncname = &#39;[a-zA-Z_][\\w\\-\\.]*&#39;;
        var endTagMatch = html.match(endTag);
        if (endTagMatch) {
          var curIndex = index;
          advance(endTagMatch[0].length);
          parseEndTag(endTagMatch[1], curIndex, index);
          continue
        }

        // 匹配开始标签,获取match对象
        var startTagMatch = parseStartTag();
        if (startTagMatch) {
          handleStartTag(startTagMatch);
          if (shouldIgnoreFirstNewline(lastTag, html)) {
            advance(1);
          }
          continue
        }
        var text = (void 0), rest = (void 0), next = (void 0);
      if (textEnd >= 0) {
        rest = html.slice(textEnd);
        while (
          !endTag.test(rest) &&
          !startTagOpen.test(rest) &&
          !comment.test(rest) &&
          !conditionalComment.test(rest)
        ) {
            // 处理文本中的<字符
          next = rest.indexOf(&#39;<&#39;, 1);
          if (next < 0) { break }
          textEnd += next;
          rest = html.slice(textEnd);
        }
        text = html.substring(0, textEnd);
        advance(textEnd);
      }

      if (textEnd < 0) {
        text = html;
        html = &#39;&#39;;
      }

      if (options.chars && text) {
        options.chars(text);
      }
    } else {
      //代码省略
    }

    if (html === last) {
      //代码省略
    }
      }</script>
Copier après la connexion

Quest-ce que lAST ? Analyse de larbre de syntaxe AST dans le code source de Vue

parseHTML使用while循环对传进来的html进行解析。首先获取var textEnd = html.indexOf('如果textEnd为0 说明是标签或者,再用正则匹配是否为注释标签,如果不是,再判断是否为向下兼容放入注释,如(详情见),如果不是,再判断是否已如果不是,再判断当前是否结束标签。var endTagMatch = html.match(endTag); 匹配不到那么就是开始标签,调用parseStartTag()函数解析。

parseStartTag()

  function parseStartTag () {
    var start = html.match(startTagOpen);
    if (start) {
      var match = {
        tagName: start[1],//标签名,本文的例子p
        attrs: [],
        start: index//0
      };//定义match对象
      advance(start[0].length);//index=4,html=" id="test">...
      var end, attr;
      //match对象的attrs
      //index=14
      while (!(end = html.match(startTagClose)) && (attr = html.match(attribute))) {
        advance(attr[0].length);
        match.attrs.push(attr);
      }
      // 在第二次while循环后 end匹配到结束标签 => ['>','']
      if (end) {
        match.unarySlash = end[1];
        advance(end[0].length);
        match.end = index;
        return match
      }
    }
  }
Copier après la connexion

parseStartTag()构建一个match对象,对象里面包含标签名(tagName),标签属性(attrs),右开始标签的位置(end)。本文的例子,程序第一次进入该函数,所以tagName:p,start:0,end:14 match

 function advance (n) {
    index += n;
    html = html.substring(n);
  }
Copier après la connexion

advance函数将局部变量index往后推 并切割字符串。

handleStartTag()

  function handleStartTag (match) {
    var tagName = match.tagName;
    var unarySlash = match.unarySlash;

    if (expectHTML) {
    //段落式元素
      if (lastTag === 'p' && isNonPhrasingTag(tagName)) {
        parseEndTag(lastTag);
      }
      // 可以省略闭合标签
      if (canBeLeftOpenTag$$1(tagName) && lastTag === tagName) {
        parseEndTag(tagName);
      }
    }

    var unary = isUnaryTag$$1(tagName) || !!unarySlash;

    var l = match.attrs.length;
    var attrs = new Array(l);
    //解析html属性值{name:'id',value:'test'}的格式
    for (var i = 0; i <p>在该函数中,对match进行了二次处理,根据标签名、属性生成一个新对象,push到最开始的stack数组中。<br>由于匹配的是起始标签,所以也会以这个标签名结束,此处的lastTag就是p。<br>函数最后调用了parse内部声明的方法start</p><pre class="brush:php;toolbar:false">function start (tag, attrs, unary) {
      //检查命名空间是否是svg或者math
      var ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag);

      // handle IE svg bug
      /* istanbul ignore if */
      if (isIE && ns === 'svg') {
        attrs = guardIESVGBug(attrs);
      }

      //创建element元素,element其实就是{type: 1,
      //tag: "p",
      //attrsList: [{name: "id", value: "test"}]],
      //attrsMap: makeAttrsMap(attrs), //parent:undefined
      //children: []}的一个对象
      var element = createASTElement(tag, attrs, currentParent);
      if (ns) {
        element.ns = ns;
      }
    
      //排除script,style标签
      if (isForbiddenTag(element) && !isServerRendering()) {
        element.forbidden = true;
        "development" !== 'production' && warn$2(
          'Templates should only be responsible for mapping the state to the ' +
          'UI. Avoid placing tags with side-effects in your templates, such as ' +
          "" + ', as they will not be parsed.'
        );
      }

      // apply pre-transforms
      for (var i = 0; i <p>对标签名进行校验,同时对属性进行更细致的处理,如v-pre,v-for,v-if等。最后调用processElement(element, options)对当前的树节点元素进行处理,具体如下:</p><pre class="brush:php;toolbar:false">  processKey(element);
  // 检测是否是空属性节点
  element.plain = !element.key && !element.attrsList.length;
 // 处理:ref或v-bind:ref属性
  processRef(element);
  //处理标签名为slot的情况
  processSlot(element);
  // 处理is或v-bind:is属性
  processComponent(element);
  for (var i = 0; i <p>start()生成element对象,再连接元素的parent和children节点,最后push到栈中,此时栈中第一个元素生成。结构如下:</p><p style="text-align: center;"><span class="img-wrap"><img src="/static/imghw/default1.png" data-src="https://img.php.cn//upload/image/187/717/423/1533181233204676.png" class="lazy" title="1533181233204676.png" alt="Quest-ce que lAST ? Analyse de larbre de syntaxe AST dans le code source de Vue"></span></p><p>接下来开始第二次循环,html变成了 请输入:<input type="text" v-model="message"></p><p>,因此这次解析的是文字:'请输入',具体代码分析在下一次~~~</p><p class="post-topheader custom- pt0">相关文章推荐:</p><p class="post-topheader custom- pt0"><a href="http://www.php.cn/php-weizijiaocheng-256904.html" target="_blank" class="title">使用PHP-Parser生成<span class="course-color">AST</span>抽象语法树</a></p>
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Où trouver la courte de la grue à atomide atomique
1 Il y a quelques semaines By DDD

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Quelle est la différence entre la composantisation et la modularisation dans Vue Quelle est la différence entre la composantisation et la modularisation dans Vue Dec 15, 2022 pm 12:54 PM

La différence entre la modularisation et la modularisation : la modularisation est divisée du point de vue de la logique du code ; elle facilite le développement en couches de code et garantit la cohérence des fonctions de chaque module fonctionnel. La composantisation est planifiée du point de vue de l'interface utilisateur ; la composantisation du frontal facilite la réutilisation des composants de l'interface utilisateur.

Discussion approfondie sur la façon dont vite analyse les fichiers .env Discussion approfondie sur la façon dont vite analyse les fichiers .env Jan 24, 2023 am 05:30 AM

Lorsque nous utilisons le framework Vue pour développer des projets front-end, nous déploierons plusieurs environnements lors du déploiement. Souvent, les noms de domaine d'interface appelés par les environnements de développement, de test et en ligne sont différents. Comment peut-on faire la distinction ? Cela utilise des variables et des modèles d'environnement.

Combat pratique : développer un plug-in dans vscode qui prend en charge les fichiers vue pour accéder aux définitions Combat pratique : développer un plug-in dans vscode qui prend en charge les fichiers vue pour accéder aux définitions Nov 16, 2022 pm 08:43 PM

vscode lui-même prend en charge les composants de fichiers Vue pour accéder aux définitions, mais la prise en charge est très faible. Sous la configuration de vue-cli, nous pouvons écrire de nombreuses utilisations flexibles, ce qui peut améliorer notre efficacité de production. Mais ce sont ces méthodes d'écriture flexibles qui empêchent les fonctions fournies par vscode lui-même de prendre en charge le passage aux définitions de fichiers. Afin d'être compatible avec ces méthodes d'écriture flexibles et d'améliorer l'efficacité du travail, j'ai écrit un plug-in vscode qui prend en charge les fichiers Vue pour accéder aux définitions.

Explication graphique détaillée de la façon d'intégrer l'éditeur de code Ace dans un projet Vue Explication graphique détaillée de la façon d'intégrer l'éditeur de code Ace dans un projet Vue Apr 24, 2023 am 10:52 AM

Ace est un éditeur de code intégrable écrit en JavaScript. Il correspond aux fonctionnalités et aux performances des éditeurs natifs comme Sublime, Vim et TextMate. Il peut être facilement intégré à n’importe quelle page Web et application JavaScript. Ace est maintenu en tant qu'éditeur principal de l'IDE Cloud9 et est le successeur du projet Mozilla Skywriter (Bespin).

Découvrez comment écrire des tests unitaires dans Vue3 Découvrez comment écrire des tests unitaires dans Vue3 Apr 25, 2023 pm 07:41 PM

Vue.js est devenu aujourd'hui un framework très populaire dans le développement front-end. À mesure que Vue.js continue d'évoluer, les tests unitaires deviennent de plus en plus importants. Aujourd'hui, nous allons explorer comment écrire des tests unitaires dans Vue.js 3 et fournir quelques bonnes pratiques ainsi que des problèmes et solutions courants.

Parlons en profondeur de reactive() dans vue3 Parlons en profondeur de reactive() dans vue3 Jan 06, 2023 pm 09:21 PM

Avant-propos : Dans le développement de vue3, réactif fournit une méthode pour implémenter des données réactives. Il s'agit d'une API fréquemment utilisée dans le développement quotidien. Dans cet article, l’auteur explorera son mécanisme de fonctionnement interne.

Une brève analyse de la façon de gérer les exceptions dans les composants dynamiques Vue3 Une brève analyse de la façon de gérer les exceptions dans les composants dynamiques Vue3 Dec 02, 2022 pm 09:11 PM

Comment gérer les exceptions dans les composants dynamiques Vue3 ? L'article suivant parlera des méthodes de gestion des exceptions des composants dynamiques Vue3. J'espère qu'il sera utile à tout le monde !

Analyser le principe de mise en œuvre de l'API de composition de Vue2 Analyser le principe de mise en œuvre de l'API de composition de Vue2 Jan 13, 2023 am 08:30 AM

Depuis la sortie de Vue3, l'API de composition de mots est entrée dans le champ de vision des étudiants qui écrivent Vue. Je pense que tout le monde a toujours entendu à quel point l'API de composition est meilleure que l'API d'options précédente, grâce à la sortie de @. plug-in vue/composition-api, Vue2 Les étudiants peuvent également monter dans le bus. Ensuite, nous utiliserons principalement responsive ref et reactive pour effectuer une analyse approfondie de la façon dont ce plug-in y parvient.

See all articles