上下文相关的标记化是否需要词汇语法中的多个目标符号?

2023-12-31

根据ECMAScript 规范 https://tc39.es/ecma262/#sec-ecmascript-language-lexical-grammar:

词法输入的识别有几种情况 元素对句法语法上下文敏感,即 消耗输入元素。这需要多个目标符号 词汇语法。

两个这样的符号是InputElementDiv and InputElementRegExp.

在 ECMAScript 中,含义/取决于它出现的上下文。根据上下文,/可以是除法运算符、正则表达式文字的开头或注释分隔符。词法分析器无法自行区分除法运算符和正则表达式文字,因此它必须依赖于解析器的上下文信息。

我想了解为什么这需要在词汇语法中使用多个目标符号。我对语言设计了解不多,所以我不知道这是否是由于语法的某些正式要求或只是惯例。

问题

  • 为什么不只使用单个目标符号,如下所示:
InputElement ::
     [...]
     DivPunctuator
     RegularExpressionLiteral
     [...]

并让解析器告诉词法分析器使用哪个产生式(DivPunctuator vs RegExLiteral),而不是使用哪个目标符号 (InputElementDiv vs InputElementRegExp)?

  • 还有哪些其他语言在词汇语法中使用多个目标符号?

  • 我们如何对 ECMAScript 词法语法进行分类?从 CSG 的正式定义的意义上来说,它不是上下文相关的(即,其产生式的 LHS 不被终结符和非终结符的上下文包围)。


在该术语的形式语言定义中,说词汇产生“对消耗输入元素的句法语法上下文敏感”并不意味着语法对上下文敏感。事实上,在几乎所有重要的语法中都存在“对句法语法上下文敏感”的产生式。这是解析的本质:语法上下文有效地提供了一组潜在的可扩展非终结符,并且这些非终结符在不同的语法上下文中会有所不同,这意味着,例如,在大多数语言中,无法在需要表达式的地方输入语句(尽管通常情况下,表达式是语句的表现形式之一)。

然而,差异并不涉及不同的扩展相同的非终结符。 “上下文无关”语言所要求的是,非终结符的可能派生集合是相同的集合,无论该非终结符出现在何处。因此上下文可以提供不同的非终结符选择,但是每个非终结符都可以在不考虑其上下文的情况下进行扩展。这就是语法脱离上下文的意义。

正如您所注意到的,上下文敏感性通常是通过左侧带有模式而不是单个非终结符的语法在语法中抽象出来的。在最初的定义中,上下文——除了要扩展的非终结符之外的所有内容——需要不受影响地通过产生式;只能扩展一个非终结符,但可能的扩展取决于上下文,如产生式所示。上面隐含的是,有些语法可以用 BNF 编写,但它们甚至不符合上下文敏感规则(或其他等效规则)。所以它不是一个二元除法,无论是上下文无关的还是上下文相关的。语法有可能两者都不是(并且,由于空上下文仍然是上下文,因此任何上下文无关语法也是上下文相关的)。最重要的是,当数学家说话时,他们使用语言的方式有时是意想不到的。但它总是有一个明确的基本定义。

在形式语言理论中,不存在词汇和句法产生式;只是作品。如果词汇产生式和句法产生式都不受上下文影响,那么整个语法就不受上下文影响。然而,从实际的角度来看,由于多种原因,组合语法更难解析,我不打算在这里讨论。事实证明,通过词法解析器和句法解析器的划分,编写语言的语法并解析它们要容易一些。

在经典模型中,词法分析是完成的first,这样解析器就不会看到单个字符。相反,句法分析是通过“词汇标记”的“字母表”(在非常扩展的意义上)完成的。这非常方便——例如,这意味着词法分析可以简单地删除空格和注释,这极大地简化了句法语法的编写。但它也降低了通用性,正是因为语法解析器无法“指导”词法分析器做任何事情。在语法分析器意识到它的需求之前,词法分析器已经完成了它要做的事情。

如果解析器能够指导词法分析器,它会以与指导自身相同的方式进行操作。在某些产品中,令牌非终结符将包括InputElementDiv在其他作品中InputElementRegExp将是可接受的非终结符。正如我所指出的,这不是上下文敏感——这只是上下文无关语法的正常功能——但它确实需要修改程序的组织,以允许词法分析器考虑解析器的目标。这通常被(实践者,而不是理论家)称为“词汇反馈”,有时也被称为价值中立程度较低的术语;有时它被认为是语言设计中的一个弱点,因为违反了整齐隔离的词法分析器/解析器架构。 C++ 是一个相当激烈的例子,确实有些 C++ 程序也很难被人类解析,这是某种迹象。但 ECMAScript 并没有真正遇到这个问题;人类通常无需付出任何明显的智力努力就能区分除法运算符和正则表达式分隔符。而且,虽然实现 ECMAScript 解析器所需的词汇反馈确实使架构变得不太整洁,但这实际上也不是一项困难的任务。

无论如何,词法语法中的“目标符号”只是 ECMAScript 参考文献的作者决定使用的一个短语。这些“目标符号”只是普通的词法非终结符,就像任何其他产生式一样,因此说存在“多个目标符号”和说“解析器指示词法分析器使用不同的产生式”之间没有区别,我希望能解决您提出的问题。

Notes

  1. 两种语境中的词汇差异不仅仅如此/有不同的意义。如果仅此而已,就根本不需要词汇反馈了。问题在于标记化本身发生了变化。如果运算符是可能的,那么/= in

    a /=4/gi;
    

    是单个标记(复合赋值运算符),并且gi是单个标识符标记。但是,如果此时正则表达式文字是可能的(但事实并非如此,因为正则表达式文字不能跟随标识符),那么/=将是单独的令牌,因此g and i.

  2. 一些程序员更喜欢从一组产生式构建的解析器(但不是编写此内容的人:-));它们通常被称为“无扫描器解析器”。在 ECMAScript 的无扫描器解析器中,不会有词法反馈,因为没有单独的词法分析。

  3. 形式语言理论的理论纯粹性与编写现实编程语言的工作解析器的实际细节之间确实存在差距。理论模型确实很有用,如果不了解它们,就很难编写解析器。但很少有解析器严格遵守该模型,这没关系。同样,那些通俗地称为“regular从正式语言意义上来说,“表达式”根本不是正则表达式;一些“正则表达式”运算符甚至不是上下文无关的(反向引用)。因此,假设某些理论结果(“正则表达式”)是一个巨大的错误表达式可以在线性时间和常数空间中识别”)实际上对于“正则表达式”库来说也是如此。我不认为解析理论是计算机科学中表现出这种二分法的唯一分支。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

上下文相关的标记化是否需要词汇语法中的多个目标符号? 的相关文章

  • 在哪里存储 Java 的 .properties 文件?

    The Java教程 http download oracle com javase tutorial essential environment properties htmlon using Properties 讨论如何使用 Prop
  • 在 GWT 中,在任何主机页标记上添加事件处理程序

    我想为任何标签添加 MouseOver 事件处理程序 举个例子 我想为旧版 HTML 页面中的每个锚点页面添加事件处理程序 继GWT指南 http code google com webtoolkit doc 1 6 DevGuideUse
  • 没有 OAuth 的 Spring Security JWT

    最近我开始学习如何使用oauth 2 0 jwt配置spring boot 我有一个问题 是否可以使用spring boot security jwt避免oauth 2 0 是的 可以使用JWT无需使用标准化的功能OAuth 2 0 flo
  • 迭代 pandas 数据框的最快方法?

    如何运行数据框并仅返回满足特定条件的行 必须在之前的行和列上测试此条件 例如 1 2 3 4 1 1 1999 4 2 4 5 1 2 1999 5 2 3 3 1 3 1999 5 2 3 8 1 4 1999 6 4 2 6 1 5 1
  • 如何为 Windows toast 注册协议?

    如何注册 Windows toast 协议 样本中来自https blogs msdn microsoft com tiles and toasts 2015 07 02 adaptive and interactive toast not
  • 使用 crypt() 加密

    我目前正在做一个非常安全的登录系统 但我是 crypt 函数的新手 需要一些快速帮助 我在注册过程中使用 crypt 加密密码字符串并将其保存到数据库中 但是 我如何在登录过程中解密密钥 或者我应该怎么做 或者是否可以对提交的密码字符串进行
  • 带重定向标准流的 C# + telnet 进程立即退出

    我正在尝试用 C 做一个 脚本化 telnet 项目 有点类似于Tcl期望 http expect nist gov 我需要为其启动 telnet 进程并重定向 和处理 其 stdin stdout 流 问题是 生成的 telnet 进程在
  • Scrapy Spider不存储状态(持久状态)

    您好 有一个基本的蜘蛛 可以运行以获取给定域上的所有链接 我想确保它保持其状态 以便它可以从离开的位置恢复 我已按照给定的网址进行操作http doc scrapy org en latest topics jobs html http d
  • 在 Android 中使用 iText 将图像添加到特定位置

    我想使用 Android 中的 iText 将图像添加到 PDF 文件中的特定位置 这是一个可填写的表单 我添加了作为图像占位符的文本框 我想要做的就是像这样获取该文本框和图像 public class FormFill public st
  • Googletest:如何异步运行测试?

    考虑到一个包含数千个测试的大型项目 其中一些测试需要几分钟才能完成 如果按顺序执行 整套测试需要一个多小时才能完成 通过并行执行测试可以减少测试时间 据我所知 没有办法直接从 googletest mock 做到这一点 就像 async选项
  • NGinx $proxy_add_x_forwarded_for 和 real_ip_header

    我在 NGinx 下有一个 web 应用程序和另一个前端负载均衡器 如下所示 x x x x IP 地址 客户端 a a a a gt LB b b b b gt NGX c c c c gt WEBAPP d d d d 这是我的 NGi
  • Typescript 函数接口重载

    我有以下代码 interface MySecondInterface a type A interface MyInterface val1 string val2 string MySecondInterface a
  • 实例化 Microsoft.Office.Interop.Excel.Application 对象时出现错误:800700c1

    实例化 Microsoft Office Interop Excel Application 以从 winforms 应用程序生成 Excel 时 出现以下错误 这之前是有效的 但突然间它停止工作了 尽管代码和 Excel 版本没有变化 我
  • 带显示块的SPAN

    和默认有什么区别 div 元素和默认值 span 元素与display block HTML 元素的有效性和语义存在差异 否则它们是相同的 div and span两者都被定义为通用容器 在 HTML 方面没有更深层次的含义 一个默认为块显
  • 使用 Crypto++ 获取 ECDSA 签名

    我必须使用 Crypto 在变量中获取 ECDSA 签名 我在启动 SignMessage 后尝试获取它 但签名为空 我怎样才能得到它 你看过 Crypto wiki 吗 上面有很多东西椭圆曲线数字签名算法 http www cryptop
  • 从 Azure 应用服务连接到 MongoDB Atlas 集群

    我在 Azure 上有一个 Web 应用程序 它连接到 Atlas cloud mongodb com 上托管的 MongoDB 集群 我想使用 Atlas 这样我就不必关心 MongoDb 配置 问题是我的集群连接超时 我必须在我的 mo
  • 匿名结构体作为返回类型

    下面的代码编译得很好VC 19 00 23506 http rextester com GMUP11493 标志 Wall WX Za 与VC 19 10 25109 0 标志 Wall WX Za permissive 这可以在以下位置检
  • 使用泛型全面实现特征

    我正在通过实现矩阵数学来练习 Rust 但遇到了一些障碍 我定义了我认为与矩阵相关的特征 trait Matrix
  • 错误:无效使用不完整类型“类 Move”/未定义对 Move::NONE 的引用

    拜托 我不知道为什么这个简单的代码被拒绝 它给了我 2 个编译错误 请帮帮我 I use 代码 块 20 03 我的编译器是GNU GCC 移动 hpp class Move public Move Move int int public
  • 当ScrollView滚动到底部时加载更多数据

    我有一个带有动态加载内容的滚动视图 有时可能会有很多内容 所以我想在用户滚动到底部时加载更多内容 我搜索了合适的方法 发现了两种 onScrollChanged and getScrollY 但我不知道如何将它用于我的目的 请给我一些建议

随机推荐