Вы споткнулся разница между бинарным и унарным. В кратчайших сроках -2
буквально является числом «отрицательные два». --2
«отрицательный (отрицательный два)», или более условно «положительные два». 2+++--2
анализируется как «два плюс положительные отрицательные отрицательные два», поэтому он сводится к 2+2
и дает вам 4
. Оба +2
и -2
являются номерами, но *2
- нет, поэтому возникает синтаксическая ошибка.
Читайте дальше, если вы хотите ужасающие детали, но первый абзац наиболее точно отвечает на ваш вопрос.
Вы запросили детали, так что вот оно. Языки программирования (обычно ...) определяются понятиями, называемыми контекстно-свободными грамматиками. Грамматика Python описывается с использованием формы Bachus Naur. Из 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.
Если вы хотите получить более подробную информацию, вы будете входить в компьютерную науку, а не программировать - да, они разные. Начните с изучения таких тем, как «Регулярные языки», «Автоматы с конечным состоянием», «Контекстно-свободные языки» и «Комская иерархия»
Существует так много способов сделать это, посмотрите на [wiki] (https: // en. wikipedia.org/wiki/Lexical_analysis). – Stargateur
@Stargateur Спасибо за ссылку. Я знал о лексических анализаторах и синтаксических анализаторах, но я не знаю, как его детали работают на python. –
Это не плохой вопрос, просто слишком широкий. Я думаю, что было бы идеально по теме, если бы вы могли только сузить ее до одного конкретного языка программирования, так как Python и C в этом отношении очень разные. – Lundin