代码之家  ›  专栏  ›  技术社区  ›  Magnus

ECMAScript中语法生成规则与解析的关系

  •  0
  • Magnus  · 技术社区  · 6 年前

    正如维基百科上关于 Parsing ,该过程分为三个阶段:

    1. Lexical analysis
    2. 语法分析:验证令牌流是否形成有效的脚本/模块,并创建解析树
    3. 语义分析:令牌的附加验证(在创建解析树之后发生?)

    除了上面第(3)阶段的小混乱,我想验证我对过程的理解是否正确 ECMAScript .

    那么,下面的流程是否正确?


    词法分析阶段 ( ECMAScript Clause 11

    • 输入:Unicode代码点流&词汇语法中的终端符号
    • 语法应用
      1. 分析每个Unicode码位(字符),每次一个
      2. 然后,通过应用产生式规则,替换可能最长的非终结符号序列
    • 目标符号是输入元素(又名。标记),用于语法分析阶段(下一阶段)
    • ECMAScript词汇语法中存在多个“目标符号”(英文) spec states which to pick )

    • 输入:标记流<——语法中的终端符号
    • 输出:Parse Tree,Script | Module作为根Parse Node<——语法中的非终结符
    • 语法应用
      1. 从输入元素流开始,aka。代币
      2. 这些标记是句法语法中的终端符号
      3. 通过将符号的最大流与适当的生产规则的RHS匹配,然后用该规则的LHS非终结符替换流,应用生产规则。
      4. 直到只剩下“目标符号”为止
    • ECMAScript:如果我们可以替换所有终端符号(令牌),以单个“目标符号”(Script | Module)结尾,那么程序是有效的
    1 回复  |  直到 6 年前
        1
  •  4
  •   rici    6 年前

    句法分析不遵循“最大MunCH”规则(选择最长匹配前缀)。事实上,据我所知,ECMA-262并没有指定解析算法,但提供了一个明确的上下文无关语法,可以对其进行解析,例如使用自底向上(LR(k))解析器,除了一些自动分号插入的问题和对跨换行(不是语法标记)的生成的一些限制之外。

    但是,如中所述 §5.1.4 ,语法实际上识别语言的超集;附加限制以补充语法的形式提供。

    一个澄清:与多个上下文相关的词汇目标符号相关的复杂性使得第一次将输入划分为词条很困难,并且仅将词素组合成解析树。在每一点上都不可能知道正确的词汇目标符号,而不需要至少部分解析,因此很方便地插入句法和词汇分析。实际的解析算法从左到右进行操作,基本上按输入顺序处理词条,因此有可能对需求进行词法分析,只有当解析器需要更多的输入才能继续时才找到一个词位。

    但除此之外,你概述的整体结构是正确的。在词法解析中,终端(字符)的最长前缀被聚合成非终端来创建一个LIVEE(根据需要复杂的词汇目标规则);在句法分析中,终端(lexem)聚合为非终端,生成对应于两个语法目标符号之一的单个解析树。

    就像现实世界中的语言一样,现实并没有那么干净。除了解析器需要指示哪些词汇目标是必需的之外,还有新行规则和自动分号插入,它们都跨越了词汇和句法分析之间的界限。


    “终端”和“非终端”这两个词的用法可能会有点混乱,但我(和ECMA标准)在上下文无关语法中使用它们的标准意义。

    上下文无关语法由产品组成,每个产品的形式如下:

    N ⇒ S …

    N 是一个 符号和 S

    标准句法分析模型将句法分析分为词汇和句法两个层次。原始输入是一个字符序列;词法分析将其转换成一个序列的词条,这是句法分析的输入。

    标准的上下文无关语法有一个目标符号,它是由语法定义的非终结符之一。如果整个输入可以减少到这个非终端,那么解析就成功了。

    使用语义属性扩充符号也很有用;这些属性不会影响解析,但在解析完成后它们会很有用。特别是,解析树是通过将树节点作为属性附加到解析期间从生产创建的每个非终端来构建的,因此,解析的最终结果不是这样的非终端符号(在解析开始之前是已知的),而是附加到非终端的特定实例的语义属性,而每个点的词法扫描的结果是非终结符号及其相关的语义属性;语义属性将是关联的输入序列,或这些字符的某些函数。

    在任何情况下,两级解析都包括将词汇级的输出非终结点作为句法级的终端。