简单的 2++ 2 在Python语言中如何在后台运行?

如果我们在 Python解释器中输入:

>>> 2+++--2
4
>>> 2+++*2
  File "<stdin>", line 1
    2++*2
       ^
SyntaxError: invalid syntax

在这里寻找语法错误时,我注意到这是Python设计人员设计/实现Python的方式。

据说Python是开放源代码,所以我开始对其进行更多的探索。
我已经阅读了许多有关使用cpython实现Python的文章。

因此,这里的Python编译器很容易将这些++*%-标识为运算符。
因为它是使用 C语言编写的。 C使用一些直接汇编代码编译器,然后将其转换为机器代码。

问题1: Python编译器如何设计来识别运算符? (关于词法和解析功能)

问题2 :如何修改Python解释器的这种简单行为,在该行为中,使用多个运算符时会抛出语法错误,与乘法操作相同。
>>> 2**2
4
>>> 2***2
  File "<stdin>", line 1
    2***2
       ^
SyntaxError: invalid syntax

我已经阅读了cpython的以下文件:compile.c parser.creadline.c

但是我没有在语法错误的异常处理机制中遇到任何这样的文件。

更新:

我仍在搜索并等待问题2的任何答案

最佳答案

您已经跳过了二元运算符和一元运算符之间的区别。简而言之,-2实际上是数字“负二”。 --2是“负数(负二)”,或更常用的是“正数二”。 2+++--2被解析为“2加正负数负2”,因此归结为2+2并为您提供4+2-2都是数字,但*2并非数字,因此这就是发生语法错误的原因。

如果您想要令人恐惧的细节,请继续阅读,但是第一段最直接地回答了您的问题。

您要求提供详细信息,所以就来了。编程语言(通常...)由无上下文语法定义。使用Bachus Naur Form描述Python的语法。从https://docs.python.org/2/reference/expressions.html#unary-arithmetic-and-bitwise-operations,我们有以下定义:

u_expr ::=  power | "-" u_expr | "+" u_expr | "~" u_expr

m_expr ::=  u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr
            | m_expr "%" u_expr

a_expr ::=  m_expr | a_expr "+" m_expr | a_expr "-" m_expr

这用Python语言定义了一元表达式,乘法表达式和算术表达式。在尝试解释之前,我将把这两者都缩小到与我们的问题直接相关的部分:
u_expr ::=  "2" | "-" u_expr | "+" u_expr

m_expr ::=  u_expr | m_expr "*" u_expr

a_expr ::=  m_expr | a_expr "+" m_expr | a_expr "-" m_expr

因此,在此语法中,u_expr要么是2,要么是文字字符串+-,后跟任何其他u_expr,因此以下所有内容均符合u_expr的定义:'2', '-2', '+2', '+-2', '++++---++2'
m_expr可以是u_expr,也可以是m_expr,然后是*,再是u_expr22*22*+22*++-+2均符合此定义。
a_expr可以是m_expr,也可以是a_expr,后跟加号或减号,然后是m_expr22*22+22+2*22++2*-2等。

现在,让我们开始看看您的第一个语法错误2+++*2。我们正在尝试将其转换为a_expr。它以2+开头,因此我们必须寻找a_expr "+" m_expr形式的东西。 2a_expr,我们有字面的+,因此为了避免语法错误,我们必须以某种方式将++*2转换为m_expr。我们可以看到每个a_expr必须以“2”开头,但是现在解析失败。

但是,2+++--2可以解析为a_expr。具体来说,2a_expr,其后是文字+,后跟是++--2m_expr

关于使2***2有意义的第二个问题,恐怕在Python中您必须重新定义程序成为有效Python的实际含义。查看我链接的文档,您会发现每个运算符都已明确定义,对于**,我们有:
power ::=  primary ["**" u_expr]

诸如Haskell之类的某些语言对2+2之类的东西的根本含义有所不同,并且可以让您定义自己的任意运算符。使用这种语言,您可以定义***运算符,但是Python没有提高PEP并从根本上重写Python的部分就没有这样的功能。

如果您需要更多细节,那么您将直接进入计算机科学而不是编程—是的,它们是不同的。通过查找诸如常规语言,有限状态自动机,无上下文语言和Comsky层次结构之类的主题来开始自己的工作

关于python - 如何识别数学运算符,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41997158/

10-14 19:10
查看更多