[pypy-commit] pypy pyparser-improvements-3: merge default

2018-06-06 Thread cfbolz
Author: Carl Friedrich Bolz-Tereick 
Branch: pyparser-improvements-3
Changeset: r94729:37acacd15a8b
Date: 2018-06-06 14:27 +0200
http://bitbucket.org/pypy/pypy/changeset/37acacd15a8b/

Log:merge default

diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py 
b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -27,7 +27,7 @@
 generator._resolve_block_targets(blocks)
 return generator, blocks
 
-class TestCompiler:
+class BaseTestCompiler:
 """These tests compile snippets of code and check them by
 running them with our own interpreter.  These are thus not
 completely *unit* tests, but given that our interpreter is
@@ -74,6 +74,9 @@
 def error_test(self, source, exc_type):
 py.test.raises(exc_type, self.simple_test, source, None, None)
 
+
+class TestCompiler(BaseTestCompiler):
+
 def test_issue_713(self):
 func = "def f(_=2): return (_ if _ else _) if False else _"
 yield self.st, func, "f()", 2
@@ -953,9 +956,11 @@
 yield (self.st, "x=(lambda: (-0.0, 0.0), lambda: (0.0, -0.0))[1]()",
 'repr(x)', '(0.0, -0.0)')
 
+class TestCompilerRevDB(BaseTestCompiler):
+spaceconfig = {"translation.reverse_debugger": True}
+
 def test_revdb_metavar(self):
 from pypy.interpreter.reverse_debugging import dbstate, setup_revdb
-self.space.config.translation.reverse_debugger = True
 self.space.reverse_debugging = True
 try:
 setup_revdb(self.space)
diff --git a/pypy/interpreter/pyparser/parser.py 
b/pypy/interpreter/pyparser/parser.py
--- a/pypy/interpreter/pyparser/parser.py
+++ b/pypy/interpreter/pyparser/parser.py
@@ -28,6 +28,7 @@
 new.symbol_ids = self.symbol_ids
 new.symbols_names = self.symbol_names
 new.keyword_ids = self.keyword_ids
+new.token_to_error_string = self.token_to_error_string
 new.dfas = self.dfas
 new.labels = self.labels
 new.token_ids = self.token_ids
diff --git a/pypy/interpreter/pyparser/pygram.py 
b/pypy/interpreter/pyparser/pygram.py
--- a/pypy/interpreter/pyparser/pygram.py
+++ b/pypy/interpreter/pyparser/pygram.py
@@ -23,6 +23,17 @@
 python_grammar_no_print.keyword_ids = 
python_grammar_no_print.keyword_ids.copy()
 del python_grammar_no_print.keyword_ids["print"]
 
+python_grammar_revdb = python_grammar.shared_copy()
+python_grammar_no_print_revdb = python_grammar_no_print.shared_copy()
+copied_token_ids = python_grammar.token_ids.copy()
+python_grammar_revdb.token_ids = copied_token_ids
+python_grammar_no_print_revdb.token_ids = copied_token_ids
+
+metavar_token_id = pytoken.python_tokens['REVDBMETAVAR']
+# the following line affects python_grammar_no_print too, since they share the
+# dict
+del python_grammar.token_ids[metavar_token_id]
+
 class _Tokens(object):
 pass
 for tok_name, idx in pytoken.python_tokens.iteritems():
@@ -39,3 +50,16 @@
 syms._rev_lookup = rev_lookup # for debugging
 
 del _get_python_grammar, _Tokens, tok_name, sym_name, idx
+
+def choose_grammar(print_function, revdb):
+if print_function:
+if revdb:
+return python_grammar_no_print_revdb
+else:
+return python_grammar_no_print
+else:
+if revdb:
+return python_grammar_revdb
+else:
+return python_grammar
+
diff --git a/pypy/interpreter/pyparser/pyparse.py 
b/pypy/interpreter/pyparser/pyparse.py
--- a/pypy/interpreter/pyparser/pyparse.py
+++ b/pypy/interpreter/pyparser/pyparse.py
@@ -165,10 +165,9 @@
 compile_info.last_future_import = last_future_import
 compile_info.flags |= newflags
 
-if compile_info.flags & consts.CO_FUTURE_PRINT_FUNCTION:
-self.grammar = pygram.python_grammar_no_print
-else:
-self.grammar = pygram.python_grammar
+self.grammar = pygram.choose_grammar(
+print_function=compile_info.flags & 
consts.CO_FUTURE_PRINT_FUNCTION,
+revdb=self.space.config.translation.reverse_debugger)
 
 try:
 for token in tokens:
diff --git a/pypy/interpreter/pyparser/test/test_pyparse.py 
b/pypy/interpreter/pyparser/test/test_pyparse.py
--- a/pypy/interpreter/pyparser/test/test_pyparse.py
+++ b/pypy/interpreter/pyparser/test/test_pyparse.py
@@ -168,13 +168,11 @@
 assert expected_tree == tree
 
 def test_revdb_dollar_num(self):
-self.parse('$0')
-self.parse('$5')
-self.parse('$42')
-self.parse('2+$42.attrname')
-py.test.raises(SyntaxError, self.parse, '$')
-py.test.raises(SyntaxError, self.parse, '$a')
-py.test.raises(SyntaxError, self.parse, '$.5')
+assert not self.space.config.translation.reverse_debugger
+py.test.raises(SyntaxError, self.parse, '$0')
+

[pypy-commit] pypy default: merge pyparser-improvements-3

2018-06-06 Thread cfbolz
Author: Carl Friedrich Bolz-Tereick 
Branch: 
Changeset: r94730:e85e93d7927e
Date: 2018-06-06 15:11 +0200
http://bitbucket.org/pypy/pypy/changeset/e85e93d7927e/

Log:merge pyparser-improvements-3

some small refactorings in interpreter/pyparser and module/parser

diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -27,3 +27,8 @@
 
 The reverse-debugger branch has been merged.  For more information, see
 https://bitbucket.org/pypy/revdb
+
+
+.. branch: pyparser-improvements-3
+
+Small refactorings in the Python parser.
diff --git a/pypy/interpreter/pyparser/future.py 
b/pypy/interpreter/pyparser/future.py
--- a/pypy/interpreter/pyparser/future.py
+++ b/pypy/interpreter/pyparser/future.py
@@ -43,7 +43,7 @@
 self.tok = self.tokens[index]
 
 def skip(self, n):
-if self.tok[0] == n:
+if self.tok.token_type == n:
 self.next()
 return True
 else:
@@ -51,7 +51,7 @@
 
 def skip_name(self, name):
 from pypy.interpreter.pyparser import pygram
-if self.tok[0] == pygram.tokens.NAME and self.tok[1] == name:
+if self.tok.token_type == pygram.tokens.NAME and self.tok.value == 
name:
 self.next()
 return True
 else:
@@ -59,8 +59,8 @@
 
 def next_feature_name(self):
 from pypy.interpreter.pyparser import pygram
-if self.tok[0] == pygram.tokens.NAME:
-name = self.tok[1]
+if self.tok.token_type == pygram.tokens.NAME:
+name = self.tok.value
 self.next()
 if self.skip_name("as"):
 self.skip(pygram.tokens.NAME)
@@ -101,7 +101,7 @@
 # somewhere inside the last __future__ import statement
 # (at the start would be fine too, but it's easier to grab a
 # random position inside)
-last_position = (it.tok[2], it.tok[3])
+last_position = (it.tok.lineno, it.tok.column)
 result |= future_flags.get_compiler_feature(it.next_feature_name())
 while it.skip(pygram.tokens.COMMA):
 result |= future_flags.get_compiler_feature(it.next_feature_name())
diff --git a/pypy/interpreter/pyparser/parser.py 
b/pypy/interpreter/pyparser/parser.py
--- a/pypy/interpreter/pyparser/parser.py
+++ b/pypy/interpreter/pyparser/parser.py
@@ -34,6 +34,18 @@
 new.token_ids = self.token_ids
 return new
 
+
+def classify(self, token):
+"""Find the label for a token."""
+if token.token_type == self.KEYWORD_TOKEN:
+label_index = self.keyword_ids.get(token.value, -1)
+if label_index != -1:
+return label_index
+label_index = self.token_ids.get(token.token_type, -1)
+if label_index == -1:
+raise ParseError("invalid token", token)
+return label_index
+
 def _freeze_(self):
 # Remove some attributes not used in parsing.
 try:
@@ -66,6 +78,33 @@
 b[pos] |= bit
 return str(b)
 
+
+class Token(object):
+def __init__(self, token_type, value, lineno, column, line):
+self.token_type = token_type
+self.value = value
+self.lineno = lineno
+# 0-based offset
+self.column = column
+self.line = line
+
+def __repr__(self):
+return "Token(%s, %s)" % (self.token_type, self.value)
+
+def __eq__(self, other):
+# for tests
+return (
+self.token_type == other.token_type and
+self.value == other.value and
+self.lineno == other.lineno and
+self.column == other.column and
+self.line == other.line
+)
+
+def __ne__(self, other):
+return not self == other
+
+
 class Node(object):
 
 __slots__ = ("type", )
@@ -106,6 +145,11 @@
 self.lineno = lineno
 self.column = column
 
+@staticmethod
+def fromtoken(token):
+return Terminal(
+token.token_type, token.value, token.lineno, token.column)
+
 def __repr__(self):
 return "Terminal(type=%s, value=%r)" % (self.type, self.value)
 
@@ -194,20 +238,14 @@
 
 class ParseError(Exception):
 
-def __init__(self, msg, token_type, value, lineno, column, line,
- expected=-1, expected_str=None):
+def __init__(self, msg, token, expected=-1, expected_str=None):
 self.msg = msg
-self.token_type = token_type
-self.value = value
-self.lineno = lineno
-# this is a 0-based index
-self.column = column
-self.line = line
+self.token = token
 self.expected = expected
 self.expected_str = expected_str
 
 def __str__(self):
-return "ParserError(%s, %r)" % (self.token_type, self.value)
+return "ParserError(%s)" % (self.token, )
 
 
 class StackEntry(object):
@@ -250,8 +288,8 @@
 self.root = None
 self.stack