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"""