【问题标题】:Tokenizing f string in lexical analysis phase of Python languagePython语言词法分析阶段对f字符串进行分词
【发布时间】:2021-08-30 06:20:34
【问题描述】:

我最近通过 Aho 的龙书了解了编译器。据我了解,语言首先通过词法分析进行标记化。对于 C/C++ 和 Java 等语言,这个过程似乎很简单。但是对于 Python,特别是 Python3,f 字符串应该如何表现?我不认为仅通过正则表达式或使用 lex 的词法分析可以标记化字符串,如 f"1+2 = {int(f'{1}') + int(f'{2}')}" 。我不认为正则表达式和状态可以识别{} 中的部分不是字符串字符。我搜索了一下,发现这个语法适用于 python3 使用 antlr https://github.com/antlr/grammars-v4/blob/master/python/python3-py/Python3.g4 。但我不相信它会标记 f 字符串。所以我的问题是如何处理 f 字符串?是否可以使用 lex/flex 处理它们?还是在其他阶段处理?或者标准解析器技术不能与它们一起使用?

【问题讨论】:

    标签: parsing lexical-analysis f-string


    【解决方案1】:

    Python 的格式化字符串文字旨在使解析器的工作更轻松,但代价是一些限制,有时会给用户带来不便。特别是,格式化的字符串文字总是在第一次出现打开文字的引号时终止,因为不允许在字符串文字的任何地方使用该引号符号(或序列),包括嵌入的表达式。此外,文字中不允许使用反斜杠,因此您也不能在反斜杠转义的引号符号中偷偷插入。

    所以词法分析很简单,与任何其他字符串文字没有太大区别。 (主要区别在于没有反斜杠转义。)

    当然,一旦识别出文字标记,最终将需要递归解析它,此时将需要基于词法分析器状态的策略来处理嵌入式表达式。

    大多数其他具有类似功能的语言——Perl、Javascript、Posix shell 等等——确实允许任意嵌套表达式,包括包含定界引号的表达式。对此类语言进行词法分析的一个简单策略是使用词法状态和一堆状态来跟踪递归嵌入。这可能有点混乱,而且肯定与 Aho 等人概述的简单模型有偏差,但并不是特别复杂。

    通过构建递归解析器/扫描器可以实现更简洁的(在我看来)解决方案,但这需要重构词法扫描器,以便将词法分析与输入管理分开。 (f)lex 和 Antlr 架构都没有促进这一点,尽管可以将它们弯曲成这种形式。

    顺便说一句,我没有尝试您链接到的 Antlr 解析器,但在我看来它会标记格式化的字符串文字。但是,它错误地允许反斜杠转义,因此它会接受一些会被标准 Python 拒绝的文字。我认为它不包含在识别文字后分解文字所需的代码。

    【讨论】:

    • 因此,f 字符串中的表达式应该稍后递归解析,否则词法分析器需要成为基于堆栈的。谢谢,这清除了它。我其实不知道斜线规则,所以我在 antlr 语法中没有注意到。
    猜你喜欢
    • 2017-05-16
    • 1970-01-01
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    • 2012-05-30
    • 1970-01-01
    • 2011-02-25
    相关资源
    最近更新 更多