3

我正在实现一个自定义(铁)Python 控制台。

一般来说,我需要显示一个>>>提示,但是当一个语句不完整时,我需要将提示更改为...并收集更多行,然后再执行它们。

我如何知道用户输入的一行是否完整,或者我是否需要阅读更多行?

一种简单的方法似乎是检查是否:存在。但我不确定我是否没有错过其他:不存在的情况。

我查看了 IronPython 源代码以了解它是如何做到这一点的,但是涉及到许多步骤,而且我的简单复制未能完全奏效。

4

4 回答 4

4

仅通过查看冒号和括号的代码字符串来尝试猜测是不切实际的。你最终需要实现一半的 Python 解析器才能做到这一点。

标准库代码模块再现了交互式 Python 解释器的行为,我相信 IronPython 使用这个模块来实现其控制台。(CPython 本身并没有在 Python 中实现。)

您感兴趣的行延续逻辑来自codeop.compile_command函数。

这有点骇人听闻。本质上,它尝试compile()使用 obscure 标志来处理给定的代码PyCF_DONT_IMPLY_DEDENT,这意味着它不会假设任何打开的缩进在块的末尾自动关闭。然后它尝试添加换行符(导致显式 DEDENT)再次编译它。如果第二个有效但第一个无效,则您有可能继续,可以在块中输入更多内容。

于 2010-11-12T01:20:21.150 回答
3

repl 循环具有完整的知识和对解析器的访问权限。如果解析器的状态是它期望的不是语句,那么 repl 循环会产生一个.... 在未闭合括号的情况下,下一行的语句将是非法的,因为没有可能包含语句的子表达式。在 a 之后:,下一个预期的标记总是一个缩进,再一次声明总是非法的。这就是为什么总是需要在 repl 循环的缩进块的末尾键入一个空行,因为您必须为语句提供结束的缩进,才能成为下一个预期的生产规则。

于 2010-11-12T00:35:14.387 回答
3

我可以想到几种不同的方法来获得...提示。

  • 开始(或继续)一个块
    • def foo():
  • 未闭合的括号、大括号、方括号(并注意嵌套)
    • x = (
    • x = {
    • x = [
  • 未闭合的三引号字符串
    • x = '''
  • 行尾的反斜杠:
    • x = \
于 2010-11-12T00:20:20.177 回答
1

您是否使用了 a:或 a \(或未闭合的分隔符,如括号或括号)?交互式解释器显示一个....

实际的逻辑可能有点复杂,但这是基本规则。

于 2010-11-12T00:19:13.753 回答