github.com/google/grumpy@v0.0.0-20171122020858-3ec87959189c/third_party/pythonparser/parser.py (about)

     1  # encoding:utf-8
     2  
     3  """
     4  The :mod:`parser` module concerns itself with parsing Python source.
     5  """
     6  
     7  from __future__ import absolute_import, division, print_function, unicode_literals
     8  from functools import reduce
     9  from . import source, diagnostic, lexer, ast
    10  
    11  # A few notes about our approach to parsing:
    12  #
    13  # Python uses an LL(1) parser generator. It's a bit weird, because
    14  # the usual reason to choose LL(1) is to make a handwritten parser
    15  # possible, however Python's grammar is formulated in a way that
    16  # is much more easily recognized if you make an FSM rather than
    17  # the usual "if accept(token)..." ladder. So in a way it is
    18  # the worst of both worlds.
    19  #
    20  # We don't use a parser generator because we want to have an unified
    21  # grammar for all Python versions, and also have grammar coverage
    22  # analysis and nice error recovery. To make the grammar compact,
    23  # we use combinators to compose it from predefined fragments,
    24  # such as "sequence" or "alternation" or "Kleene star". This easily
    25  # gives us one token of lookahead in most cases, but e.g. not
    26  # in the following one:
    27  #
    28  #     argument: test | test '=' test
    29  #
    30  # There are two issues with this. First, in an alternation, the first
    31  # variant will be tried (and accepted) earlier. Second, if we reverse
    32  # them, by the point it is clear ``'='`` will not be accepted, ``test``
    33  # has already been consumed.
    34  #
    35  # The way we fix this is by reordering rules so that longest match
    36  # comes first, and adding backtracking on alternations (as well as
    37  # plus and star, since those have a hidden alternation inside).
    38  #
    39  # While backtracking can in principle make asymptotical complexity
    40  # worse, it never makes parsing syntactically correct code supralinear
    41  # with Python's LL(1) grammar, and we could not come up with any
    42  # pathological incorrect input as well.
    43  
    44  # Coverage data
    45  _all_rules = []
    46  _all_stmts = {}
    47  
    48  # Generic LL parsing combinators
    49  class Unmatched:
    50      pass
    51  
    52  unmatched = Unmatched()
    53  
    54  def llrule(loc, expected, cases=1):
    55      if loc is None:
    56          def decorator(rule):
    57              rule.expected = expected
    58              return rule
    59      else:
    60          def decorator(inner_rule):
    61              if cases == 1:
    62                  def rule(*args, **kwargs):
    63                      result = inner_rule(*args, **kwargs)
    64                      if result is not unmatched:
    65                          rule.covered[0] = True
    66                      return result
    67              else:
    68                  rule = inner_rule
    69  
    70              rule.loc, rule.expected, rule.covered = \
    71                  loc, expected, [False] * cases
    72              _all_rules.append(rule)
    73  
    74              return rule
    75      return decorator
    76  
    77  def action(inner_rule, loc=None):
    78      """
    79      A decorator returning a function that first runs ``inner_rule`` and then, if its
    80      return value is not None, maps that value using ``mapper``.
    81  
    82      If the value being mapped is a tuple, it is expanded into multiple arguments.
    83  
    84      Similar to attaching semantic actions to rules in traditional parser generators.
    85      """
    86      def decorator(mapper):
    87          @llrule(loc, inner_rule.expected)
    88          def outer_rule(parser):
    89              result = inner_rule(parser)
    90              if result is unmatched:
    91                  return result
    92              if isinstance(result, tuple):
    93                  return mapper(parser, *result)
    94              else:
    95                  return mapper(parser, result)
    96          return outer_rule
    97      return decorator
    98  
    99  def Eps(value=None, loc=None):
   100      """A rule that accepts no tokens (epsilon) and returns ``value``."""
   101      @llrule(loc, lambda parser: [])
   102      def rule(parser):
   103          return value
   104      return rule
   105  
   106  def Tok(kind, loc=None):
   107      """A rule that accepts a token of kind ``kind`` and returns it, or returns None."""
   108      @llrule(loc, lambda parser: [kind])
   109      def rule(parser):
   110          return parser._accept(kind)
   111      return rule
   112  
   113  def Loc(kind, loc=None):
   114      """A rule that accepts a token of kind ``kind`` and returns its location, or returns None."""
   115      @llrule(loc, lambda parser: [kind])
   116      def rule(parser):
   117          result = parser._accept(kind)
   118          if result is unmatched:
   119              return result
   120          return result.loc
   121      return rule
   122  
   123  def Rule(name, loc=None):
   124      """A proxy for a rule called ``name`` which may not be yet defined."""
   125      @llrule(loc, lambda parser: getattr(parser, name).expected(parser))
   126      def rule(parser):
   127          return getattr(parser, name)()
   128      return rule
   129  
   130  def Expect(inner_rule, loc=None):
   131      """A rule that executes ``inner_rule`` and emits a diagnostic error if it returns None."""
   132      @llrule(loc, inner_rule.expected)
   133      def rule(parser):
   134          result = inner_rule(parser)
   135          if result is unmatched:
   136              expected = reduce(list.__add__, [rule.expected(parser) for rule in parser._errrules])
   137              expected = list(sorted(set(expected)))
   138  
   139              if len(expected) > 1:
   140                  expected = " or ".join([", ".join(expected[0:-1]), expected[-1]])
   141              elif len(expected) == 1:
   142                  expected = expected[0]
   143              else:
   144                  expected = "(impossible)"
   145  
   146              error_tok = parser._tokens[parser._errindex]
   147              error = diagnostic.Diagnostic(
   148                  "fatal", "unexpected {actual}: expected {expected}",
   149                  {"actual": error_tok.kind, "expected": expected},
   150                  error_tok.loc)
   151              parser.diagnostic_engine.process(error)
   152          return result
   153      return rule
   154  
   155  def Seq(first_rule, *rest_of_rules, **kwargs):
   156      """
   157      A rule that accepts a sequence of tokens satisfying ``rules`` and returns a tuple
   158      containing their return values, or None if the first rule was not satisfied.
   159      """
   160      @llrule(kwargs.get("loc", None), first_rule.expected)
   161      def rule(parser):
   162          result = first_rule(parser)
   163          if result is unmatched:
   164              return result
   165  
   166          results = [result]
   167          for rule in rest_of_rules:
   168              result = rule(parser)
   169              if result is unmatched:
   170                  return result
   171              results.append(result)
   172          return tuple(results)
   173      return rule
   174  
   175  def SeqN(n, *inner_rules, **kwargs):
   176      """
   177      A rule that accepts a sequence of tokens satisfying ``rules`` and returns
   178      the value returned by rule number ``n``, or None if the first rule was not satisfied.
   179      """
   180      @action(Seq(*inner_rules), loc=kwargs.get("loc", None))
   181      def rule(parser, *values):
   182          return values[n]
   183      return rule
   184  
   185  def Alt(*inner_rules, **kwargs):
   186      """
   187      A rule that expects a sequence of tokens satisfying one of ``rules`` in sequence
   188      (a rule is satisfied when it returns anything but None) and returns the return
   189      value of that rule, or None if no rules were satisfied.
   190      """
   191      loc = kwargs.get("loc", None)
   192      expected = lambda parser: reduce(list.__add__, map(lambda x: x.expected(parser), inner_rules))
   193      if loc is not None:
   194          @llrule(loc, expected, cases=len(inner_rules))
   195          def rule(parser):
   196              data = parser._save()
   197              for idx, inner_rule in enumerate(inner_rules):
   198                  result = inner_rule(parser)
   199                  if result is unmatched:
   200                      parser._restore(data, rule=inner_rule)
   201                  else:
   202                      rule.covered[idx] = True
   203                      return result
   204              return unmatched
   205      else:
   206          @llrule(loc, expected, cases=len(inner_rules))
   207          def rule(parser):
   208              data = parser._save()
   209              for inner_rule in inner_rules:
   210                  result = inner_rule(parser)
   211                  if result is unmatched:
   212                      parser._restore(data, rule=inner_rule)
   213                  else:
   214                      return result
   215              return unmatched
   216      return rule
   217  
   218  def Opt(inner_rule, loc=None):
   219      """Shorthand for ``Alt(inner_rule, Eps())``"""
   220      return Alt(inner_rule, Eps(), loc=loc)
   221  
   222  def Star(inner_rule, loc=None):
   223      """
   224      A rule that accepts a sequence of tokens satisfying ``inner_rule`` zero or more times,
   225      and returns the returned values in a :class:`list`.
   226      """
   227      @llrule(loc, lambda parser: [])
   228      def rule(parser):
   229          results = []
   230          while True:
   231              data = parser._save()
   232              result = inner_rule(parser)
   233              if result is unmatched:
   234                  parser._restore(data, rule=inner_rule)
   235                  return results
   236              results.append(result)
   237      return rule
   238  
   239  def Plus(inner_rule, loc=None):
   240      """
   241      A rule that accepts a sequence of tokens satisfying ``inner_rule`` one or more times,
   242      and returns the returned values in a :class:`list`.
   243      """
   244      @llrule(loc, inner_rule.expected)
   245      def rule(parser):
   246          result = inner_rule(parser)
   247          if result is unmatched:
   248              return result
   249  
   250          results = [result]
   251          while True:
   252              data = parser._save()
   253              result = inner_rule(parser)
   254              if result is unmatched:
   255                  parser._restore(data, rule=inner_rule)
   256                  return results
   257              results.append(result)
   258      return rule
   259  
   260  class commalist(list):
   261      __slots__ = ("trailing_comma",)
   262  
   263  def List(inner_rule, separator_tok, trailing, leading=True, loc=None):
   264      if not trailing:
   265          @action(Seq(inner_rule, Star(SeqN(1, Tok(separator_tok), inner_rule))), loc=loc)
   266          def outer_rule(parser, first, rest):
   267              return [first] + rest
   268          return outer_rule
   269      else:
   270          # A rule like this: stmt (';' stmt)* [';']
   271          # This doesn't yield itself to combinators above, because disambiguating
   272          # another iteration of the Kleene star and the trailing separator
   273          # requires two lookahead tokens (naively).
   274          separator_rule = Tok(separator_tok)
   275          @llrule(loc, inner_rule.expected)
   276          def rule(parser):
   277              results = commalist()
   278  
   279              if leading:
   280                  result = inner_rule(parser)
   281                  if result is unmatched:
   282                      return result
   283                  else:
   284                      results.append(result)
   285  
   286              while True:
   287                  result = separator_rule(parser)
   288                  if result is unmatched:
   289                      results.trailing_comma = None
   290                      return results
   291  
   292                  result_1 = inner_rule(parser)
   293                  if result_1 is unmatched:
   294                      results.trailing_comma = result
   295                      return results
   296                  else:
   297                      results.append(result_1)
   298          return rule
   299  
   300  # Python AST specific parser combinators
   301  def Newline(loc=None):
   302      """A rule that accepts token of kind ``newline`` and returns an empty list."""
   303      @llrule(loc, lambda parser: ["newline"])
   304      def rule(parser):
   305          result = parser._accept("newline")
   306          if result is unmatched:
   307              return result
   308          return []
   309      return rule
   310  
   311  def Oper(klass, *kinds, **kwargs):
   312      """
   313      A rule that accepts a sequence of tokens of kinds ``kinds`` and returns
   314      an instance of ``klass`` with ``loc`` encompassing the entire sequence
   315      or None if the first token is not of ``kinds[0]``.
   316      """
   317      @action(Seq(*map(Loc, kinds)), loc=kwargs.get("loc", None))
   318      def rule(parser, *tokens):
   319          return klass(loc=tokens[0].join(tokens[-1]))
   320      return rule
   321  
   322  def BinOper(expr_rulename, op_rule, node=ast.BinOp, loc=None):
   323      @action(Seq(Rule(expr_rulename), Star(Seq(op_rule, Rule(expr_rulename)))), loc=loc)
   324      def rule(parser, lhs, trailers):
   325          for (op, rhs) in trailers:
   326              lhs = node(left=lhs, op=op, right=rhs,
   327                         loc=lhs.loc.join(rhs.loc))
   328          return lhs
   329      return rule
   330  
   331  def BeginEnd(begin_tok, inner_rule, end_tok, empty=None, loc=None):
   332      @action(Seq(Loc(begin_tok), inner_rule, Loc(end_tok)), loc=loc)
   333      def rule(parser, begin_loc, node, end_loc):
   334          if node is None:
   335              node = empty(parser)
   336  
   337          # Collection nodes don't have loc yet. If a node has loc at this
   338          # point, it means it's an expression passed in parentheses.
   339          if node.loc is None and type(node) in [
   340                  ast.List, ast.ListComp,
   341                  ast.Dict, ast.DictComp,
   342                  ast.Set, ast.SetComp,
   343                  ast.GeneratorExp,
   344                  ast.Tuple, ast.Repr,
   345                  ast.Call, ast.Subscript,
   346                  ast.arguments]:
   347              node.begin_loc, node.end_loc, node.loc = \
   348                  begin_loc, end_loc, begin_loc.join(end_loc)
   349          return node
   350      return rule
   351  
   352  class Parser:
   353  
   354      # Generic LL parsing methods
   355      def __init__(self, lexer, version, diagnostic_engine):
   356          self._init_version(version)
   357          self.diagnostic_engine = diagnostic_engine
   358  
   359          self.lexer     = lexer
   360          self._tokens   = []
   361          self._index    = -1
   362          self._errindex = -1
   363          self._errrules = []
   364          self._advance()
   365  
   366      def _save(self):
   367          return self._index
   368  
   369      def _restore(self, data, rule):
   370          self._index = data
   371          self._token = self._tokens[self._index]
   372  
   373          if self._index > self._errindex:
   374              # We have advanced since last error
   375              self._errindex = self._index
   376              self._errrules = [rule]
   377          elif self._index == self._errindex:
   378              # We're at the same place as last error
   379              self._errrules.append(rule)
   380          else:
   381              # We've backtracked far and are now just failing the
   382              # whole parse
   383              pass
   384  
   385      def _advance(self):
   386          self._index += 1
   387          if self._index == len(self._tokens):
   388              self._tokens.append(self.lexer.next(eof_token=True))
   389          self._token = self._tokens[self._index]
   390  
   391      def _accept(self, expected_kind):
   392          if self._token.kind == expected_kind:
   393              result = self._token
   394              self._advance()
   395              return result
   396          return unmatched
   397  
   398      # Python-specific methods
   399      def _init_version(self, version):
   400          if version in ((2, 6), (2, 7)):
   401              if version == (2, 6):
   402                  self.with_stmt       = self.with_stmt__26
   403                  self.atom_6          = self.atom_6__26
   404              else:
   405                  self.with_stmt       = self.with_stmt__27
   406                  self.atom_6          = self.atom_6__27
   407              self.except_clause_1 = self.except_clause_1__26
   408              self.classdef        = self.classdef__26
   409              self.subscript       = self.subscript__26
   410              self.raise_stmt      = self.raise_stmt__26
   411              self.comp_if         = self.comp_if__26
   412              self.atom            = self.atom__26
   413              self.funcdef         = self.funcdef__26
   414              self.parameters      = self.parameters__26
   415              self.varargslist     = self.varargslist__26
   416              self.comparison_1    = self.comparison_1__26
   417              self.exprlist_1      = self.exprlist_1__26
   418              self.testlist_comp_1 = self.testlist_comp_1__26
   419              self.expr_stmt_1     = self.expr_stmt_1__26
   420              self.yield_expr      = self.yield_expr__26
   421              return
   422          elif version in ((3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5)):
   423              if version == (3, 0):
   424                  self.with_stmt       = self.with_stmt__26 # lol
   425              else:
   426                  self.with_stmt       = self.with_stmt__27
   427              self.except_clause_1 = self.except_clause_1__30
   428              self.classdef        = self.classdef__30
   429              self.subscript       = self.subscript__30
   430              self.raise_stmt      = self.raise_stmt__30
   431              self.comp_if         = self.comp_if__30
   432              self.atom            = self.atom__30
   433              self.funcdef         = self.funcdef__30
   434              self.parameters      = self.parameters__30
   435              if version < (3, 2):
   436                  self.varargslist     = self.varargslist__30
   437                  self.typedargslist   = self.typedargslist__30
   438                  self.comparison_1    = self.comparison_1__30
   439                  self.star_expr       = self.star_expr__30
   440                  self.exprlist_1      = self.exprlist_1__30
   441                  self.testlist_comp_1 = self.testlist_comp_1__26
   442                  self.expr_stmt_1     = self.expr_stmt_1__26
   443              else:
   444                  self.varargslist     = self.varargslist__32
   445                  self.typedargslist   = self.typedargslist__32
   446                  self.comparison_1    = self.comparison_1__32
   447                  self.star_expr       = self.star_expr__32
   448                  self.exprlist_1      = self.exprlist_1__32
   449                  self.testlist_comp_1 = self.testlist_comp_1__32
   450                  self.expr_stmt_1     = self.expr_stmt_1__32
   451              if version < (3, 3):
   452                  self.yield_expr      = self.yield_expr__26
   453              else:
   454                  self.yield_expr      = self.yield_expr__33
   455              return
   456  
   457          raise NotImplementedError("pythonparser.parser.Parser cannot parse Python %s" %
   458                                    str(version))
   459  
   460      def _arguments(self, args=None, defaults=None, kwonlyargs=None, kw_defaults=None,
   461                     vararg=None, kwarg=None,
   462                     star_loc=None, dstar_loc=None, begin_loc=None, end_loc=None,
   463                     equals_locs=None, kw_equals_locs=None, loc=None):
   464          if args is None:
   465              args = []
   466          if defaults is None:
   467              defaults = []
   468          if kwonlyargs is None:
   469              kwonlyargs = []
   470          if kw_defaults is None:
   471              kw_defaults = []
   472          if equals_locs is None:
   473              equals_locs = []
   474          if kw_equals_locs is None:
   475              kw_equals_locs = []
   476          return ast.arguments(args=args, defaults=defaults,
   477                               kwonlyargs=kwonlyargs, kw_defaults=kw_defaults,
   478                               vararg=vararg, kwarg=kwarg,
   479                               star_loc=star_loc, dstar_loc=dstar_loc,
   480                               begin_loc=begin_loc, end_loc=end_loc,
   481                               equals_locs=equals_locs, kw_equals_locs=kw_equals_locs,
   482                               loc=loc)
   483  
   484      def _arg(self, tok, colon_loc=None, annotation=None):
   485          loc = tok.loc
   486          if annotation:
   487              loc = loc.join(annotation.loc)
   488          return ast.arg(arg=tok.value, annotation=annotation,
   489                         arg_loc=tok.loc, colon_loc=colon_loc, loc=loc)
   490  
   491      def _empty_arglist(self):
   492          return ast.Call(args=[], keywords=[], starargs=None, kwargs=None,
   493                          star_loc=None, dstar_loc=None, loc=None)
   494  
   495      def _wrap_tuple(self, elts):
   496          assert len(elts) > 0
   497          if len(elts) > 1:
   498              return ast.Tuple(ctx=None, elts=elts,
   499                               loc=elts[0].loc.join(elts[-1].loc), begin_loc=None, end_loc=None)
   500          else:
   501              return elts[0]
   502  
   503      def _assignable(self, node, is_delete=False):
   504          if isinstance(node, ast.Name) or isinstance(node, ast.Subscript) or \
   505                  isinstance(node, ast.Attribute) or isinstance(node, ast.Starred):
   506              return node
   507          elif (isinstance(node, ast.List) or isinstance(node, ast.Tuple)) and \
   508                  any(node.elts):
   509              node.elts = [self._assignable(elt, is_delete) for elt in node.elts]
   510              return node
   511          else:
   512              if is_delete:
   513                  error = diagnostic.Diagnostic(
   514                      "fatal", "cannot delete this expression", {}, node.loc)
   515              else:
   516                  error = diagnostic.Diagnostic(
   517                      "fatal", "cannot assign to this expression", {}, node.loc)
   518              self.diagnostic_engine.process(error)
   519  
   520      def add_flags(self, flags):
   521          if "print_function" in flags:
   522              self.lexer.print_function = True
   523          if "unicode_literals" in flags:
   524              self.lexer.unicode_literals = True
   525  
   526      # Grammar
   527      @action(Expect(Alt(Newline(),
   528                         Rule("simple_stmt"),
   529                         SeqN(0, Rule("compound_stmt"), Newline()))))
   530      def single_input(self, body):
   531          """single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE"""
   532          loc = None
   533          if body != []:
   534              loc = body[0].loc
   535          return ast.Interactive(body=body, loc=loc)
   536  
   537      @action(Expect(SeqN(0, Star(Alt(Newline(), Rule("stmt"))), Tok("eof"))))
   538      def file_input(parser, body):
   539          """file_input: (NEWLINE | stmt)* ENDMARKER"""
   540          body = reduce(list.__add__, body, [])
   541          loc = None
   542          if body != []:
   543              loc = body[0].loc
   544          return ast.Module(body=body, loc=loc)
   545  
   546      @action(Expect(SeqN(0, Rule("testlist"), Star(Tok("newline")), Tok("eof"))))
   547      def eval_input(self, expr):
   548          """eval_input: testlist NEWLINE* ENDMARKER"""
   549          return ast.Expression(body=[expr], loc=expr.loc)
   550  
   551      @action(Seq(Loc("@"), List(Tok("ident"), ".", trailing=False),
   552                  Opt(BeginEnd("(", Opt(Rule("arglist")), ")",
   553                               empty=_empty_arglist)),
   554                  Loc("newline")))
   555      def decorator(self, at_loc, idents, call_opt, newline_loc):
   556          """decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE"""
   557          root = idents[0]
   558          dec_loc = root.loc
   559          expr = ast.Name(id=root.value, ctx=None, loc=root.loc)
   560          for ident in idents[1:]:
   561            dot_loc = ident.loc.begin()
   562            dot_loc.begin_pos -= 1
   563            dec_loc = dec_loc.join(ident.loc)
   564            expr = ast.Attribute(value=expr, attr=ident.value, ctx=None,
   565                                 loc=expr.loc.join(ident.loc),
   566                                 attr_loc=ident.loc, dot_loc=dot_loc)
   567  
   568          if call_opt:
   569              call_opt.func = expr
   570              call_opt.loc = dec_loc.join(call_opt.loc)
   571              expr = call_opt
   572          return at_loc, expr
   573  
   574      decorators = Plus(Rule("decorator"))
   575      """decorators: decorator+"""
   576  
   577      @action(Seq(Rule("decorators"), Alt(Rule("classdef"), Rule("funcdef"))))
   578      def decorated(self, decorators, classfuncdef):
   579          """decorated: decorators (classdef | funcdef)"""
   580          classfuncdef.at_locs = list(map(lambda x: x[0], decorators))
   581          classfuncdef.decorator_list = list(map(lambda x: x[1], decorators))
   582          classfuncdef.loc = classfuncdef.loc.join(decorators[0][0])
   583          return classfuncdef
   584  
   585      @action(Seq(Loc("def"), Tok("ident"), Rule("parameters"), Loc(":"), Rule("suite")))
   586      def funcdef__26(self, def_loc, ident_tok, args, colon_loc, suite):
   587          """(2.6, 2.7) funcdef: 'def' NAME parameters ':' suite"""
   588          return ast.FunctionDef(name=ident_tok.value, args=args, returns=None,
   589                                 body=suite, decorator_list=[],
   590                                 at_locs=[], keyword_loc=def_loc, name_loc=ident_tok.loc,
   591                                 colon_loc=colon_loc, arrow_loc=None,
   592                                 loc=def_loc.join(suite[-1].loc))
   593  
   594      @action(Seq(Loc("def"), Tok("ident"), Rule("parameters"),
   595                  Opt(Seq(Loc("->"), Rule("test"))),
   596                  Loc(":"), Rule("suite")))
   597      def funcdef__30(self, def_loc, ident_tok, args, returns_opt, colon_loc, suite):
   598          """(3.0-) funcdef: 'def' NAME parameters ['->' test] ':' suite"""
   599          arrow_loc = returns = None
   600          if returns_opt:
   601              arrow_loc, returns = returns_opt
   602          return ast.FunctionDef(name=ident_tok.value, args=args, returns=returns,
   603                                 body=suite, decorator_list=[],
   604                                 at_locs=[], keyword_loc=def_loc, name_loc=ident_tok.loc,
   605                                 colon_loc=colon_loc, arrow_loc=arrow_loc,
   606                                 loc=def_loc.join(suite[-1].loc))
   607  
   608      parameters__26 = BeginEnd("(", Opt(Rule("varargslist")), ")", empty=_arguments)
   609      """(2.6, 2.7) parameters: '(' [varargslist] ')'"""
   610  
   611      parameters__30 = BeginEnd("(", Opt(Rule("typedargslist")), ")", empty=_arguments)
   612      """(3.0) parameters: '(' [typedargslist] ')'"""
   613  
   614      varargslist__26_1 = Seq(Rule("fpdef"), Opt(Seq(Loc("="), Rule("test"))))
   615  
   616      @action(Seq(Loc("**"), Tok("ident")))
   617      def varargslist__26_2(self, dstar_loc, kwarg_tok):
   618          return self._arguments(kwarg=self._arg(kwarg_tok),
   619                                 dstar_loc=dstar_loc, loc=dstar_loc.join(kwarg_tok.loc))
   620  
   621      @action(Seq(Loc("*"), Tok("ident"),
   622                  Opt(Seq(Tok(","), Loc("**"), Tok("ident")))))
   623      def varargslist__26_3(self, star_loc, vararg_tok, kwarg_opt):
   624          dstar_loc = kwarg = None
   625          loc = star_loc.join(vararg_tok.loc)
   626          vararg = self._arg(vararg_tok)
   627          if kwarg_opt:
   628              _, dstar_loc, kwarg_tok = kwarg_opt
   629              kwarg = self._arg(kwarg_tok)
   630              loc = star_loc.join(kwarg_tok.loc)
   631          return self._arguments(vararg=vararg, kwarg=kwarg,
   632                                 star_loc=star_loc, dstar_loc=dstar_loc, loc=loc)
   633  
   634      @action(Eps(value=()))
   635      def varargslist__26_4(self):
   636          return self._arguments()
   637  
   638      @action(Alt(Seq(Star(SeqN(0, varargslist__26_1, Tok(","))),
   639                      Alt(varargslist__26_2, varargslist__26_3)),
   640                  Seq(List(varargslist__26_1, ",", trailing=True),
   641                      varargslist__26_4)))
   642      def varargslist__26(self, fparams, args):
   643          """
   644          (2.6, 2.7)
   645          varargslist: ((fpdef ['=' test] ',')*
   646                        ('*' NAME [',' '**' NAME] | '**' NAME) |
   647                        fpdef ['=' test] (',' fpdef ['=' test])* [','])
   648          """
   649          for fparam, default_opt in fparams:
   650              if default_opt:
   651                  equals_loc, default = default_opt
   652                  args.equals_locs.append(equals_loc)
   653                  args.defaults.append(default)
   654              elif len(args.defaults) > 0:
   655                  error = diagnostic.Diagnostic(
   656                      "fatal", "non-default argument follows default argument", {},
   657                      fparam.loc, [args.args[-1].loc.join(args.defaults[-1].loc)])
   658                  self.diagnostic_engine.process(error)
   659  
   660              args.args.append(fparam)
   661  
   662          def fparam_loc(fparam, default_opt):
   663              if default_opt:
   664                  equals_loc, default = default_opt
   665                  return fparam.loc.join(default.loc)
   666              else:
   667                  return fparam.loc
   668  
   669          if args.loc is None:
   670              args.loc = fparam_loc(*fparams[0]).join(fparam_loc(*fparams[-1]))
   671          elif len(fparams) > 0:
   672              args.loc = args.loc.join(fparam_loc(*fparams[0]))
   673  
   674          return args
   675  
   676      @action(Tok("ident"))
   677      def fpdef_1(self, ident_tok):
   678          return ast.arg(arg=ident_tok.value, annotation=None,
   679                         arg_loc=ident_tok.loc, colon_loc=None,
   680                         loc=ident_tok.loc)
   681  
   682      fpdef = Alt(fpdef_1, BeginEnd("(", Rule("fplist"), ")",
   683                                    empty=lambda self: ast.Tuple(elts=[], ctx=None, loc=None)))
   684      """fpdef: NAME | '(' fplist ')'"""
   685  
   686      def _argslist(fpdef_rule, old_style=False):
   687          argslist_1 = Seq(fpdef_rule, Opt(Seq(Loc("="), Rule("test"))))
   688  
   689          @action(Seq(Loc("**"), Tok("ident")))
   690          def argslist_2(self, dstar_loc, kwarg_tok):
   691              return self._arguments(kwarg=self._arg(kwarg_tok),
   692                                     dstar_loc=dstar_loc, loc=dstar_loc.join(kwarg_tok.loc))
   693  
   694          @action(Seq(Loc("*"), Tok("ident"),
   695                      Star(SeqN(1, Tok(","), argslist_1)),
   696                      Opt(Seq(Tok(","), Loc("**"), Tok("ident")))))
   697          def argslist_3(self, star_loc, vararg_tok, fparams, kwarg_opt):
   698              dstar_loc = kwarg = None
   699              loc = star_loc.join(vararg_tok.loc)
   700              vararg = self._arg(vararg_tok)
   701              if kwarg_opt:
   702                  _, dstar_loc, kwarg_tok = kwarg_opt
   703                  kwarg = self._arg(kwarg_tok)
   704                  loc = star_loc.join(kwarg_tok.loc)
   705              kwonlyargs, kw_defaults, kw_equals_locs = [], [], []
   706              for fparam, default_opt in fparams:
   707                  if default_opt:
   708                      equals_loc, default = default_opt
   709                      kw_equals_locs.append(equals_loc)
   710                      kw_defaults.append(default)
   711                  else:
   712                      kw_defaults.append(None)
   713                  kwonlyargs.append(fparam)
   714              if any(kw_defaults):
   715                  loc = loc.join(kw_defaults[-1].loc)
   716              elif any(kwonlyargs):
   717                  loc = loc.join(kwonlyargs[-1].loc)
   718              return self._arguments(vararg=vararg, kwarg=kwarg,
   719                                     kwonlyargs=kwonlyargs, kw_defaults=kw_defaults,
   720                                     star_loc=star_loc, dstar_loc=dstar_loc,
   721                                     kw_equals_locs=kw_equals_locs, loc=loc)
   722  
   723          argslist_4 = Alt(argslist_2, argslist_3)
   724  
   725          @action(Eps(value=()))
   726          def argslist_5(self):
   727              return self._arguments()
   728  
   729          if old_style:
   730              argslist = Alt(Seq(Star(SeqN(0, argslist_1, Tok(","))),
   731                                 argslist_4),
   732                             Seq(List(argslist_1, ",", trailing=True),
   733                                 argslist_5))
   734          else:
   735              argslist = Alt(Seq(Eps(value=[]), argslist_4),
   736                             Seq(List(argslist_1, ",", trailing=False),
   737                                 Alt(SeqN(1, Tok(","), Alt(argslist_4, argslist_5)),
   738                                     argslist_5)))
   739  
   740          def argslist_action(self, fparams, args):
   741              for fparam, default_opt in fparams:
   742                  if default_opt:
   743                      equals_loc, default = default_opt
   744                      args.equals_locs.append(equals_loc)
   745                      args.defaults.append(default)
   746                  elif len(args.defaults) > 0:
   747                      error = diagnostic.Diagnostic(
   748                          "fatal", "non-default argument follows default argument", {},
   749                          fparam.loc, [args.args[-1].loc.join(args.defaults[-1].loc)])
   750                      self.diagnostic_engine.process(error)
   751  
   752                  args.args.append(fparam)
   753  
   754              def fparam_loc(fparam, default_opt):
   755                  if default_opt:
   756                      equals_loc, default = default_opt
   757                      return fparam.loc.join(default.loc)
   758                  else:
   759                      return fparam.loc
   760  
   761              if args.loc is None:
   762                  args.loc = fparam_loc(*fparams[0]).join(fparam_loc(*fparams[-1]))
   763              elif len(fparams) > 0:
   764                  args.loc = args.loc.join(fparam_loc(*fparams[0]))
   765  
   766              return args
   767  
   768          return action(argslist)(argslist_action)
   769  
   770      typedargslist__30 = _argslist(Rule("tfpdef"), old_style=True)
   771      """
   772      (3.0, 3.1)
   773      typedargslist: ((tfpdef ['=' test] ',')*
   774                      ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef)
   775                      | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
   776      """
   777  
   778      typedargslist__32 = _argslist(Rule("tfpdef"))
   779      """
   780      (3.2-)
   781      typedargslist: (tfpdef ['=' test] (',' tfpdef ['=' test])* [','
   782             ['*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef]]
   783           |  '*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef)
   784      """
   785  
   786      varargslist__30 = _argslist(Rule("vfpdef"), old_style=True)
   787      """
   788      (3.0, 3.1)
   789      varargslist: ((vfpdef ['=' test] ',')*
   790                    ('*' [vfpdef] (',' vfpdef ['=' test])*  [',' '**' vfpdef] | '**' vfpdef)
   791                    | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
   792      """
   793  
   794      varargslist__32 = _argslist(Rule("vfpdef"))
   795      """
   796      (3.2-)
   797      varargslist: (vfpdef ['=' test] (',' vfpdef ['=' test])* [','
   798             ['*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef]]
   799           |  '*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef)
   800      """
   801  
   802      @action(Seq(Tok("ident"), Opt(Seq(Loc(":"), Rule("test")))))
   803      def tfpdef(self, ident_tok, annotation_opt):
   804          """(3.0-) tfpdef: NAME [':' test]"""
   805          if annotation_opt:
   806              colon_loc, annotation = annotation_opt
   807              return self._arg(ident_tok, colon_loc, annotation)
   808          return self._arg(ident_tok)
   809  
   810      vfpdef = fpdef_1
   811      """(3.0-) vfpdef: NAME"""
   812  
   813      @action(List(Rule("fpdef"), ",", trailing=True))
   814      def fplist(self, elts):
   815          """fplist: fpdef (',' fpdef)* [',']"""
   816          return ast.Tuple(elts=elts, ctx=None, loc=None)
   817  
   818      stmt = Alt(Rule("simple_stmt"), Rule("compound_stmt"))
   819      """stmt: simple_stmt | compound_stmt"""
   820  
   821      simple_stmt = SeqN(0, List(Rule("small_stmt"), ";", trailing=True), Tok("newline"))
   822      """simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE"""
   823  
   824      small_stmt = Alt(Rule("expr_stmt"), Rule("print_stmt"),  Rule("del_stmt"),
   825                       Rule("pass_stmt"), Rule("flow_stmt"), Rule("import_stmt"),
   826                       Rule("global_stmt"), Rule("nonlocal_stmt"), Rule("exec_stmt"),
   827                       Rule("assert_stmt"))
   828      """
   829      (2.6, 2.7)
   830      small_stmt: (expr_stmt | print_stmt  | del_stmt | pass_stmt | flow_stmt |
   831                   import_stmt | global_stmt | exec_stmt | assert_stmt)
   832      (3.0-)
   833      small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
   834                   import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
   835      """
   836  
   837      expr_stmt_1__26 = Rule("testlist")
   838      expr_stmt_1__32 = Rule("testlist_star_expr")
   839  
   840      @action(Seq(Rule("augassign"), Alt(Rule("yield_expr"), Rule("testlist"))))
   841      def expr_stmt_2(self, augassign, rhs_expr):
   842          return ast.AugAssign(op=augassign, value=rhs_expr)
   843  
   844      @action(Star(Seq(Loc("="), Alt(Rule("yield_expr"), Rule("expr_stmt_1")))))
   845      def expr_stmt_3(self, seq):
   846          if len(seq) > 0:
   847              return ast.Assign(targets=list(map(lambda x: x[1], seq[:-1])), value=seq[-1][1],
   848                                op_locs=list(map(lambda x: x[0], seq)))
   849          else:
   850              return None
   851  
   852      @action(Seq(Rule("expr_stmt_1"), Alt(expr_stmt_2, expr_stmt_3)))
   853      def expr_stmt(self, lhs, rhs):
   854          """
   855          (2.6, 2.7, 3.0, 3.1)
   856          expr_stmt: testlist (augassign (yield_expr|testlist) |
   857                               ('=' (yield_expr|testlist))*)
   858          (3.2-)
   859          expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
   860                               ('=' (yield_expr|testlist_star_expr))*)
   861          """
   862          if isinstance(rhs, ast.AugAssign):
   863              if isinstance(lhs, ast.Tuple) or isinstance(lhs, ast.List):
   864                  error = diagnostic.Diagnostic(
   865                      "fatal", "illegal expression for augmented assignment", {},
   866                      rhs.op.loc, [lhs.loc])
   867                  self.diagnostic_engine.process(error)
   868              else:
   869                  rhs.target = self._assignable(lhs)
   870                  rhs.loc = rhs.target.loc.join(rhs.value.loc)
   871                  return rhs
   872          elif rhs is not None:
   873              rhs.targets = list(map(self._assignable, [lhs] + rhs.targets))
   874              rhs.loc = lhs.loc.join(rhs.value.loc)
   875              return rhs
   876          else:
   877              return ast.Expr(value=lhs, loc=lhs.loc)
   878  
   879      testlist_star_expr = action(
   880          List(Alt(Rule("test"), Rule("star_expr")), ",", trailing=True)) \
   881          (_wrap_tuple)
   882      """(3.2-) testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']"""
   883  
   884      augassign = Alt(Oper(ast.Add, "+="), Oper(ast.Sub, "-="), Oper(ast.MatMult, "@="),
   885                      Oper(ast.Mult, "*="), Oper(ast.Div, "/="), Oper(ast.Mod, "%="),
   886                      Oper(ast.BitAnd, "&="), Oper(ast.BitOr, "|="), Oper(ast.BitXor, "^="),
   887                      Oper(ast.LShift, "<<="), Oper(ast.RShift, ">>="),
   888                      Oper(ast.Pow, "**="), Oper(ast.FloorDiv, "//="))
   889      """augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' |
   890                     '<<=' | '>>=' | '**=' | '//=')"""
   891  
   892      @action(List(Rule("test"), ",", trailing=True))
   893      def print_stmt_1(self, values):
   894          nl, loc = True, values[-1].loc
   895          if values.trailing_comma:
   896              nl, loc = False, values.trailing_comma.loc
   897          return ast.Print(dest=None, values=values, nl=nl,
   898                           dest_loc=None, loc=loc)
   899  
   900      @action(Seq(Loc(">>"), Rule("test"), Tok(","), List(Rule("test"), ",", trailing=True)))
   901      def print_stmt_2(self, dest_loc, dest, comma_tok, values):
   902          nl, loc = True, values[-1].loc
   903          if values.trailing_comma:
   904              nl, loc = False, values.trailing_comma.loc
   905          return ast.Print(dest=dest, values=values, nl=nl,
   906                           dest_loc=dest_loc, loc=loc)
   907  
   908      @action(Eps())
   909      def print_stmt_3(self, eps):
   910          return ast.Print(dest=None, values=[], nl=True,
   911                           dest_loc=None, loc=None)
   912  
   913      @action(Seq(Loc("print"), Alt(print_stmt_1, print_stmt_2, print_stmt_3)))
   914      def print_stmt(self, print_loc, stmt):
   915          """
   916          (2.6-2.7)
   917          print_stmt: 'print' ( [ test (',' test)* [','] ] |
   918                                '>>' test [ (',' test)+ [','] ] )
   919          """
   920          stmt.keyword_loc = print_loc
   921          if stmt.loc is None:
   922              stmt.loc = print_loc
   923          else:
   924              stmt.loc = print_loc.join(stmt.loc)
   925          return stmt
   926  
   927      @action(Seq(Loc("del"), List(Rule("expr"), ",", trailing=True)))
   928      def del_stmt(self, stmt_loc, exprs):
   929          # Python uses exprlist here, but does *not* obey the usual
   930          # tuple-wrapping semantics, so we embed the rule directly.
   931          """del_stmt: 'del' exprlist"""
   932          return ast.Delete(targets=[self._assignable(expr, is_delete=True) for expr in exprs],
   933                            loc=stmt_loc.join(exprs[-1].loc), keyword_loc=stmt_loc)
   934  
   935      @action(Loc("pass"))
   936      def pass_stmt(self, stmt_loc):
   937          """pass_stmt: 'pass'"""
   938          return ast.Pass(loc=stmt_loc, keyword_loc=stmt_loc)
   939  
   940      flow_stmt = Alt(Rule("break_stmt"), Rule("continue_stmt"), Rule("return_stmt"),
   941                      Rule("raise_stmt"), Rule("yield_stmt"))
   942      """flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt"""
   943  
   944      @action(Loc("break"))
   945      def break_stmt(self, stmt_loc):
   946          """break_stmt: 'break'"""
   947          return ast.Break(loc=stmt_loc, keyword_loc=stmt_loc)
   948  
   949      @action(Loc("continue"))
   950      def continue_stmt(self, stmt_loc):
   951          """continue_stmt: 'continue'"""
   952          return ast.Continue(loc=stmt_loc, keyword_loc=stmt_loc)
   953  
   954      @action(Seq(Loc("return"), Opt(Rule("testlist"))))
   955      def return_stmt(self, stmt_loc, values):
   956          """return_stmt: 'return' [testlist]"""
   957          loc = stmt_loc
   958          if values:
   959              loc = loc.join(values.loc)
   960          return ast.Return(value=values,
   961                            loc=loc, keyword_loc=stmt_loc)
   962  
   963      @action(Rule("yield_expr"))
   964      def yield_stmt(self, expr):
   965          """yield_stmt: yield_expr"""
   966          return ast.Expr(value=expr, loc=expr.loc)
   967  
   968      @action(Seq(Loc("raise"), Opt(Seq(Rule("test"),
   969                                        Opt(Seq(Tok(","), Rule("test"),
   970                                                Opt(SeqN(1, Tok(","), Rule("test")))))))))
   971      def raise_stmt__26(self, raise_loc, type_opt):
   972          """(2.6, 2.7) raise_stmt: 'raise' [test [',' test [',' test]]]"""
   973          type_ = inst = tback = None
   974          loc = raise_loc
   975          if type_opt:
   976              type_, inst_opt = type_opt
   977              loc = loc.join(type_.loc)
   978              if inst_opt:
   979                  _, inst, tback = inst_opt
   980                  loc = loc.join(inst.loc)
   981                  if tback:
   982                      loc = loc.join(tback.loc)
   983          return ast.Raise(exc=type_, inst=inst, tback=tback, cause=None,
   984                           keyword_loc=raise_loc, from_loc=None, loc=loc)
   985  
   986      @action(Seq(Loc("raise"), Opt(Seq(Rule("test"), Opt(Seq(Loc("from"), Rule("test")))))))
   987      def raise_stmt__30(self, raise_loc, exc_opt):
   988          """(3.0-) raise_stmt: 'raise' [test ['from' test]]"""
   989          exc = from_loc = cause = None
   990          loc = raise_loc
   991          if exc_opt:
   992              exc, cause_opt = exc_opt
   993              loc = loc.join(exc.loc)
   994              if cause_opt:
   995                  from_loc, cause = cause_opt
   996                  loc = loc.join(cause.loc)
   997          return ast.Raise(exc=exc, inst=None, tback=None, cause=cause,
   998                           keyword_loc=raise_loc, from_loc=from_loc, loc=loc)
   999  
  1000      import_stmt = Alt(Rule("import_name"), Rule("import_from"))
  1001      """import_stmt: import_name | import_from"""
  1002  
  1003      @action(Seq(Loc("import"), Rule("dotted_as_names")))
  1004      def import_name(self, import_loc, names):
  1005          """import_name: 'import' dotted_as_names"""
  1006          return ast.Import(names=names,
  1007                            keyword_loc=import_loc, loc=import_loc.join(names[-1].loc))
  1008  
  1009      @action(Loc("."))
  1010      def import_from_1(self, loc):
  1011          return 1, loc
  1012  
  1013      @action(Loc("..."))
  1014      def import_from_2(self, loc):
  1015          return 3, loc
  1016  
  1017      @action(Seq(Star(Alt(import_from_1, import_from_2)), Rule("dotted_name")))
  1018      def import_from_3(self, dots, dotted_name):
  1019          dots_loc, dots_count = None, 0
  1020          if any(dots):
  1021              dots_loc = dots[0][1].join(dots[-1][1])
  1022              dots_count = sum([count for count, loc in dots])
  1023          return (dots_loc, dots_count), dotted_name
  1024  
  1025      @action(Plus(Alt(import_from_1, import_from_2)))
  1026      def import_from_4(self, dots):
  1027          dots_loc = dots[0][1].join(dots[-1][1])
  1028          dots_count = sum([count for count, loc in dots])
  1029          return (dots_loc, dots_count), None
  1030  
  1031      @action(Loc("*"))
  1032      def import_from_5(self, star_loc):
  1033          return (None, 0), \
  1034                 [ast.alias(name="*", asname=None,
  1035                            name_loc=star_loc, as_loc=None, asname_loc=None, loc=star_loc)], \
  1036                 None
  1037  
  1038      @action(Rule("atom_5"))
  1039      def import_from_7(self, string):
  1040          return (None, 0), (string.loc, string.s)
  1041  
  1042      @action(Rule("import_as_names"))
  1043      def import_from_6(self, names):
  1044          return (None, 0), names, None
  1045  
  1046      @action(Seq(Loc("from"), Alt(import_from_3, import_from_4, import_from_7),
  1047                  Loc("import"), Alt(import_from_5,
  1048                                     Seq(Loc("("), Rule("import_as_names"), Loc(")")),
  1049                                     import_from_6)))
  1050      def import_from(self, from_loc, module_name, import_loc, names):
  1051          """
  1052          (2.6, 2.7)
  1053          import_from: ('from' ('.'* dotted_name | '.'+)
  1054                        'import' ('*' | '(' import_as_names ')' | import_as_names))
  1055          (3.0-)
  1056          # note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS
  1057          import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
  1058                        'import' ('*' | '(' import_as_names ')' | import_as_names))
  1059          """
  1060          (dots_loc, dots_count), dotted_name_opt = module_name
  1061          module_loc = module = None
  1062          if dotted_name_opt:
  1063              module_loc, module = dotted_name_opt
  1064          lparen_loc, names, rparen_loc = names
  1065          loc = from_loc.join(names[-1].loc)
  1066          if rparen_loc:
  1067              loc = loc.join(rparen_loc)
  1068  
  1069          if module == "__future__":
  1070              self.add_flags([x.name for x in names])
  1071  
  1072          return ast.ImportFrom(names=names, module=module, level=dots_count,
  1073                                keyword_loc=from_loc, dots_loc=dots_loc, module_loc=module_loc,
  1074                                import_loc=import_loc, lparen_loc=lparen_loc, rparen_loc=rparen_loc,
  1075                                loc=loc)
  1076  
  1077      @action(Seq(Tok("ident"), Opt(Seq(Loc("as"), Tok("ident")))))
  1078      def import_as_name(self, name_tok, as_name_opt):
  1079          """import_as_name: NAME ['as' NAME]"""
  1080          asname_name = asname_loc = as_loc = None
  1081          loc = name_tok.loc
  1082          if as_name_opt:
  1083              as_loc, asname = as_name_opt
  1084              asname_name = asname.value
  1085              asname_loc = asname.loc
  1086              loc = loc.join(asname.loc)
  1087          return ast.alias(name=name_tok.value, asname=asname_name,
  1088                           loc=loc, name_loc=name_tok.loc, as_loc=as_loc, asname_loc=asname_loc)
  1089  
  1090      @action(Seq(Rule("dotted_name"), Opt(Seq(Loc("as"), Tok("ident")))))
  1091      def dotted_as_name(self, dotted_name, as_name_opt):
  1092          """dotted_as_name: dotted_name ['as' NAME]"""
  1093          asname_name = asname_loc = as_loc = None
  1094          dotted_name_loc, dotted_name_name = dotted_name
  1095          loc = dotted_name_loc
  1096          if as_name_opt:
  1097              as_loc, asname = as_name_opt
  1098              asname_name = asname.value
  1099              asname_loc = asname.loc
  1100              loc = loc.join(asname.loc)
  1101          return ast.alias(name=dotted_name_name, asname=asname_name,
  1102                           loc=loc, name_loc=dotted_name_loc, as_loc=as_loc, asname_loc=asname_loc)
  1103  
  1104      @action(Seq(Rule("atom_5"), Opt(Seq(Loc("as"), Tok("ident")))))
  1105      def str_as_name(self, string, as_name_opt):
  1106          asname_name = asname_loc = as_loc = None
  1107          loc = string.loc
  1108          if as_name_opt:
  1109              as_loc, asname = as_name_opt
  1110              asname_name = asname.value
  1111              asname_loc = asname.loc
  1112              loc = loc.join(asname.loc)
  1113          return ast.alias(name=string.s, asname=asname_name,
  1114                           loc=loc, name_loc=string.loc, as_loc=as_loc, asname_loc=asname_loc)
  1115  
  1116      import_as_names = List(Rule("import_as_name"), ",", trailing=True)
  1117      """import_as_names: import_as_name (',' import_as_name)* [',']"""
  1118  
  1119      dotted_as_names = List(Alt(Rule("dotted_as_name"), Rule("str_as_name")), ",", trailing=False)
  1120      """dotted_as_names: dotted_as_name (',' dotted_as_name)*"""
  1121  
  1122      @action(List(Tok("ident"), ".", trailing=False))
  1123      def dotted_name(self, idents):
  1124          """dotted_name: NAME ('.' NAME)*"""
  1125          return idents[0].loc.join(idents[-1].loc), \
  1126                 ".".join(list(map(lambda x: x.value, idents)))
  1127  
  1128      @action(Seq(Loc("global"), List(Tok("ident"), ",", trailing=False)))
  1129      def global_stmt(self, global_loc, names):
  1130          """global_stmt: 'global' NAME (',' NAME)*"""
  1131          return ast.Global(names=list(map(lambda x: x.value, names)),
  1132                            name_locs=list(map(lambda x: x.loc, names)),
  1133                            keyword_loc=global_loc, loc=global_loc.join(names[-1].loc))
  1134  
  1135      @action(Seq(Loc("exec"), Rule("expr"),
  1136                  Opt(Seq(Loc("in"), Rule("test"),
  1137                          Opt(SeqN(1, Loc(","), Rule("test")))))))
  1138      def exec_stmt(self, exec_loc, body, in_opt):
  1139          """(2.6, 2.7) exec_stmt: 'exec' expr ['in' test [',' test]]"""
  1140          in_loc, globals, locals = None, None, None
  1141          loc = exec_loc.join(body.loc)
  1142          if in_opt:
  1143              in_loc, globals, locals = in_opt
  1144              if locals:
  1145                  loc = loc.join(locals.loc)
  1146              else:
  1147                  loc = loc.join(globals.loc)
  1148          return ast.Exec(body=body, locals=locals, globals=globals,
  1149                          loc=loc, keyword_loc=exec_loc, in_loc=in_loc)
  1150  
  1151      @action(Seq(Loc("nonlocal"), List(Tok("ident"), ",", trailing=False)))
  1152      def nonlocal_stmt(self, nonlocal_loc, names):
  1153          """(3.0-) nonlocal_stmt: 'nonlocal' NAME (',' NAME)*"""
  1154          return ast.Nonlocal(names=list(map(lambda x: x.value, names)),
  1155                              name_locs=list(map(lambda x: x.loc, names)),
  1156                              keyword_loc=nonlocal_loc, loc=nonlocal_loc.join(names[-1].loc))
  1157  
  1158      @action(Seq(Loc("assert"), Rule("test"), Opt(SeqN(1, Tok(","), Rule("test")))))
  1159      def assert_stmt(self, assert_loc, test, msg):
  1160          """assert_stmt: 'assert' test [',' test]"""
  1161          loc = assert_loc.join(test.loc)
  1162          if msg:
  1163              loc = loc.join(msg.loc)
  1164          return ast.Assert(test=test, msg=msg,
  1165                            loc=loc, keyword_loc=assert_loc)
  1166  
  1167      @action(Alt(Rule("if_stmt"), Rule("while_stmt"), Rule("for_stmt"),
  1168                  Rule("try_stmt"), Rule("with_stmt"), Rule("funcdef"),
  1169                  Rule("classdef"), Rule("decorated")))
  1170      def compound_stmt(self, stmt):
  1171          """compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt |
  1172                            funcdef | classdef | decorated"""
  1173          return [stmt]
  1174  
  1175      @action(Seq(Loc("if"), Rule("test"), Loc(":"), Rule("suite"),
  1176                  Star(Seq(Loc("elif"), Rule("test"), Loc(":"), Rule("suite"))),
  1177                  Opt(Seq(Loc("else"), Loc(":"), Rule("suite")))))
  1178      def if_stmt(self, if_loc, test, if_colon_loc, body, elifs, else_opt):
  1179          """if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]"""
  1180          stmt = ast.If(orelse=[],
  1181                        else_loc=None, else_colon_loc=None)
  1182  
  1183          if else_opt:
  1184              stmt.else_loc, stmt.else_colon_loc, stmt.orelse = else_opt
  1185  
  1186          for elif_ in reversed(elifs):
  1187              stmt.keyword_loc, stmt.test, stmt.if_colon_loc, stmt.body = elif_
  1188              stmt.loc = stmt.keyword_loc.join(stmt.body[-1].loc)
  1189              if stmt.orelse:
  1190                  stmt.loc = stmt.loc.join(stmt.orelse[-1].loc)
  1191              stmt = ast.If(orelse=[stmt],
  1192                            else_loc=None, else_colon_loc=None)
  1193  
  1194          stmt.keyword_loc, stmt.test, stmt.if_colon_loc, stmt.body = \
  1195              if_loc, test, if_colon_loc, body
  1196          stmt.loc = stmt.keyword_loc.join(stmt.body[-1].loc)
  1197          if stmt.orelse:
  1198              stmt.loc = stmt.loc.join(stmt.orelse[-1].loc)
  1199          return stmt
  1200  
  1201      @action(Seq(Loc("while"), Rule("test"), Loc(":"), Rule("suite"),
  1202                  Opt(Seq(Loc("else"), Loc(":"), Rule("suite")))))
  1203      def while_stmt(self, while_loc, test, while_colon_loc, body, else_opt):
  1204          """while_stmt: 'while' test ':' suite ['else' ':' suite]"""
  1205          stmt = ast.While(test=test, body=body, orelse=[],
  1206                           keyword_loc=while_loc, while_colon_loc=while_colon_loc,
  1207                           else_loc=None, else_colon_loc=None,
  1208                           loc=while_loc.join(body[-1].loc))
  1209          if else_opt:
  1210              stmt.else_loc, stmt.else_colon_loc, stmt.orelse = else_opt
  1211              stmt.loc = stmt.loc.join(stmt.orelse[-1].loc)
  1212  
  1213          return stmt
  1214  
  1215      @action(Seq(Loc("for"), Rule("exprlist"), Loc("in"), Rule("testlist"),
  1216                  Loc(":"), Rule("suite"),
  1217                  Opt(Seq(Loc("else"), Loc(":"), Rule("suite")))))
  1218      def for_stmt(self, for_loc, target, in_loc, iter, for_colon_loc, body, else_opt):
  1219          """for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]"""
  1220          stmt = ast.For(target=self._assignable(target), iter=iter, body=body, orelse=[],
  1221                         keyword_loc=for_loc, in_loc=in_loc, for_colon_loc=for_colon_loc,
  1222                         else_loc=None, else_colon_loc=None,
  1223                         loc=for_loc.join(body[-1].loc))
  1224          if else_opt:
  1225              stmt.else_loc, stmt.else_colon_loc, stmt.orelse = else_opt
  1226              stmt.loc = stmt.loc.join(stmt.orelse[-1].loc)
  1227  
  1228          return stmt
  1229  
  1230      @action(Seq(Plus(Seq(Rule("except_clause"), Loc(":"), Rule("suite"))),
  1231                  Opt(Seq(Loc("else"), Loc(":"), Rule("suite"))),
  1232                  Opt(Seq(Loc("finally"), Loc(":"), Rule("suite")))))
  1233      def try_stmt_1(self, clauses, else_opt, finally_opt):
  1234          handlers = []
  1235          for clause in clauses:
  1236              handler, handler.colon_loc, handler.body = clause
  1237              handler.loc = handler.loc.join(handler.body[-1].loc)
  1238              handlers.append(handler)
  1239  
  1240          else_loc, else_colon_loc, orelse = None, None, []
  1241          loc = handlers[-1].loc
  1242          if else_opt:
  1243              else_loc, else_colon_loc, orelse = else_opt
  1244              loc = orelse[-1].loc
  1245  
  1246          finally_loc, finally_colon_loc, finalbody = None, None, []
  1247          if finally_opt:
  1248              finally_loc, finally_colon_loc, finalbody = finally_opt
  1249              loc = finalbody[-1].loc
  1250          stmt = ast.Try(body=None, handlers=handlers, orelse=orelse, finalbody=finalbody,
  1251                         else_loc=else_loc, else_colon_loc=else_colon_loc,
  1252                         finally_loc=finally_loc, finally_colon_loc=finally_colon_loc,
  1253                         loc=loc)
  1254          return stmt
  1255  
  1256      @action(Seq(Loc("finally"), Loc(":"), Rule("suite")))
  1257      def try_stmt_2(self, finally_loc, finally_colon_loc, finalbody):
  1258          return ast.Try(body=None, handlers=[], orelse=[], finalbody=finalbody,
  1259                         else_loc=None, else_colon_loc=None,
  1260                         finally_loc=finally_loc, finally_colon_loc=finally_colon_loc,
  1261                         loc=finalbody[-1].loc)
  1262  
  1263      @action(Seq(Loc("try"), Loc(":"), Rule("suite"), Alt(try_stmt_1, try_stmt_2)))
  1264      def try_stmt(self, try_loc, try_colon_loc, body, stmt):
  1265          """
  1266          try_stmt: ('try' ':' suite
  1267                     ((except_clause ':' suite)+
  1268                      ['else' ':' suite]
  1269                      ['finally' ':' suite] |
  1270                      'finally' ':' suite))
  1271          """
  1272          stmt.keyword_loc, stmt.try_colon_loc, stmt.body = \
  1273              try_loc, try_colon_loc, body
  1274          stmt.loc = stmt.loc.join(try_loc)
  1275          return stmt
  1276  
  1277      @action(Seq(Loc("with"), Rule("test"), Opt(Rule("with_var")), Loc(":"), Rule("suite")))
  1278      def with_stmt__26(self, with_loc, context, with_var, colon_loc, body):
  1279          """(2.6, 3.0) with_stmt: 'with' test [ with_var ] ':' suite"""
  1280          if with_var:
  1281              as_loc, optional_vars = with_var
  1282              item = ast.withitem(context_expr=context, optional_vars=optional_vars,
  1283                                  as_loc=as_loc, loc=context.loc.join(optional_vars.loc))
  1284          else:
  1285              item = ast.withitem(context_expr=context, optional_vars=None,
  1286                                  as_loc=None, loc=context.loc)
  1287          return ast.With(items=[item], body=body,
  1288                          keyword_loc=with_loc, colon_loc=colon_loc,
  1289                          loc=with_loc.join(body[-1].loc))
  1290  
  1291      with_var = Seq(Loc("as"), Rule("expr"))
  1292      """(2.6, 3.0) with_var: 'as' expr"""
  1293  
  1294      @action(Seq(Loc("with"), List(Rule("with_item"), ",", trailing=False), Loc(":"),
  1295                  Rule("suite")))
  1296      def with_stmt__27(self, with_loc, items, colon_loc, body):
  1297          """(2.7, 3.1-) with_stmt: 'with' with_item (',' with_item)*  ':' suite"""
  1298          return ast.With(items=items, body=body,
  1299                          keyword_loc=with_loc, colon_loc=colon_loc,
  1300                          loc=with_loc.join(body[-1].loc))
  1301  
  1302      @action(Seq(Rule("test"), Opt(Seq(Loc("as"), Rule("expr")))))
  1303      def with_item(self, context, as_opt):
  1304          """(2.7, 3.1-) with_item: test ['as' expr]"""
  1305          if as_opt:
  1306              as_loc, optional_vars = as_opt
  1307              return ast.withitem(context_expr=context, optional_vars=optional_vars,
  1308                                  as_loc=as_loc, loc=context.loc.join(optional_vars.loc))
  1309          else:
  1310              return ast.withitem(context_expr=context, optional_vars=None,
  1311                                  as_loc=None, loc=context.loc)
  1312  
  1313      @action(Seq(Alt(Loc("as"), Loc(",")), Rule("test")))
  1314      def except_clause_1__26(self, as_loc, name):
  1315          return as_loc, None, name
  1316  
  1317      @action(Seq(Loc("as"), Tok("ident")))
  1318      def except_clause_1__30(self, as_loc, name):
  1319          return as_loc, name, None
  1320  
  1321      @action(Seq(Loc("except"),
  1322                  Opt(Seq(Rule("test"),
  1323                          Opt(Rule("except_clause_1"))))))
  1324      def except_clause(self, except_loc, exc_opt):
  1325          """
  1326          (2.6, 2.7) except_clause: 'except' [test [('as' | ',') test]]
  1327          (3.0-) except_clause: 'except' [test ['as' NAME]]
  1328          """
  1329          type_ = name = as_loc = name_loc = None
  1330          loc = except_loc
  1331          if exc_opt:
  1332              type_, name_opt = exc_opt
  1333              loc = loc.join(type_.loc)
  1334              if name_opt:
  1335                  as_loc, name_tok, name_node = name_opt
  1336                  if name_tok:
  1337                      name = name_tok.value
  1338                      name_loc = name_tok.loc
  1339                  else:
  1340                      name = name_node
  1341                      name_loc = name_node.loc
  1342                  loc = loc.join(name_loc)
  1343          return ast.ExceptHandler(type=type_, name=name,
  1344                                   except_loc=except_loc, as_loc=as_loc, name_loc=name_loc,
  1345                                   loc=loc)
  1346  
  1347      @action(Plus(Rule("stmt")))
  1348      def suite_1(self, stmts):
  1349          return reduce(list.__add__, stmts, [])
  1350  
  1351      suite = Alt(Rule("simple_stmt"),
  1352                  SeqN(2, Tok("newline"), Tok("indent"), suite_1, Tok("dedent")))
  1353      """suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT"""
  1354  
  1355      # 2.x-only backwards compatibility start
  1356      testlist_safe = action(List(Rule("old_test"), ",", trailing=False))(_wrap_tuple)
  1357      """(2.6, 2.7) testlist_safe: old_test [(',' old_test)+ [',']]"""
  1358  
  1359      old_test = Alt(Rule("or_test"), Rule("old_lambdef"))
  1360      """(2.6, 2.7) old_test: or_test | old_lambdef"""
  1361  
  1362      @action(Seq(Loc("lambda"), Opt(Rule("varargslist")), Loc(":"), Rule("old_test")))
  1363      def old_lambdef(self, lambda_loc, args_opt, colon_loc, body):
  1364          """(2.6, 2.7) old_lambdef: 'lambda' [varargslist] ':' old_test"""
  1365          if args_opt is None:
  1366              args_opt = self._arguments()
  1367              args_opt.loc = colon_loc.begin()
  1368          return ast.Lambda(args=args_opt, body=body,
  1369                            lambda_loc=lambda_loc, colon_loc=colon_loc,
  1370                            loc=lambda_loc.join(body.loc))
  1371      # 2.x-only backwards compatibility end
  1372  
  1373      @action(Seq(Rule("or_test"), Opt(Seq(Loc("if"), Rule("or_test"),
  1374                                           Loc("else"), Rule("test")))))
  1375      def test_1(self, lhs, rhs_opt):
  1376          if rhs_opt is not None:
  1377              if_loc, test, else_loc, orelse = rhs_opt
  1378              return ast.IfExp(test=test, body=lhs, orelse=orelse,
  1379                               if_loc=if_loc, else_loc=else_loc, loc=lhs.loc.join(orelse.loc))
  1380          return lhs
  1381  
  1382      test = Alt(test_1, Rule("lambdef"))
  1383      """test: or_test ['if' or_test 'else' test] | lambdef"""
  1384  
  1385      test_nocond = Alt(Rule("or_test"), Rule("lambdef_nocond"))
  1386      """(3.0-) test_nocond: or_test | lambdef_nocond"""
  1387  
  1388      def lambdef_action(self, lambda_loc, args_opt, colon_loc, body):
  1389          if args_opt is None:
  1390              args_opt = self._arguments()
  1391              args_opt.loc = colon_loc.begin()
  1392          return ast.Lambda(args=args_opt, body=body,
  1393                            lambda_loc=lambda_loc, colon_loc=colon_loc,
  1394                            loc=lambda_loc.join(body.loc))
  1395  
  1396      lambdef = action(
  1397          Seq(Loc("lambda"), Opt(Rule("varargslist")), Loc(":"), Rule("test"))) \
  1398          (lambdef_action)
  1399      """lambdef: 'lambda' [varargslist] ':' test"""
  1400  
  1401      lambdef_nocond = action(
  1402          Seq(Loc("lambda"), Opt(Rule("varargslist")), Loc(":"), Rule("test_nocond"))) \
  1403          (lambdef_action)
  1404      """(3.0-) lambdef_nocond: 'lambda' [varargslist] ':' test_nocond"""
  1405  
  1406      @action(Seq(Rule("and_test"), Star(Seq(Loc("or"), Rule("and_test")))))
  1407      def or_test(self, lhs, rhs):
  1408          """or_test: and_test ('or' and_test)*"""
  1409          if len(rhs) > 0:
  1410              return ast.BoolOp(op=ast.Or(),
  1411                                values=[lhs] + list(map(lambda x: x[1], rhs)),
  1412                                loc=lhs.loc.join(rhs[-1][1].loc),
  1413                                op_locs=list(map(lambda x: x[0], rhs)))
  1414          else:
  1415              return lhs
  1416  
  1417      @action(Seq(Rule("not_test"), Star(Seq(Loc("and"), Rule("not_test")))))
  1418      def and_test(self, lhs, rhs):
  1419          """and_test: not_test ('and' not_test)*"""
  1420          if len(rhs) > 0:
  1421              return ast.BoolOp(op=ast.And(),
  1422                                values=[lhs] + list(map(lambda x: x[1], rhs)),
  1423                                loc=lhs.loc.join(rhs[-1][1].loc),
  1424                                op_locs=list(map(lambda x: x[0], rhs)))
  1425          else:
  1426              return lhs
  1427  
  1428      @action(Seq(Oper(ast.Not, "not"), Rule("not_test")))
  1429      def not_test_1(self, op, operand):
  1430          return ast.UnaryOp(op=op, operand=operand,
  1431                             loc=op.loc.join(operand.loc))
  1432  
  1433      not_test = Alt(not_test_1, Rule("comparison"))
  1434      """not_test: 'not' not_test | comparison"""
  1435  
  1436      comparison_1__26 = Seq(Rule("expr"), Star(Seq(Rule("comp_op"), Rule("expr"))))
  1437      comparison_1__30 = Seq(Rule("star_expr"), Star(Seq(Rule("comp_op"), Rule("star_expr"))))
  1438      comparison_1__32 = comparison_1__26
  1439  
  1440      @action(Rule("comparison_1"))
  1441      def comparison(self, lhs, rhs):
  1442          """
  1443          (2.6, 2.7) comparison: expr (comp_op expr)*
  1444          (3.0, 3.1) comparison: star_expr (comp_op star_expr)*
  1445          (3.2-) comparison: expr (comp_op expr)*
  1446          """
  1447          if len(rhs) > 0:
  1448              return ast.Compare(left=lhs, ops=list(map(lambda x: x[0], rhs)),
  1449                                 comparators=list(map(lambda x: x[1], rhs)),
  1450                                 loc=lhs.loc.join(rhs[-1][1].loc))
  1451          else:
  1452              return lhs
  1453  
  1454      @action(Seq(Opt(Loc("*")), Rule("expr")))
  1455      def star_expr__30(self, star_opt, expr):
  1456          """(3.0, 3.1) star_expr: ['*'] expr"""
  1457          if star_opt:
  1458              return ast.Starred(value=expr, ctx=None,
  1459                                 star_loc=star_opt, loc=expr.loc.join(star_opt))
  1460          return expr
  1461  
  1462      @action(Seq(Loc("*"), Rule("expr")))
  1463      def star_expr__32(self, star_loc, expr):
  1464          """(3.0-) star_expr: '*' expr"""
  1465          return ast.Starred(value=expr, ctx=None,
  1466                             star_loc=star_loc, loc=expr.loc.join(star_loc))
  1467  
  1468      comp_op = Alt(Oper(ast.Lt, "<"), Oper(ast.Gt, ">"), Oper(ast.Eq, "=="),
  1469                    Oper(ast.GtE, ">="), Oper(ast.LtE, "<="), Oper(ast.NotEq, "<>"),
  1470                    Oper(ast.NotEq, "!="),
  1471                    Oper(ast.In, "in"), Oper(ast.NotIn, "not", "in"),
  1472                    Oper(ast.IsNot, "is", "not"), Oper(ast.Is, "is"))
  1473      """
  1474      (2.6, 2.7) comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
  1475      (3.0-) comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not'
  1476      """
  1477  
  1478      expr = BinOper("xor_expr", Oper(ast.BitOr, "|"))
  1479      """expr: xor_expr ('|' xor_expr)*"""
  1480  
  1481      xor_expr = BinOper("and_expr", Oper(ast.BitXor, "^"))
  1482      """xor_expr: and_expr ('^' and_expr)*"""
  1483  
  1484      and_expr = BinOper("shift_expr", Oper(ast.BitAnd, "&"))
  1485      """and_expr: shift_expr ('&' shift_expr)*"""
  1486  
  1487      shift_expr = BinOper("arith_expr", Alt(Oper(ast.LShift, "<<"), Oper(ast.RShift, ">>")))
  1488      """shift_expr: arith_expr (('<<'|'>>') arith_expr)*"""
  1489  
  1490      arith_expr = BinOper("term", Alt(Oper(ast.Add, "+"), Oper(ast.Sub, "-")))
  1491      """arith_expr: term (('+'|'-') term)*"""
  1492  
  1493      term = BinOper("factor", Alt(Oper(ast.Mult, "*"), Oper(ast.MatMult, "@"),
  1494                                   Oper(ast.Div, "/"), Oper(ast.Mod, "%"),
  1495                                   Oper(ast.FloorDiv, "//")))
  1496      """term: factor (('*'|'/'|'%'|'//') factor)*"""
  1497  
  1498      @action(Seq(Alt(Oper(ast.UAdd, "+"), Oper(ast.USub, "-"), Oper(ast.Invert, "~")),
  1499                  Rule("factor")))
  1500      def factor_1(self, op, factor):
  1501          return ast.UnaryOp(op=op, operand=factor,
  1502                             loc=op.loc.join(factor.loc))
  1503  
  1504      factor = Alt(factor_1, Rule("power"))
  1505      """factor: ('+'|'-'|'~') factor | power"""
  1506  
  1507      @action(Seq(Rule("atom"), Star(Rule("trailer")), Opt(Seq(Loc("**"), Rule("factor")))))
  1508      def power(self, atom, trailers, factor_opt):
  1509          """power: atom trailer* ['**' factor]"""
  1510          for trailer in trailers:
  1511              if isinstance(trailer, ast.Attribute) or isinstance(trailer, ast.Subscript):
  1512                  trailer.value = atom
  1513              elif isinstance(trailer, ast.Call):
  1514                  trailer.func = atom
  1515              trailer.loc = atom.loc.join(trailer.loc)
  1516              atom = trailer
  1517          if factor_opt:
  1518              op_loc, factor = factor_opt
  1519              return ast.BinOp(left=atom, op=ast.Pow(loc=op_loc), right=factor,
  1520                               loc=atom.loc.join(factor.loc))
  1521          return atom
  1522  
  1523      @action(Rule("testlist1"))
  1524      def atom_1(self, expr):
  1525          return ast.Repr(value=expr, loc=None)
  1526  
  1527      @action(Tok("ident"))
  1528      def atom_2(self, tok):
  1529          return ast.Name(id=tok.value, loc=tok.loc, ctx=None)
  1530  
  1531      @action(Alt(Tok("int"), Tok("float"), Tok("complex")))
  1532      def atom_3(self, tok):
  1533          return ast.Num(n=tok.value, loc=tok.loc)
  1534  
  1535      @action(Seq(Tok("strbegin"), Tok("strdata"), Tok("strend")))
  1536      def atom_4(self, begin_tok, data_tok, end_tok):
  1537          return ast.Str(s=data_tok.value,
  1538                         begin_loc=begin_tok.loc, end_loc=end_tok.loc,
  1539                         loc=begin_tok.loc.join(end_tok.loc))
  1540  
  1541      @action(Plus(atom_4))
  1542      def atom_5(self, strings):
  1543          joint = ""
  1544          if all(isinstance(x.s, bytes) for x in strings):
  1545              joint = b""
  1546          return ast.Str(s=joint.join([x.s for x in strings]),
  1547                         begin_loc=strings[0].begin_loc, end_loc=strings[-1].end_loc,
  1548                         loc=strings[0].loc.join(strings[-1].loc))
  1549  
  1550      atom_6__26 = Rule("dictmaker")
  1551      atom_6__27 = Rule("dictorsetmaker")
  1552  
  1553      atom__26 = Alt(BeginEnd("(", Opt(Alt(Rule("yield_expr"), Rule("testlist_comp"))), ")",
  1554                              empty=lambda self: ast.Tuple(elts=[], ctx=None, loc=None)),
  1555                     BeginEnd("[", Opt(Rule("listmaker")), "]",
  1556                              empty=lambda self: ast.List(elts=[], ctx=None, loc=None)),
  1557                     BeginEnd("{", Opt(Rule("atom_6")), "}",
  1558                              empty=lambda self: ast.Dict(keys=[], values=[], colon_locs=[],
  1559                                                          loc=None)),
  1560                     BeginEnd("`", atom_1, "`"),
  1561                     atom_2, atom_3, atom_5)
  1562      """
  1563      (2.6)
  1564      atom: ('(' [yield_expr|testlist_gexp] ')' |
  1565             '[' [listmaker] ']' |
  1566             '{' [dictmaker] '}' |
  1567             '`' testlist1 '`' |
  1568             NAME | NUMBER | STRING+)
  1569      (2.7)
  1570      atom: ('(' [yield_expr|testlist_comp] ')' |
  1571             '[' [listmaker] ']' |
  1572             '{' [dictorsetmaker] '}' |
  1573             '`' testlist1 '`' |
  1574             NAME | NUMBER | STRING+)
  1575      """
  1576  
  1577      @action(Loc("..."))
  1578      def atom_7(self, loc):
  1579          return ast.Ellipsis(loc=loc)
  1580  
  1581      @action(Alt(Tok("None"), Tok("True"), Tok("False")))
  1582      def atom_8(self, tok):
  1583          if tok.kind == "None":
  1584              value = None
  1585          elif tok.kind == "True":
  1586              value = True
  1587          elif tok.kind == "False":
  1588              value = False
  1589          return ast.NameConstant(value=value, loc=tok.loc)
  1590  
  1591      atom__30 = Alt(BeginEnd("(", Opt(Alt(Rule("yield_expr"), Rule("testlist_comp"))), ")",
  1592                              empty=lambda self: ast.Tuple(elts=[], ctx=None, loc=None)),
  1593                     BeginEnd("[", Opt(Rule("testlist_comp__list")), "]",
  1594                              empty=lambda self: ast.List(elts=[], ctx=None, loc=None)),
  1595                     BeginEnd("{", Opt(Rule("dictorsetmaker")), "}",
  1596                              empty=lambda self: ast.Dict(keys=[], values=[], colon_locs=[],
  1597                                                          loc=None)),
  1598                     atom_2, atom_3, atom_5, atom_7, atom_8)
  1599      """
  1600      (3.0-)
  1601      atom: ('(' [yield_expr|testlist_comp] ')' |
  1602             '[' [testlist_comp] ']' |
  1603             '{' [dictorsetmaker] '}' |
  1604             NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False')
  1605      """
  1606  
  1607      def list_gen_action(self, lhs, rhs):
  1608          if rhs is None: # (x)
  1609              return lhs
  1610          elif isinstance(rhs, ast.Tuple) or isinstance(rhs, ast.List):
  1611              rhs.elts = [lhs] + rhs.elts
  1612              return rhs
  1613          elif isinstance(rhs, ast.ListComp) or isinstance(rhs, ast.GeneratorExp):
  1614              rhs.elt = lhs
  1615              return rhs
  1616  
  1617      @action(Rule("list_for"))
  1618      def listmaker_1(self, compose):
  1619          return ast.ListComp(generators=compose([]), loc=None)
  1620  
  1621      @action(List(Rule("test"), ",", trailing=True, leading=False))
  1622      def listmaker_2(self, elts):
  1623          return ast.List(elts=elts, ctx=None, loc=None)
  1624  
  1625      listmaker = action(
  1626          Seq(Rule("test"),
  1627              Alt(listmaker_1, listmaker_2))) \
  1628          (list_gen_action)
  1629      """listmaker: test ( list_for | (',' test)* [','] )"""
  1630  
  1631      testlist_comp_1__26 = Rule("test")
  1632      testlist_comp_1__32 = Alt(Rule("test"), Rule("star_expr"))
  1633  
  1634      @action(Rule("comp_for"))
  1635      def testlist_comp_2(self, compose):
  1636          return ast.GeneratorExp(generators=compose([]), loc=None)
  1637  
  1638      @action(List(Rule("testlist_comp_1"), ",", trailing=True, leading=False))
  1639      def testlist_comp_3(self, elts):
  1640          if elts == [] and not elts.trailing_comma:
  1641              return None
  1642          else:
  1643              return ast.Tuple(elts=elts, ctx=None, loc=None)
  1644  
  1645      testlist_comp = action(
  1646          Seq(Rule("testlist_comp_1"), Alt(testlist_comp_2, testlist_comp_3))) \
  1647          (list_gen_action)
  1648      """
  1649      (2.6) testlist_gexp: test ( gen_for | (',' test)* [','] )
  1650      (2.7, 3.0, 3.1) testlist_comp: test ( comp_for | (',' test)* [','] )
  1651      (3.2-) testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
  1652      """
  1653  
  1654      @action(Rule("comp_for"))
  1655      def testlist_comp__list_1(self, compose):
  1656          return ast.ListComp(generators=compose([]), loc=None)
  1657  
  1658      @action(List(Rule("testlist_comp_1"), ",", trailing=True, leading=False))
  1659      def testlist_comp__list_2(self, elts):
  1660          return ast.List(elts=elts, ctx=None, loc=None)
  1661  
  1662      testlist_comp__list = action(
  1663          Seq(Rule("testlist_comp_1"), Alt(testlist_comp__list_1, testlist_comp__list_2))) \
  1664          (list_gen_action)
  1665      """Same grammar as testlist_comp, but different semantic action."""
  1666  
  1667      @action(Seq(Loc("."), Tok("ident")))
  1668      def trailer_1(self, dot_loc, ident_tok):
  1669          return ast.Attribute(attr=ident_tok.value, ctx=None,
  1670                               loc=dot_loc.join(ident_tok.loc),
  1671                               attr_loc=ident_tok.loc, dot_loc=dot_loc)
  1672  
  1673      trailer = Alt(BeginEnd("(", Opt(Rule("arglist")), ")",
  1674                             empty=_empty_arglist),
  1675                    BeginEnd("[", Rule("subscriptlist"), "]"),
  1676                    trailer_1)
  1677      """trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME"""
  1678  
  1679      @action(List(Rule("subscript"), ",", trailing=True))
  1680      def subscriptlist(self, subscripts):
  1681          """subscriptlist: subscript (',' subscript)* [',']"""
  1682          if len(subscripts) == 1:
  1683              return ast.Subscript(slice=subscripts[0], ctx=None, loc=None)
  1684          elif all([isinstance(x, ast.Index) for x in subscripts]):
  1685              elts  = [x.value for x in subscripts]
  1686              loc   = subscripts[0].loc.join(subscripts[-1].loc)
  1687              index = ast.Index(value=ast.Tuple(elts=elts, ctx=None,
  1688                                                begin_loc=None, end_loc=None, loc=loc),
  1689                                loc=loc)
  1690              return ast.Subscript(slice=index, ctx=None, loc=None)
  1691          else:
  1692              extslice = ast.ExtSlice(dims=subscripts,
  1693                                      loc=subscripts[0].loc.join(subscripts[-1].loc))
  1694              return ast.Subscript(slice=extslice, ctx=None, loc=None)
  1695  
  1696      @action(Seq(Loc("."), Loc("."), Loc(".")))
  1697      def subscript_1(self, dot_1_loc, dot_2_loc, dot_3_loc):
  1698          return ast.Ellipsis(loc=dot_1_loc.join(dot_3_loc))
  1699  
  1700      @action(Seq(Opt(Rule("test")), Loc(":"), Opt(Rule("test")), Opt(Rule("sliceop"))))
  1701      def subscript_2(self, lower_opt, colon_loc, upper_opt, step_opt):
  1702          loc = colon_loc
  1703          if lower_opt:
  1704              loc = loc.join(lower_opt.loc)
  1705          if upper_opt:
  1706              loc = loc.join(upper_opt.loc)
  1707          step_colon_loc = step = None
  1708          if step_opt:
  1709              step_colon_loc, step = step_opt
  1710              loc = loc.join(step_colon_loc)
  1711              if step:
  1712                  loc = loc.join(step.loc)
  1713          return ast.Slice(lower=lower_opt, upper=upper_opt, step=step,
  1714                           loc=loc, bound_colon_loc=colon_loc, step_colon_loc=step_colon_loc)
  1715  
  1716      @action(Rule("test"))
  1717      def subscript_3(self, expr):
  1718          return ast.Index(value=expr, loc=expr.loc)
  1719  
  1720      subscript__26 = Alt(subscript_1, subscript_2, subscript_3)
  1721      """(2.6, 2.7) subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]"""
  1722  
  1723      subscript__30 = Alt(subscript_2, subscript_3)
  1724      """(3.0-) subscript: test | [test] ':' [test] [sliceop]"""
  1725  
  1726      sliceop = Seq(Loc(":"), Opt(Rule("test")))
  1727      """sliceop: ':' [test]"""
  1728  
  1729      exprlist_1__26 = List(Rule("expr"), ",", trailing=True)
  1730      exprlist_1__30 = List(Rule("star_expr"), ",", trailing=True)
  1731      exprlist_1__32 = List(Alt(Rule("expr"), Rule("star_expr")), ",", trailing=True)
  1732  
  1733      @action(Rule("exprlist_1"))
  1734      def exprlist(self, exprs):
  1735          """
  1736          (2.6, 2.7) exprlist: expr (',' expr)* [',']
  1737          (3.0, 3.1) exprlist: star_expr (',' star_expr)* [',']
  1738          (3.2-) exprlist: (expr|star_expr) (',' (expr|star_expr))* [',']
  1739          """
  1740          return self._wrap_tuple(exprs)
  1741  
  1742      @action(List(Rule("test"), ",", trailing=True))
  1743      def testlist(self, exprs):
  1744          """testlist: test (',' test)* [',']"""
  1745          return self._wrap_tuple(exprs)
  1746  
  1747      @action(List(Seq(Rule("test"), Loc(":"), Rule("test")), ",", trailing=True))
  1748      def dictmaker(self, elts):
  1749          """(2.6) dictmaker: test ':' test (',' test ':' test)* [',']"""
  1750          return ast.Dict(keys=list(map(lambda x: x[0], elts)),
  1751                          values=list(map(lambda x: x[2], elts)),
  1752                          colon_locs=list(map(lambda x: x[1], elts)),
  1753                          loc=None)
  1754  
  1755      dictorsetmaker_1 = Seq(Rule("test"), Loc(":"), Rule("test"))
  1756  
  1757      @action(Seq(dictorsetmaker_1,
  1758                  Alt(Rule("comp_for"),
  1759                      List(dictorsetmaker_1, ",", leading=False, trailing=True))))
  1760      def dictorsetmaker_2(self, first, elts):
  1761          if isinstance(elts, commalist):
  1762              elts.insert(0, first)
  1763              return ast.Dict(keys=list(map(lambda x: x[0], elts)),
  1764                              values=list(map(lambda x: x[2], elts)),
  1765                              colon_locs=list(map(lambda x: x[1], elts)),
  1766                              loc=None)
  1767          else:
  1768              return ast.DictComp(key=first[0], value=first[2], generators=elts([]),
  1769                                  colon_loc=first[1],
  1770                                  begin_loc=None, end_loc=None, loc=None)
  1771  
  1772      @action(Seq(Rule("test"),
  1773                  Alt(Rule("comp_for"),
  1774                      List(Rule("test"), ",", leading=False, trailing=True))))
  1775      def dictorsetmaker_3(self, first, elts):
  1776          if isinstance(elts, commalist):
  1777              elts.insert(0, first)
  1778              return ast.Set(elts=elts, loc=None)
  1779          else:
  1780              return ast.SetComp(elt=first, generators=elts([]),
  1781                                 begin_loc=None, end_loc=None, loc=None)
  1782  
  1783      dictorsetmaker = Alt(dictorsetmaker_2, dictorsetmaker_3)
  1784      """
  1785      (2.7-)
  1786      dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) |
  1787                        (test (comp_for | (',' test)* [','])) )
  1788      """
  1789  
  1790      @action(Seq(Loc("class"), Tok("ident"),
  1791                  Opt(Seq(Loc("("), List(Rule("test"), ",", trailing=True), Loc(")"))),
  1792                  Loc(":"), Rule("suite")))
  1793      def classdef__26(self, class_loc, name_tok, bases_opt, colon_loc, body):
  1794          """(2.6, 2.7) classdef: 'class' NAME ['(' [testlist] ')'] ':' suite"""
  1795          bases, lparen_loc, rparen_loc = [], None, None
  1796          if bases_opt:
  1797              lparen_loc, bases, rparen_loc = bases_opt
  1798  
  1799          return ast.ClassDef(name=name_tok.value, bases=bases, keywords=[],
  1800                              starargs=None, kwargs=None, body=body,
  1801                              decorator_list=[], at_locs=[],
  1802                              keyword_loc=class_loc, lparen_loc=lparen_loc,
  1803                              star_loc=None, dstar_loc=None, rparen_loc=rparen_loc,
  1804                              name_loc=name_tok.loc, colon_loc=colon_loc,
  1805                              loc=class_loc.join(body[-1].loc))
  1806  
  1807      @action(Seq(Loc("class"), Tok("ident"),
  1808                  Opt(Seq(Loc("("), Rule("arglist"), Loc(")"))),
  1809                  Loc(":"), Rule("suite")))
  1810      def classdef__30(self, class_loc, name_tok, arglist_opt, colon_loc, body):
  1811          """(3.0) classdef: 'class' NAME ['(' [testlist] ')'] ':' suite"""
  1812          arglist, lparen_loc, rparen_loc = [], None, None
  1813          bases, keywords, starargs, kwargs = [], [], None, None
  1814          star_loc, dstar_loc = None, None
  1815          if arglist_opt:
  1816              lparen_loc, arglist, rparen_loc = arglist_opt
  1817              bases, keywords, starargs, kwargs = \
  1818                  arglist.args, arglist.keywords, arglist.starargs, arglist.kwargs
  1819              star_loc, dstar_loc = arglist.star_loc, arglist.dstar_loc
  1820  
  1821          return ast.ClassDef(name=name_tok.value, bases=bases, keywords=keywords,
  1822                              starargs=starargs, kwargs=kwargs, body=body,
  1823                              decorator_list=[], at_locs=[],
  1824                              keyword_loc=class_loc, lparen_loc=lparen_loc,
  1825                              star_loc=star_loc, dstar_loc=dstar_loc, rparen_loc=rparen_loc,
  1826                              name_loc=name_tok.loc, colon_loc=colon_loc,
  1827                              loc=class_loc.join(body[-1].loc))
  1828  
  1829      @action(Seq(Loc("*"), Rule("test"), Star(SeqN(1, Tok(","), Rule("argument"))),
  1830                  Opt(Seq(Tok(","), Loc("**"), Rule("test")))))
  1831      def arglist_1(self, star_loc, stararg, postargs, kwarg_opt):
  1832          dstar_loc = kwarg = None
  1833          if kwarg_opt:
  1834              _, dstar_loc, kwarg = kwarg_opt
  1835  
  1836          for postarg in postargs:
  1837              if not isinstance(postarg, ast.keyword):
  1838                  error = diagnostic.Diagnostic(
  1839                      "fatal", "only named arguments may follow *expression", {},
  1840                      postarg.loc, [star_loc.join(stararg.loc)])
  1841                  self.diagnostic_engine.process(error)
  1842  
  1843          return postargs, \
  1844                 ast.Call(args=[], keywords=[], starargs=stararg, kwargs=kwarg,
  1845                          star_loc=star_loc, dstar_loc=dstar_loc, loc=None)
  1846  
  1847      @action(Seq(Loc("**"), Rule("test")))
  1848      def arglist_2(self, dstar_loc, kwarg):
  1849          return [], \
  1850                 ast.Call(args=[], keywords=[], starargs=None, kwargs=kwarg,
  1851                          star_loc=None, dstar_loc=dstar_loc, loc=None)
  1852  
  1853      @action(Seq(Rule("argument"),
  1854                  Alt(SeqN(1, Tok(","), Alt(Rule("arglist_1"),
  1855                                            Rule("arglist_2"),
  1856                                            Rule("arglist_3"),
  1857                                            Eps())),
  1858                      Eps())))
  1859      def arglist_3(self, arg, cont):
  1860          if cont is None:
  1861              return [arg], self._empty_arglist()
  1862          else:
  1863              args, rest = cont
  1864              return [arg] + args, rest
  1865  
  1866      @action(Alt(Rule("arglist_1"),
  1867                  Rule("arglist_2"),
  1868                  Rule("arglist_3")))
  1869      def arglist(self, args, call):
  1870          """arglist: (argument ',')* (argument [','] |
  1871                                       '*' test (',' argument)* [',' '**' test] |
  1872                                       '**' test)"""
  1873          for arg in args:
  1874              if isinstance(arg, ast.keyword):
  1875                  call.keywords.append(arg)
  1876              elif len(call.keywords) > 0:
  1877                  error = diagnostic.Diagnostic(
  1878                      "fatal", "non-keyword arg after keyword arg", {},
  1879                      arg.loc, [call.keywords[-1].loc])
  1880                  self.diagnostic_engine.process(error)
  1881              else:
  1882                  call.args.append(arg)
  1883          return call
  1884  
  1885      @action(Seq(Loc("="), Rule("test")))
  1886      def argument_1(self, equals_loc, rhs):
  1887          def thunk(lhs):
  1888              if not isinstance(lhs, ast.Name):
  1889                  error = diagnostic.Diagnostic(
  1890                      "fatal", "keyword must be an identifier", {}, lhs.loc)
  1891                  self.diagnostic_engine.process(error)
  1892              return ast.keyword(arg=lhs.id, value=rhs,
  1893                                 loc=lhs.loc.join(rhs.loc),
  1894                                 arg_loc=lhs.loc, equals_loc=equals_loc)
  1895          return thunk
  1896  
  1897      @action(Opt(Rule("comp_for")))
  1898      def argument_2(self, compose_opt):
  1899          def thunk(lhs):
  1900              if compose_opt:
  1901                  generators = compose_opt([])
  1902                  return ast.GeneratorExp(elt=lhs, generators=generators,
  1903                                          begin_loc=None, end_loc=None,
  1904                                          loc=lhs.loc.join(generators[-1].loc))
  1905              return lhs
  1906          return thunk
  1907  
  1908      @action(Seq(Rule("test"), Alt(argument_1, argument_2)))
  1909      def argument(self, lhs, thunk):
  1910          # This rule is reformulated to avoid exponential backtracking.
  1911          """
  1912          (2.6) argument: test [gen_for] | test '=' test  # Really [keyword '='] test
  1913          (2.7-) argument: test [comp_for] | test '=' test
  1914          """
  1915          return thunk(lhs)
  1916  
  1917      list_iter = Alt(Rule("list_for"), Rule("list_if"))
  1918      """(2.6, 2.7) list_iter: list_for | list_if"""
  1919  
  1920      def list_comp_for_action(self, for_loc, target, in_loc, iter, next_opt):
  1921          def compose(comprehensions):
  1922              comp = ast.comprehension(
  1923                  target=target, iter=iter, ifs=[],
  1924                  loc=for_loc.join(iter.loc), for_loc=for_loc, in_loc=in_loc, if_locs=[])
  1925              comprehensions += [comp]
  1926              if next_opt:
  1927                  return next_opt(comprehensions)
  1928              else:
  1929                  return comprehensions
  1930          return compose
  1931  
  1932      def list_comp_if_action(self, if_loc, cond, next_opt):
  1933          def compose(comprehensions):
  1934              comprehensions[-1].ifs.append(cond)
  1935              comprehensions[-1].if_locs.append(if_loc)
  1936              comprehensions[-1].loc = comprehensions[-1].loc.join(cond.loc)
  1937              if next_opt:
  1938                  return next_opt(comprehensions)
  1939              else:
  1940                  return comprehensions
  1941          return compose
  1942  
  1943      list_for = action(
  1944          Seq(Loc("for"), Rule("exprlist"),
  1945              Loc("in"), Rule("testlist_safe"), Opt(Rule("list_iter")))) \
  1946          (list_comp_for_action)
  1947      """(2.6, 2.7) list_for: 'for' exprlist 'in' testlist_safe [list_iter]"""
  1948  
  1949      list_if = action(
  1950          Seq(Loc("if"), Rule("old_test"), Opt(Rule("list_iter")))) \
  1951          (list_comp_if_action)
  1952      """(2.6, 2.7) list_if: 'if' old_test [list_iter]"""
  1953  
  1954      comp_iter = Alt(Rule("comp_for"), Rule("comp_if"))
  1955      """
  1956      (2.6) gen_iter: gen_for | gen_if
  1957      (2.7-) comp_iter: comp_for | comp_if
  1958      """
  1959  
  1960      comp_for = action(
  1961          Seq(Loc("for"), Rule("exprlist"),
  1962              Loc("in"), Rule("or_test"), Opt(Rule("comp_iter")))) \
  1963          (list_comp_for_action)
  1964      """
  1965      (2.6) gen_for: 'for' exprlist 'in' or_test [gen_iter]
  1966      (2.7-) comp_for: 'for' exprlist 'in' or_test [comp_iter]
  1967      """
  1968  
  1969      comp_if__26 = action(
  1970          Seq(Loc("if"), Rule("old_test"), Opt(Rule("comp_iter")))) \
  1971          (list_comp_if_action)
  1972      """
  1973      (2.6) gen_if: 'if' old_test [gen_iter]
  1974      (2.7) comp_if: 'if' old_test [comp_iter]
  1975      """
  1976  
  1977      comp_if__30 = action(
  1978          Seq(Loc("if"), Rule("test_nocond"), Opt(Rule("comp_iter")))) \
  1979          (list_comp_if_action)
  1980      """
  1981      (3.0-) comp_if: 'if' test_nocond [comp_iter]
  1982      """
  1983  
  1984      testlist1 = action(List(Rule("test"), ",", trailing=False))(_wrap_tuple)
  1985      """testlist1: test (',' test)*"""
  1986  
  1987      @action(Seq(Loc("yield"), Opt(Rule("testlist"))))
  1988      def yield_expr__26(self, yield_loc, exprs):
  1989          """(2.6, 2.7, 3.0, 3.1, 3.2) yield_expr: 'yield' [testlist]"""
  1990          if exprs is not None:
  1991              return ast.Yield(value=exprs,
  1992                               yield_loc=yield_loc, loc=yield_loc.join(exprs.loc))
  1993          else:
  1994              return ast.Yield(value=None,
  1995                               yield_loc=yield_loc, loc=yield_loc)
  1996  
  1997      @action(Seq(Loc("yield"), Opt(Rule("yield_arg"))))
  1998      def yield_expr__33(self, yield_loc, arg):
  1999          """(3.3-) yield_expr: 'yield' [yield_arg]"""
  2000          if isinstance(arg, ast.YieldFrom):
  2001              arg.yield_loc = yield_loc
  2002              arg.loc = arg.loc.join(arg.yield_loc)
  2003              return arg
  2004          elif arg is not None:
  2005              return ast.Yield(value=arg,
  2006                               yield_loc=yield_loc, loc=yield_loc.join(arg.loc))
  2007          else:
  2008              return ast.Yield(value=None,
  2009                               yield_loc=yield_loc, loc=yield_loc)
  2010  
  2011      @action(Seq(Loc("from"), Rule("test")))
  2012      def yield_arg_1(self, from_loc, value):
  2013          return ast.YieldFrom(value=value,
  2014                               from_loc=from_loc, loc=from_loc.join(value.loc))
  2015  
  2016      yield_arg = Alt(yield_arg_1, Rule("testlist"))
  2017      """(3.3-) yield_arg: 'from' test | testlist"""