zoukankan      html  css  js  c++  java
  • [译]Razor内幕之解析

    ASPX语法比较简单,所以ASPX解析器几乎完全是通过正则表达式来实现的。Razor解析器与ASPX解析器之间有很大不同,它实际上分为三个独立的组件:

    1)理解基础HTML语法的标记解析器;

    2)理解基础C#或者VB语法的代码解析器;

    3)理解标记和代码如何混合的中央控制器

    所以Razor解析器有三个参与者:代码解析器,标记解析器,代码解析器。三个组件相互配合,协同工作完成对Razor文档的解析。Razor解析器有三种状态,分别是:解析标记文档、解析标记块,解析代码块,任何情况下解析器都处在以上三种状态中的一种状态上。前两种状态由标记解析器来处理,最后一种状态由代码解析器处理。

    在此我们依然使用上次的例子来说明使用这些组件解析Razor文档的过程。

    文件内容如下:

    <ul>  

        @foreach(var p in Model.Products) {  

        <li>@p.Name ($@p.Price)</li>  

        }  

    </ul>  

    我们从最上面开始解析过程。当第一次调用核心解析器的时候,它会调用标记解析器来解析标记文档。此时,解析器处在解析标记文档状态,在这种状态下,它会一直向前扫描,直到找到下一个"@"字符,除此之外它不关心任何标记或者其它HTML相关的内容。当遇到一个"@"字符的时候,它会通过查看"@"字符前后的内容,并据此判断是切换到代码状态呢还是这仅仅是一个email地址。这是默认的处理方式,但是有些特殊情况会强制解析器切换到代码解析状态。本例中,当解析到"@"字符的时候,会发现该字符的前面是空格,据此判定这并不是一个合法的email地址,所以切换到代码解析状态。

    标记解析器接着调用代码解析器,让其来解析代码块。在Razor中块为单独的一段代码或者是有明确开始结束字符序列的标记,因而此处的"foreach"声明是代码块,它以字符"f"开始,以字符"}"结束。代码解析器非常清楚C#语法,他会跟踪C#指令,当遇到"<li>"字符序列的时候,它知道此处应该是C#指令的开始,但C#并不支持这样的指令,因而代码解析器会再次调用标记解析器来解析接下来的HTML代码块。这样在代码和标记解析器之间创建一种从标记解析开始,进入代码解析,然后再进入标记解析….的递归过程。到目前为止,解析器内的调用栈应该类似于以下结构(省略了一些帮助方法):

    HtmlMarkupParser.ParseDocument()

    CSharpCodeParser.ParseBlock()

    HtmlMarkupParser.ParseBlock()

    我们可以从中看出ASPX和Razor的区别:在ASPX文件中,代码和标记可以看作是两个并行的流,我们写一些标记然后跳过去写一些代码,再跳回来写标记,如此进行;而Razor文件更像是一棵树,我们写一些标记,然后在标记里面写一些代码,再在代码中嵌入标记….。

    所以我们仅需要调用标记解析器去解析"<li>"和"</li>"之间的标记块,在没有到达"</li>"之前解析器认为标记块还没结束,哪怕在标记之间有"}"字符都不会打断"foreach"声明。

    当解析"<li>"的时候,标记解析器发现了"@"字符,因而代码解析器会被调用,此时栈结构变成:

    HtmlMarkupParser.ParseDocument()

    CSharpCodeParser.ParseBlock()

    HtmlMarkupParser.ParseBlock()

    CSharpCodeParser.ParseBlock()

    对于这些代码块如何终止的具体信息以后再做介绍,但是最终我们会完成这些代码块的解析并且回到"<li>"块中,在"</li>"之后又回到了"foreach"块中,最后"}"字符结束了"foreach"块,重新回到栈的顶端:标记文档。之后因为没发现新的"@"字符,文档解析器将一直解析到文件的结尾。

    查看下一篇:Razor内幕之表达式

    查看英文原文,点击此处

    注:如果发现有翻译不恰当或者疏漏的地方请反馈给我,我会及时更正,谢谢!

  • 相关阅读:
    nmp部署(Nginx Mariadb Php-fpm)
    通过能别的主机连接yum库
    基于ftp服务实现yum网络共享
    nginx做代理部署WordPress
    练习题
    php-fpm包的安装与配置
    安装mariadb并修改配置文件
    mysql的简单操作
    telnet IP:ERROR
    加固mysql服务器
  • 原文地址:https://www.cnblogs.com/jingtao/p/1802440.html
Copyright © 2011-2022 走看看