解析的哪一部分应该由词法分析器完成?

时间:2017-09-13 12:46:40

标签: parsing lexical-analysis

在解析期间/之前是否存在对词汇分析(词法分析)的目的或明确的最佳使用方法的正式定义?

我知道词法分析器的目的是将字符流转换为标记流,但是在某些(无上下文)语言中,“令牌”的预期概念仍然可能依赖于它在没有完全解析的情况下,上下文和“令牌”很难识别?

使用词法分析器将每个输入字符转换为令牌并让解析器完成其余工作似乎没有明显的错误。但是,有一个词法分析器可以区分,例如,在“一元减号”和通常的二进制减号之间,而不是将它留给解析器吗?

在决定词法分析器应该做什么以及解析器应该留下什么时,是否有任何准确的规则可以遵循?

1 个答案:

答案 0 :(得分:1)

  

是否存在[词法分析器]目的的正式定义?

没有。词法分析器是实际编程世界的一部分,正式模型是有用的但不是确定的。当然,一个声称做某事的程序应该做那件事,但“词法分析我的编程语言”并不是一个足够精确的要求声明。

  

......或明确的最佳使用方法

如上所述,词法分析器应该按照它的意图去做。它也不应该尝试做任何其他事情。应避免代码重复。理想情况下,代码应该是可验证的。

这些最佳实践激发了成熟且文档良好的扫描程序框架的使用,其输入语言兼作被分析的词法语法的描述。但是,基于特定编程语言特性的实际考虑通常会导致偏离这种理想。

  

使用词法分析器将每个输入字符转换为令牌似乎没有明显的错误......

在这种情况下,词法分析器将是多余的;解析器可以简单地使用输入流。这被称为“无扫描器解析”,它有它的拥护者。我不是其中之一,所以我不会讨论利弊。如果您有兴趣,可以从Wikipedia article开始并按照其链接进行操作。如果此样式适合您的问题域,请选择它。

  

不可能在某些(无上下文)语言中出现“令牌”的预期概念仍然取决于上下文吗?

不确定。在EcmaScript正则表达式“literals”中可以找到一个经典示例,需要使用完全不同的扫描程序进行词法分析。 EcmaScript 6还定义了字符串模板文字,这需要单独的扫描环境。这可以激发无扫描器处理,但也可以使用具有词法反馈的LR(1)解析器来实现,其中特定标记非终端的减少动作导致切换到不同的扫描器。

  

但是有一个词法分析器可以区分,例如,在“一元减号”和通常的二进制减号之间,而不是将它留给解析器吗?

如果它有效,任何事情都是可以接受的,但是这个特殊的例子让我觉得不是特别有用。 LR(甚至LL)表达式解析器不需要来自词法扫描器的任何辅助来显示减号的上下文。 (Naïve运算符优先级语法确实需要这样的帮助,但是更仔细考虑的op-prec架构不会。但是,LALR解析器生成器的存在或多或少地消除了对op-prec解析器的需求。)

一般来说,为了让词法分析器能够识别语法上下文,它需要复制由解析器完成的分析,从而违反了代码开发的基本最佳实践之一(“don不重复功能“)。尽管如此,它偶尔会有用,所以我不会提倡绝对禁令。例如,许多针对yacc / bison的生成规则的解析器通过特别标记ID标记(后面紧跟冒号)来弥补幼稚语法是LALR(2)这一事实。

另一个例子,再次从EcmaScript中提取,是对自动分号插入(ASI)的有效处理,可以使用查找表来完成,该查找表的键是连续令牌的2元组。类似地,Python的空白感知语法可以通过词法扫描程序的帮助来方便地处理,词法扫描程序必须能够理解缩进是否相关(例如,不在括号或大括号内)。