You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-02 16:44:46 +08:00
store_subscript precedence fix and...
Allow format specifier "%p" to indicate a nonterminal name, like "%c" allows. store_subscr -> store_subscript to match Python AST a little closer.
This commit is contained in:
@@ -127,11 +127,17 @@ def test_tables():
|
||||
"Full entry: %s" %
|
||||
(name, k, arg, typ, entry[arg], type(entry[arg]), entry)
|
||||
)
|
||||
assert len(tup) == 2
|
||||
assert 2 <= len(tup) <= 3
|
||||
for j, x in enumerate(tup):
|
||||
assert isinstance(x, int), (
|
||||
"%s[%s][%d][%d] type '%s' is '%s should be an int but is %s. Full entry: %s" %
|
||||
(name, k, arg, j, typ, x, type(x), entry)
|
||||
if len(tup) == 3 and j == 1:
|
||||
assert isinstance(x, str), (
|
||||
"%s[%s][%d][%d] type '%s' is '%s should be an string but is %s. Full entry: %s" %
|
||||
(name, k, arg, j, typ, x, type(x), entry)
|
||||
)
|
||||
else:
|
||||
assert isinstance(x, int), (
|
||||
"%s[%s][%d][%d] type '%s' is '%s should be an int but is %s. Full entry: %s" %
|
||||
(name, k, arg, j, typ, x, type(x), entry)
|
||||
)
|
||||
pass
|
||||
arg += 1
|
||||
|
BIN
test/bytecode_2.7_run/04_subscript.pyc
Normal file
BIN
test/bytecode_2.7_run/04_subscript.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.6_run/04_subscript.pyc
Normal file
BIN
test/bytecode_3.6_run/04_subscript.pyc
Normal file
Binary file not shown.
11
test/simple_source/expression/04_subscript.py
Normal file
11
test/simple_source/expression/04_subscript.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# From 3.6.8 idlelib/query.py
|
||||
# Bug was handling parens around subscript
|
||||
|
||||
# RUNNABLE!
|
||||
a = {'text': 1}
|
||||
b = {'text': 3}
|
||||
for widget, entry, expect in (
|
||||
(a, b, 1),
|
||||
(None, b, 3)
|
||||
):
|
||||
assert (widget or entry)['text'] == expect
|
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2015-2018 Rocky Bernstein
|
||||
# Copyright (c) 2015-2019 Rocky Bernstein
|
||||
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
|
||||
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||
# Copyright (c) 1999 John Aycock
|
||||
@@ -589,14 +589,14 @@ class PythonParser(GenericASTBuilder):
|
||||
## designLists ::=
|
||||
## Will need to redo semantic actiion
|
||||
|
||||
store ::= STORE_FAST
|
||||
store ::= STORE_NAME
|
||||
store ::= STORE_GLOBAL
|
||||
store ::= STORE_DEREF
|
||||
store ::= expr STORE_ATTR
|
||||
store ::= store_subscr
|
||||
store_subscr ::= expr expr STORE_SUBSCR
|
||||
store ::= unpack
|
||||
store ::= STORE_FAST
|
||||
store ::= STORE_NAME
|
||||
store ::= STORE_GLOBAL
|
||||
store ::= STORE_DEREF
|
||||
store ::= expr STORE_ATTR
|
||||
store ::= store_subscript
|
||||
store_subscript ::= expr expr STORE_SUBSCR
|
||||
store ::= unpack
|
||||
'''
|
||||
|
||||
|
||||
|
@@ -27,6 +27,78 @@ else:
|
||||
maxint = sys.maxint
|
||||
|
||||
|
||||
# Operator precidence
|
||||
# See https://docs.python.org/2/reference/expressions.html
|
||||
# or https://docs.python.org/3/reference/expressions.html
|
||||
# for a list.
|
||||
|
||||
# Things at the top of this list below with low-value precidence will
|
||||
# tend to have parenthesis around them. Things at the bottom
|
||||
# of the list will tend not to have parenthesis around them.
|
||||
PRECEDENCE = {
|
||||
'list': 0,
|
||||
'dict': 0,
|
||||
'unary_convert': 0,
|
||||
'dict_comp': 0,
|
||||
'set_comp': 0,
|
||||
'set_comp_expr': 0,
|
||||
'list_comp': 0,
|
||||
'generator_exp': 0,
|
||||
|
||||
'attribute': 2,
|
||||
'subscript': 2,
|
||||
'subscript2': 2,
|
||||
'store_subscript': 2,
|
||||
'delete_subscr': 2,
|
||||
'slice0': 2,
|
||||
'slice1': 2,
|
||||
'slice2': 2,
|
||||
'slice3': 2,
|
||||
'buildslice2': 2,
|
||||
'buildslice3': 2,
|
||||
'call': 2,
|
||||
|
||||
'BINARY_POWER': 4,
|
||||
|
||||
'unary_expr': 6,
|
||||
|
||||
'BINARY_MULTIPLY': 8,
|
||||
'BINARY_DIVIDE': 8,
|
||||
'BINARY_TRUE_DIVIDE': 8,
|
||||
'BINARY_FLOOR_DIVIDE': 8,
|
||||
'BINARY_MODULO': 8,
|
||||
|
||||
'BINARY_ADD': 10,
|
||||
'BINARY_SUBTRACT': 10,
|
||||
|
||||
'BINARY_LSHIFT': 12,
|
||||
'BINARY_RSHIFT': 12,
|
||||
|
||||
'BINARY_AND': 14,
|
||||
'BINARY_XOR': 16,
|
||||
'BINARY_OR': 18,
|
||||
|
||||
'compare': 20,
|
||||
'unary_not': 22,
|
||||
'and': 24,
|
||||
'ret_and': 24,
|
||||
|
||||
'or': 26,
|
||||
'ret_or': 26,
|
||||
|
||||
'conditional': 28,
|
||||
'conditional_lamdba': 28,
|
||||
'conditional_not_lamdba': 28,
|
||||
'conditionalnot': 28,
|
||||
'ret_cond': 28,
|
||||
'ret_cond_not': 28,
|
||||
|
||||
'_mklambda': 30,
|
||||
|
||||
'yield': 101,
|
||||
'yield_from': 101
|
||||
}
|
||||
|
||||
LINE_LENGTH = 80
|
||||
|
||||
# Some parse trees created below are used for comparing code
|
||||
@@ -150,15 +222,17 @@ TABLE_DIRECT = {
|
||||
'DELETE_FAST': ( '%|del %{pattr}\n', ),
|
||||
'DELETE_NAME': ( '%|del %{pattr}\n', ),
|
||||
'DELETE_GLOBAL': ( '%|del %{pattr}\n', ),
|
||||
'delete_subscr': ( '%|del %c[%c]\n',
|
||||
(0, 'expr'), (1, 'expr') ),
|
||||
'subscript': ( '%c[%p]',
|
||||
(0, 'expr'),
|
||||
(1, 100) ),
|
||||
'subscript2': ( '%c[%c]',
|
||||
(0, 'expr'),
|
||||
'delete_subscr': ( '%|del %p[%c]\n',
|
||||
(0, 'expr', PRECEDENCE['subscript']), (1, 'expr') ),
|
||||
'subscript': ( '%p[%c]',
|
||||
(0, 'expr', PRECEDENCE['subscript']),
|
||||
(1, 'expr') ),
|
||||
'store_subscr': ( '%c[%c]', 0, 1),
|
||||
'subscript2': ( '%p[%c]',
|
||||
(0, 'expr', PRECEDENCE['subscript']),
|
||||
(1, 'expr') ),
|
||||
'store_subscript': ( '%p[%c]',
|
||||
(0, 'expr', PRECEDENCE['subscript']),
|
||||
(1, 'expr') ),
|
||||
'STORE_FAST': ( '%{pattr}', ),
|
||||
'STORE_NAME': ( '%{pattr}', ),
|
||||
'STORE_GLOBAL': ( '%{pattr}', ),
|
||||
@@ -337,76 +411,6 @@ MAP = {
|
||||
'exprlist': MAP_R0,
|
||||
}
|
||||
|
||||
# Operator precidence
|
||||
# See https://docs.python.org/2/reference/expressions.html
|
||||
# or https://docs.python.org/3/reference/expressions.html
|
||||
# for a list.
|
||||
|
||||
# Things at the top of this list below with low-value precidence will
|
||||
# tend to have parenthesis around them. Things at the bottom
|
||||
# of the list will tend not to have parenthesis around them.
|
||||
PRECEDENCE = {
|
||||
'list': 0,
|
||||
'dict': 0,
|
||||
'unary_convert': 0,
|
||||
'dict_comp': 0,
|
||||
'set_comp': 0,
|
||||
'set_comp_expr': 0,
|
||||
'list_comp': 0,
|
||||
'generator_exp': 0,
|
||||
|
||||
'attribute': 2,
|
||||
'subscript': 2,
|
||||
'subscript2': 2,
|
||||
'slice0': 2,
|
||||
'slice1': 2,
|
||||
'slice2': 2,
|
||||
'slice3': 2,
|
||||
'buildslice2': 2,
|
||||
'buildslice3': 2,
|
||||
'call': 2,
|
||||
|
||||
'BINARY_POWER': 4,
|
||||
|
||||
'unary_expr': 6,
|
||||
|
||||
'BINARY_MULTIPLY': 8,
|
||||
'BINARY_DIVIDE': 8,
|
||||
'BINARY_TRUE_DIVIDE': 8,
|
||||
'BINARY_FLOOR_DIVIDE': 8,
|
||||
'BINARY_MODULO': 8,
|
||||
|
||||
'BINARY_ADD': 10,
|
||||
'BINARY_SUBTRACT': 10,
|
||||
|
||||
'BINARY_LSHIFT': 12,
|
||||
'BINARY_RSHIFT': 12,
|
||||
|
||||
'BINARY_AND': 14,
|
||||
'BINARY_XOR': 16,
|
||||
'BINARY_OR': 18,
|
||||
|
||||
'compare': 20,
|
||||
'unary_not': 22,
|
||||
'and': 24,
|
||||
'ret_and': 24,
|
||||
|
||||
'or': 26,
|
||||
'ret_or': 26,
|
||||
|
||||
'conditional': 28,
|
||||
'conditional_lamdba': 28,
|
||||
'conditional_not_lamdba': 28,
|
||||
'conditionalnot': 28,
|
||||
'ret_cond': 28,
|
||||
'ret_cond_not': 28,
|
||||
|
||||
'_mklambda': 30,
|
||||
|
||||
'yield': 101,
|
||||
'yield_from': 101
|
||||
}
|
||||
|
||||
ASSIGN_TUPLE_PARAM = lambda param_name: \
|
||||
SyntaxTree('expr', [ Token('LOAD_FAST', pattr=param_name) ])
|
||||
|
||||
|
@@ -88,7 +88,8 @@ Python.
|
||||
#
|
||||
# %p like %c but sets the operator precedence.
|
||||
# Its argument then is a tuple indicating the node
|
||||
# index and the precidence value, an integer.
|
||||
# index and the precedence value, an integer. If 3 items are given,
|
||||
# the second item is the nonterminal name and the precedence is given last.
|
||||
#
|
||||
# %C evaluate children recursively, with sibling children separated by the
|
||||
# given string. It needs a 3-tuple: a starting node, the maximimum
|
||||
@@ -616,7 +617,7 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
node[-2][0].kind = 'build_tuple2'
|
||||
self.default(node)
|
||||
|
||||
n_store_subscr = n_subscript = n_delete_subscr
|
||||
n_store_subscript = n_subscript = n_delete_subscr
|
||||
|
||||
# Note: this node is only in Python 2.x
|
||||
# FIXME: figure out how to get this into customization
|
||||
@@ -1873,7 +1874,18 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
arg += 1
|
||||
elif typ == 'p':
|
||||
p = self.prec
|
||||
(index, self.prec) = entry[arg]
|
||||
tup = entry[arg]
|
||||
assert isinstance(tup, tuple)
|
||||
if len(tup) == 3:
|
||||
(index, nonterm_name, self.prec) = tup
|
||||
assert node[index] == nonterm_name, (
|
||||
"at %s[%d], expected '%s' node; got '%s'" % (
|
||||
node.kind, arg, nonterm_name, node[index].kind)
|
||||
)
|
||||
else:
|
||||
assert len(tup) == 2
|
||||
(index, self.prec) = entry[arg]
|
||||
|
||||
self.preorder(node[index])
|
||||
self.prec = p
|
||||
arg += 1
|
||||
|
Reference in New Issue
Block a user