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内幕之表达式

    查看英文原文,点击此处

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

  • 相关阅读:
    广域网(ppp协议、HDLC协议)
    0120. Triangle (M)
    0589. N-ary Tree Preorder Traversal (E)
    0377. Combination Sum IV (M)
    1074. Number of Submatrices That Sum to Target (H)
    1209. Remove All Adjacent Duplicates in String II (M)
    0509. Fibonacci Number (E)
    0086. Partition List (M)
    0667. Beautiful Arrangement II (M)
    1302. Deepest Leaves Sum (M)
  • 原文地址:https://www.cnblogs.com/jingtao/p/1802440.html
Copyright © 2011-2022 走看看