2017-02-02 3 views
4

Как простой 2 ++ 2 работает за кулисами на языке Python?Как идентифицируются математические операторы

Если мы вводим это в интерпретатора:

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

Глядя на ошибки синтаксиса тут я заметил, что это был путь Python разработан/реализована разработчиками Python.

Говорят, что Python является открытым исходным кодом, поэтому я начал исследовать его больше. Я прочитал много статей о реализации Python, используя cpython.

Итак, здесь компилятор Python легко идентифицирует эти операторы ++*%-. Потому что это написано на языке C. И C использует некоторый компилятор кода прямой сборки, который затем преобразуется в машинный код.

Вопрос 1: Каким образом компилятор Python предназначен для идентификации операторов? (В отношении лексического и синтаксического анализа функциональности)

Вопрос 2: Как я могу изменить это простое поведение интерпретатора Python, где он может бросить синтаксическую ошибку для использования нескольких операторов, как же, что он делает для умножения

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

Я прочитал эти файлы CPython: compile.cparser.c, readline.c

Но я не сталкивался ни таких файлы исключений механизма синтаксической ошибки обработки.

Update:

Я все еще ищу и жду каких-либо ответов на вопрос-2

+2

Существует так много способов сделать это, посмотрите на [wiki] (https: // en. wikipedia.org/wiki/Lexical_analysis). – Stargateur

+0

@Stargateur Спасибо за ссылку. Я знал о лексических анализаторах и синтаксических анализаторах, но я не знаю, как его детали работают на python. –

+0

Это не плохой вопрос, просто слишком широкий. Я думаю, что было бы идеально по теме, если бы вы могли только сузить ее до одного конкретного языка программирования, так как Python и C в этом отношении очень разные. – Lundin

ответ

7

Вы споткнулся разница между бинарным и унарным. В кратчайших сроках -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.

Если вы хотите получить более подробную информацию, вы будете входить в компьютерную науку, а не программировать - да, они разные. Начните с изучения таких тем, как «Регулярные языки», «Автоматы с конечным состоянием», «Контекстно-свободные языки» и «Комская иерархия»

+0

Плюс один. ** Это потрясающее усилие **. – Bathsheba

+0

Спасибо. это действительно очень хороший ответ. –

+1

Следует добавить, что в Python вы можете определить, что делают операторы на уровне объекта, так что (например) вы можете написать код, чтобы иметь смысл «вытеснить = вектор» (3.0.4.5.1.2) + Vector (2.7, -4.3 , -9,1) '. Вероятно, это является оправданием для унарного оператора '+', поскольку при применении к стандартным номерам он не работает. – nigel222

Смежные вопросы