mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-15 10:07:06 +08:00
slice precedences should be working as well.
This commit is contained in:
@@ -40,14 +40,14 @@ class PythonGrammar(object):
|
|||||||
|
|
||||||
#TEST = or_test ['if' or_test 'else' test] | lambdef
|
#TEST = or_test ['if' or_test 'else' test] | lambdef
|
||||||
|
|
||||||
#SLICEOP = ':' [test]
|
SLICE = ':',
|
||||||
#SUBSCRIPT = test | [test] ':' [test] [sliceop]
|
|
||||||
ORDER = (POWER, TERM, ARITH_EXPR, SHIFT_EXPR, AND_EXPR, XOR_EXPR,
|
ORDER = (POWER, TERM, ARITH_EXPR, SHIFT_EXPR, AND_EXPR, XOR_EXPR,
|
||||||
EXPR, COMPARISON, AND_TEST, OR_TEST)
|
EXPR, COMPARISON, AND_TEST, OR_TEST, SLICE)
|
||||||
|
|
||||||
FACTOR_PRIORITY = 0 # highest priority
|
FACTOR_PRIORITY = 0 # highest priority
|
||||||
LOWEST_PRIORITY = len(ORDER)
|
LOWEST_PRIORITY = len(ORDER)
|
||||||
NOT_TEST_PRIORITY = LOWEST_PRIORITY - 2 # priority only lower for `and`/`or`
|
NOT_TEST_PRIORITY = LOWEST_PRIORITY - 3 # priority only lower for `and`/`or`
|
||||||
|
SLICE_PRIORITY = LOWEST_PRIORITY - 1 # priority only lower for `and`/`or`
|
||||||
|
|
||||||
|
|
||||||
class Precedence(object):
|
class Precedence(object):
|
||||||
@@ -89,6 +89,10 @@ def _get_number(iterator, priority=PythonGrammar.LOWEST_PRIORITY):
|
|||||||
elif el in PythonGrammar.NOT_TEST \
|
elif el in PythonGrammar.NOT_TEST \
|
||||||
and priority >= PythonGrammar.NOT_TEST_PRIORITY:
|
and priority >= PythonGrammar.NOT_TEST_PRIORITY:
|
||||||
right = _get_number(iterator, PythonGrammar.NOT_TEST_PRIORITY)
|
right = _get_number(iterator, PythonGrammar.NOT_TEST_PRIORITY)
|
||||||
|
elif el in PythonGrammar.SLICE \
|
||||||
|
and priority >= PythonGrammar.SLICE_PRIORITY:
|
||||||
|
iterator.push_back(el)
|
||||||
|
return None
|
||||||
else:
|
else:
|
||||||
_syntax_error(el)
|
_syntax_error(el)
|
||||||
return _get_number(iterator, priority)
|
return _get_number(iterator, priority)
|
||||||
@@ -98,12 +102,9 @@ def _get_number(iterator, priority=PythonGrammar.LOWEST_PRIORITY):
|
|||||||
|
|
||||||
|
|
||||||
def _check_operator(iterator, priority=PythonGrammar.LOWEST_PRIORITY):
|
def _check_operator(iterator, priority=PythonGrammar.LOWEST_PRIORITY):
|
||||||
"""
|
|
||||||
"""
|
|
||||||
try:
|
try:
|
||||||
left = _get_number(iterator, priority)
|
left = _get_number(iterator, priority)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
_syntax_error(iterator.current, 'SyntaxError operand missing')
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
for el in iterator:
|
for el in iterator:
|
||||||
@@ -143,6 +144,8 @@ def _check_operator(iterator, priority=PythonGrammar.LOWEST_PRIORITY):
|
|||||||
if operator == '**':
|
if operator == '**':
|
||||||
check_prio += 1 # to the power of is right-associative
|
check_prio += 1 # to the power of is right-associative
|
||||||
right = _check_operator(iterator, check_prio)
|
right = _check_operator(iterator, check_prio)
|
||||||
if right is not None:
|
if right is None and not operator in PythonGrammar.SLICE:
|
||||||
|
_syntax_error(iterator.current, 'SyntaxError operand missing')
|
||||||
|
else:
|
||||||
left = Precedence(left, str(operator), right)
|
left = Precedence(left, str(operator), right)
|
||||||
return left
|
return left
|
||||||
|
|||||||
@@ -2,9 +2,12 @@ from jedi.parser import Parser
|
|||||||
from jedi.evaluate import precedence
|
from jedi.evaluate import precedence
|
||||||
|
|
||||||
|
|
||||||
def parse_tree(statement_string):
|
def parse_tree(statement_string, is_slice=False):
|
||||||
p = Parser(statement_string, no_docstr=True)
|
p = Parser(statement_string, no_docstr=True)
|
||||||
stmt = p.module.statements[0]
|
stmt = p.module.statements[0]
|
||||||
|
if is_slice:
|
||||||
|
# get the part of the execution that is the slice
|
||||||
|
stmt = stmt.expression_list()[0].execution[0]
|
||||||
iterable = iter(stmt.expression_list())
|
iterable = iter(stmt.expression_list())
|
||||||
pr = precedence.create_precedence(iterable)
|
pr = precedence.create_precedence(iterable)
|
||||||
if isinstance(pr, precedence.Precedence):
|
if isinstance(pr, precedence.Precedence):
|
||||||
@@ -51,3 +54,14 @@ def test_multi_part():
|
|||||||
|
|
||||||
def test_power():
|
def test_power():
|
||||||
assert parse_tree('2 ** 3 ** 4') == (2, '**', (3, '**', 4))
|
assert parse_tree('2 ** 3 ** 4') == (2, '**', (3, '**', 4))
|
||||||
|
|
||||||
|
|
||||||
|
def test_slice():
|
||||||
|
"""
|
||||||
|
Should be parsed as normal operators. This is not proper Python syntax,
|
||||||
|
but the warning shouldn't be given in the precedence generation.
|
||||||
|
"""
|
||||||
|
assert parse_tree('[0][2+1:3]', is_slice=True) == ((2, '+', 1), ':', 3)
|
||||||
|
assert parse_tree('[0][:]', is_slice=True) == (None, ':', None)
|
||||||
|
assert parse_tree('[0][1:]', is_slice=True) == (1, ':', None)
|
||||||
|
assert parse_tree('[0][:2]', is_slice=True) == (None, ':', 2)
|
||||||
|
|||||||
Reference in New Issue
Block a user