简单的 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.c,readline.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_expr
。 2
,2*2
,2*+2
,2*++-+2
均符合此定义。a_expr
可以是m_expr
,也可以是a_expr
,后跟加号或减号,然后是m_expr
。 2
,2*2
,2+2
,2+2*2
,2++2*-2
等。现在,让我们开始看看您的第一个语法错误
2+++*2
。我们正在尝试将其转换为a_expr
。它以2+
开头,因此我们必须寻找a_expr "+" m_expr
形式的东西。 2
是a_expr
,我们有字面的+
,因此为了避免语法错误,我们必须以某种方式将++*2
转换为m_expr
。我们可以看到每个a_expr
必须以“2”开头,但是现在解析失败。但是,
2+++--2
可以解析为a_expr
。具体来说,2
是a_expr
,其后是文字+
,后跟是++--2
的m_expr
。关于使
2***2
有意义的第二个问题,恐怕在Python中您必须重新定义程序成为有效Python的实际含义。查看我链接的文档,您会发现每个运算符都已明确定义,对于**
,我们有:power ::= primary ["**" u_expr]
诸如Haskell之类的某些语言对
2+2
之类的东西的根本含义有所不同,并且可以让您定义自己的任意运算符。使用这种语言,您可以定义***
运算符,但是Python没有提高PEP并从根本上重写Python的部分就没有这样的功能。如果您需要更多细节,那么您将直接进入计算机科学而不是编程—是的,它们是不同的。通过查找诸如常规语言,有限状态自动机,无上下文语言和Comsky层次结构之类的主题来开始自己的工作
关于python - 如何识别数学运算符,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41997158/