1 package org.python.parser; 2 3 import org.python.parser.ast.*; 4 import org.python.core.PyObject; 5 6 public class TreeBuilder implements PythonGrammarTreeConstants { 7 private JJTPythonGrammarState stack; 8 CtxVisitor ctx; 9 10 public TreeBuilder(JJTPythonGrammarState stack) { 11 this.stack = stack; 12 ctx = new CtxVisitor(); 13 } 14 15 private stmtType[] makeStmts(int l) { 16 stmtType[] stmts = new stmtType[l]; 17 for (int i = l-1; i >= 0; i--) { 18 stmts[i] = (stmtType) stack.popNode(); 19 } 20 return stmts; 21 } 22 23 private stmtType[] popSuite() { 24 return ((Suite) popNode()).body; 25 } 26 27 private exprType[] makeExprs() { 28 if (stack.nodeArity() > 0 && peekNode().getId() == JJTCOMMA) 29 popNode(); 30 return makeExprs(stack.nodeArity()); 31 } 32 33 private exprType[] makeExprs(int l) { 34 exprType[] exprs = new exprType[l]; 35 for (int i = l-1; i >= 0; i--) { 36 exprs[i] = makeExpr(); 37 } 38 return exprs; 39 } 40 41 private exprType makeExpr(SimpleNode node) { 42 return (exprType) node; 43 } 44 45 private exprType makeExpr() { 46 return makeExpr((SimpleNode) stack.popNode()); 47 } 48 49 private String makeIdentifier() { 50 return ((Name) stack.popNode()).id; 51 } 52 53 private String [] makeIdentifiers() { 54 int l = stack.nodeArity(); 55 String [] ids = new String [l]; 56 for (int i = l - 1; i >= 0; i--) { 57 ids[i] = makeIdentifier(); 58 } 59 return ids; 60 } 61 62 private aliasType[] makeAliases() { 63 return makeAliases(stack.nodeArity()); 64 } 65 66 private aliasType[] makeAliases(int l) { 67 aliasType[] aliases = new aliasType[l]; 68 for (int i = l-1; i >= 0; i--) { 69 aliases[i] = (aliasType) stack.popNode(); 70 } 71 return aliases; 72 } 73 74 private static SimpleNode[] nodes = 75 new SimpleNode[PythonGrammarTreeConstants.jjtNodeName.length]; 76 77 public SimpleNode openNode(int id) { 78 if (nodes[id] == null) 79 nodes[id] = new IdentityNode(id); 80 return nodes[id]; 81 } 82 83 84 public SimpleNode closeNode(SimpleNode n, int arity) throws Exception { 85 exprType value; 86 exprType[] exprs; 87 88 switch (n.getId()) { 89 case -1: 90 System.out.println("Illegal node"); 91 case JJTSINGLE_INPUT: 92 return new Interactive(makeStmts(arity)); 93 case JJTFILE_INPUT: 94 return new Module(makeStmts(arity)); 95 case JJTEVAL_INPUT: 96 return new Expression(makeExpr()); 97 98 case JJTNAME: 99 return new Name(n.getImage().toString(), Name.Load); 100 case JJTNUM: 101 return new Num((PyObject) n.getImage()); 102 case JJTSTRING: 103 return new Str(n.getImage().toString()); 104 105 case JJTSUITE: 106 stmtType[] stmts = new stmtType[arity]; 107 for (int i = arity-1; i >= 0; i--) { 108 stmts[i] = (stmtType) popNode(); 109 } 110 return new Suite(stmts); 111 case JJTEXPR_STMT: 112 value = makeExpr(); 113 if (arity > 1) { 114 exprs = makeExprs(arity-1); 115 ctx.setStore(exprs); 116 return new Assign(exprs, value); 117 } else { 118 return new Expr(value); 119 } 120 case JJTINDEX_OP: 121 sliceType slice = (sliceType) stack.popNode(); 122 value = makeExpr(); 123 return new Subscript(value, slice, Subscript.Load); 124 case JJTDOT_OP: 125 String attr = makeIdentifier(); 126 value = makeExpr(); 127 return new Attribute(value, attr, Attribute.Load); 128 case JJTDEL_STMT: 129 exprs = makeExprs(arity); 130 ctx.setDelete(exprs); 131 return new Delete(exprs); 132 case JJTPRINT_STMT: 133 boolean nl = true; 134 if (stack.nodeArity() == 0) 135 return new Print(null, null, true); 136 if (peekNode().getId() == JJTCOMMA) { 137 popNode(); 138 nl = false; 139 } 140 return new Print(null, makeExprs(), nl); 141 case JJTPRINTEXT_STMT: 142 nl = true; 143 if (peekNode().getId() == JJTCOMMA) { 144 popNode(); 145 nl = false; 146 } 147 exprs = makeExprs(stack.nodeArity()-1); 148 return new Print(makeExpr(), exprs, nl); 149 case JJTFOR_STMT: 150 stmtType[] orelse = null; 151 if (stack.nodeArity() == 4) 152 orelse = popSuite(); 153 stmtType[] body = popSuite(); 154 exprType iter = makeExpr(); 155 exprType target = makeExpr(); 156 ctx.setStore(target); 157 return new For(target, iter, body, orelse); 158 case JJTWHILE_STMT: 159 orelse = null; 160 if (stack.nodeArity() == 3) 161 orelse = popSuite(); 162 body = popSuite(); 163 exprType test = makeExpr(); 164 return new While(test, body, orelse); 165 case JJTIF_STMT: 166 orelse = null; 167 if (arity % 2 == 1) 168 orelse = popSuite(); 169 body = popSuite(); 170 test = makeExpr(); 171 If last = new If(test, body, orelse); 172 for (int i = 0; i < (arity / 2)-1; i++) { 173 body = popSuite(); 174 test = makeExpr(); 175 last = new If(test, body, new stmtType[] { last }); 176 } 177 return last; 178 case JJTPASS_STMT: 179 return new Pass(); 180 case JJTBREAK_STMT: 181 return new Break(); 182 case JJTCONTINUE_STMT: 183 return new Continue(); 184 case JJTFUNCDEF: 185 body = popSuite(); 186 argumentsType arguments = makeArguments(arity - 2); 187 String name = makeIdentifier(); 188 return new FunctionDef(name, arguments, body); 189 case JJTDEFAULTARG: 190 value = (arity == 1) ? null : makeExpr(); 191 return new DefaultArg(makeExpr(), value); 192 case JJTEXTRAARGLIST: 193 return new ExtraArg(makeIdentifier(), JJTEXTRAARGLIST); 194 case JJTEXTRAKEYWORDLIST: 195 return new ExtraArg(makeIdentifier(), JJTEXTRAKEYWORDLIST); 196 204 case JJTCLASSDEF: 205 body = popSuite(); 206 exprType[] bases = makeExprs(stack.nodeArity() - 1); 207 name = makeIdentifier(); 208 return new ClassDef(name, bases, body); 209 case JJTRETURN_STMT: 210 value = arity == 1 ? makeExpr() : null; 211 return new Return(value); 212 case JJTYIELD_STMT: 213 return new Yield(makeExpr()); 214 case JJTRAISE_STMT: 215 exprType tback = arity >= 3 ? makeExpr() : null; 216 exprType inst = arity >= 2 ? makeExpr() : null; 217 exprType type = arity >= 1 ? makeExpr() : null; 218 return new Raise(type, inst, tback); 219 case JJTGLOBAL_STMT: 220 return new Global(makeIdentifiers()); 221 case JJTEXEC_STMT: 222 exprType globals = arity >= 3 ? makeExpr() : null; 223 exprType locals = arity >= 2 ? makeExpr() : null; 224 value = makeExpr(); 225 return new Exec(value, locals, globals); 226 case JJTASSERT_STMT: 227 exprType msg = arity == 2 ? makeExpr() : null; 228 test = makeExpr(); 229 return new Assert(test, msg); 230 case JJTTRYFINALLY_STMT: 231 orelse = popSuite(); 232 return new TryFinally(popSuite(), orelse); 233 case JJTTRY_STMT: 234 orelse = null; 235 if (peekNode() instanceof Suite) { 236 arity--; 237 orelse = popSuite(); 238 } 239 int l = arity - 1; 240 excepthandlerType[] handlers = new excepthandlerType[l]; 241 for (int i = l - 1; i >= 0; i--) { 242 handlers[i] = (excepthandlerType) popNode(); 243 } 244 return new TryExcept(popSuite(), handlers, orelse); 245 case JJTEXCEPT_CLAUSE: 246 body = popSuite(); 247 exprType excname = arity == 3 ? makeExpr() : null; 248 if (excname != null) 249 ctx.setStore(excname); 250 type = arity >= 2 ? makeExpr() : null; 251 return new excepthandlerType(type, excname, body); 252 case JJTOR_BOOLEAN: 253 return new BoolOp(BoolOp.Or, makeExprs()); 254 case JJTAND_BOOLEAN: 255 return new BoolOp(BoolOp.And, makeExprs()); 256 case JJTCOMPARISION: 257 l = arity / 2; 258 exprType[] comparators = new exprType[l]; 259 int[] ops = new int[l]; 260 for (int i = l-1; i >= 0; i--) { 261 comparators[i] = makeExpr(); 262 SimpleNode op = (SimpleNode) stack.popNode(); 263 switch (op.getId()) { 264 case JJTLESS_CMP: ops[i] = Compare.Lt; break; 265 case JJTGREATER_CMP: ops[i] = Compare.Gt; break; 266 case JJTEQUAL_CMP: ops[i] = Compare.Eq; break; 267 case JJTGREATER_EQUAL_CMP: ops[i] = Compare.GtE; break; 268 case JJTLESS_EQUAL_CMP: ops[i] = Compare.LtE; break; 269 case JJTNOTEQUAL_CMP: ops[i] = Compare.NotEq; break; 270 case JJTIN_CMP: ops[i] = Compare.In; break; 271 case JJTNOT_IN_CMP: ops[i] = Compare.NotIn; break; 272 case JJTIS_NOT_CMP: ops[i] = Compare.IsNot; break; 273 case JJTIS_CMP: ops[i] = Compare.Is; break; 274 default: 275 throw new RuntimeException ("Unknown cmp op:" + op.getId()); 276 } 277 } 278 return new Compare(makeExpr(), ops, comparators); 279 case JJTLESS_CMP: 280 case JJTGREATER_CMP: 281 case JJTEQUAL_CMP: 282 case JJTGREATER_EQUAL_CMP: 283 case JJTLESS_EQUAL_CMP: 284 case JJTNOTEQUAL_CMP: 285 case JJTIN_CMP: 286 case JJTNOT_IN_CMP: 287 case JJTIS_NOT_CMP: 288 case JJTIS_CMP: 289 return n; 290 case JJTOR_2OP: 291 return makeBinOp(BinOp.BitOr); 292 case JJTXOR_2OP: 293 return makeBinOp(BinOp.BitXor); 294 case JJTAND_2OP: 295 return makeBinOp(BinOp.BitAnd); 296 case JJTLSHIFT_2OP: 297 return makeBinOp(BinOp.LShift); 298 case JJTRSHIFT_2OP: 299 return makeBinOp(BinOp.RShift); 300 case JJTADD_2OP: 301 return makeBinOp(BinOp.Add); 302 case JJTSUB_2OP: 303 return makeBinOp(BinOp.Sub); 304 case JJTMUL_2OP: 305 return makeBinOp(BinOp.Mult); 306 case JJTDIV_2OP: 307 return makeBinOp(BinOp.Div); 308 case JJTMOD_2OP: 309 return makeBinOp(BinOp.Mod); 310 case JJTPOW_2OP: 311 return makeBinOp(BinOp.Pow); 312 case JJTFLOORDIV_2OP: 313 return makeBinOp(BinOp.FloorDiv); 314 case JJTPOS_1OP: 315 return new UnaryOp(UnaryOp.UAdd, makeExpr()); 316 case JJTNEG_1OP: 317 return new UnaryOp(UnaryOp.USub, makeExpr()); 318 case JJTINVERT_1OP: 319 return new UnaryOp(UnaryOp.Invert, makeExpr()); 320 case JJTNOT_1OP: 321 return new UnaryOp(UnaryOp.Not, makeExpr()); 322 case JJTCALL_OP: 323 exprType starargs = null; 326 exprType kwargs = null; 327 328 l = arity - 1; 329 if (l > 0 && peekNode().getId() == JJTEXTRAKEYWORDVALUELIST) { 330 kwargs = ((ExtraArgValue) popNode()).value; 331 l--; 332 } 333 if (l > 0 && peekNode().getId() == JJTEXTRAARGVALUELIST) { 334 starargs = ((ExtraArgValue) popNode()).value; 335 l--; 336 } 337 338 int nargs = l; 339 340 SimpleNode[] tmparr = new SimpleNode[l]; 341 for (int i = l - 1; i >= 0; i--) { 342 tmparr[i] = popNode(); 343 if (tmparr[i] instanceof keywordType) { 344 nargs = i; 345 } 346 } 347 348 exprType[] args = new exprType[nargs]; 349 for (int i = 0; i < nargs; i++) { 350 args[i] = makeExpr(tmparr[i]); 351 } 352 353 keywordType[] keywords = new keywordType[l - nargs]; 354 for (int i = nargs; i < l; i++) { 355 if (!(tmparr[i] instanceof keywordType)) 356 throw new ParseException( 357 "non-keyword argument following keyword", tmparr[i]); 358 keywords[i - nargs] = (keywordType) tmparr[i]; 359 } 360 exprType func = makeExpr(); 361 return new Call(func, args, keywords, starargs, kwargs); 362 case JJTEXTRAKEYWORDVALUELIST: 363 return new ExtraArgValue(makeExpr(), JJTEXTRAKEYWORDVALUELIST); 364 case JJTEXTRAARGVALUELIST: 365 return new ExtraArgValue(makeExpr(), JJTEXTRAARGVALUELIST); 366 case JJTKEYWORD: 367 value = makeExpr(); 368 name = makeIdentifier(); 369 return new keywordType(name, value); 370 case JJTTUPLE: 371 return new Tuple(makeExprs(), Tuple.Load); 372 case JJTLIST: 373 if (stack.nodeArity() > 0 && peekNode() instanceof listcompType) { 374 listcompType[] generators = new listcompType[arity-1]; 375 for (int i = arity-2; i >= 0; i--) { 376 generators[i] = (listcompType) popNode(); 377 } 378 return new ListComp(makeExpr(), generators); 379 } 380 return new List(makeExprs(), List.Load); 381 case JJTDICTIONARY: 382 l = arity / 2; 383 exprType[] keys = new exprType[l]; 384 exprType[] vals = new exprType[l]; 385 for (int i = l - 1; i >= 0; i--) { 386 vals[i] = makeExpr(); 387 keys[i] = makeExpr(); 388 } 389 return new Dict(keys, vals); 390 case JJTSTR_1OP: 391 return new Repr(makeExpr()); 392 case JJTSTRJOIN: 393 String str2 = ((Str) popNode()).s; 394 String str1 = ((Str) popNode()).s; 395 return new Str(str1 + str2); 396 case JJTLAMBDEF: 397 test = makeExpr(); 398 arguments = makeArguments(arity - 1); 399 return new Lambda(arguments, test); 400 case JJTELLIPSES: 401 return new Ellipsis(); 402 case JJTSLICE: 403 SimpleNode[] arr = new SimpleNode[arity]; 404 for (int i = arity-1; i >= 0; i--) { 405 arr[i] = popNode(); 406 } 407 408 exprType[] values = new exprType[3]; 409 int k = 0; 410 for (int j = 0; j < arity; j++) { 411 if (arr[j].getId() == JJTCOLON) 412 k++; 413 else 414 values[k] = makeExpr(arr[j]); 415 } 416 if (k == 0) { 417 return new Index(values[0]); 418 } else { 419 return new Slice(values[0], values[1], values[2]); 420 } 421 case JJTSUBSCRIPTLIST: 422 sliceType[] dims = new sliceType[arity]; 423 for (int i = arity - 1; i >= 0; i--) { 424 dims[i] = (sliceType) popNode(); 425 } 426 return new ExtSlice(dims); 427 case JJTAUG_PLUS: 428 return makeAugAssign(AugAssign.Add); 429 case JJTAUG_MINUS: 430 return makeAugAssign(AugAssign.Sub); 431 case JJTAUG_MULTIPLY: 432 return makeAugAssign(AugAssign.Mult); 433 case JJTAUG_DIVIDE: 434 return makeAugAssign(AugAssign.Div); 435 case JJTAUG_MODULO: 436 return makeAugAssign(AugAssign.Mod); 437 case JJTAUG_AND: 438 return makeAugAssign(AugAssign.BitAnd); 439 case JJTAUG_OR: 440 return makeAugAssign(AugAssign.BitOr); 441 case JJTAUG_XOR: 442 return makeAugAssign(AugAssign.BitXor); 443 case JJTAUG_LSHIFT: 444 return makeAugAssign(AugAssign.LShift); 445 case JJTAUG_RSHIFT: 446 return makeAugAssign(AugAssign.RShift); 447 case JJTAUG_POWER: 448 return makeAugAssign(AugAssign.Pow); 449 case JJTAUG_FLOORDIVIDE: 450 return makeAugAssign(AugAssign.FloorDiv); 451 case JJTLIST_FOR: 452 exprType[] ifs = new exprType[arity-2]; 453 for (int i = arity-3; i >= 0; i--) { 454 ifs[i] = makeExpr(); 455 } 456 iter = makeExpr(); 457 target = makeExpr(); 458 ctx.setStore(target); 459 return new listcompType(target, iter, ifs); 460 case JJTIMPORTFROM: 461 aliasType[] aliases = makeAliases(arity - 1); 462 String module = makeIdentifier(); 463 return new ImportFrom(module, aliases); 464 case JJTIMPORT: 465 return new Import(makeAliases()); 466 467 case JJTDOTTED_NAME: 468 StringBuffer sb = new StringBuffer (); 469 for (int i = 0; i < arity; i++) { 470 if (i > 0) 471 sb.insert(0, '.'); 472 sb.insert(0, makeIdentifier()); 473 } 474 return new Name(sb.toString(), Name.Load); 475 476 case JJTDOTTED_AS_NAME: 477 String asname = null; 478 if (arity > 1) 479 asname = makeIdentifier(); 480 return new aliasType(makeIdentifier(), asname); 481 482 case JJTIMPORT_AS_NAME: 483 asname = null; 484 if (arity > 1) 485 asname = makeIdentifier(); 486 return new aliasType(makeIdentifier(), asname); 487 case JJTCOMMA: 488 case JJTCOLON: 489 return n; 490 default: 491 return null; 492 } 493 } 494 495 private stmtType makeAugAssign(int op) throws Exception { 496 exprType value = makeExpr(); 497 exprType target = makeExpr(); 498 ctx.setAugStore(target); 499 return new AugAssign(target, op, value); 500 } 501 502 private void dumpStack() { 503 int n = stack.nodeArity(); 504 System.out.println("nodeArity:" + n); 505 if (n > 0) { 506 System.out.println("peek:" + stack.peekNode()); 507 } 508 } 509 510 SimpleNode peekNode() { 511 return (SimpleNode) stack.peekNode(); 512 } 513 514 SimpleNode popNode() { 515 return (SimpleNode) stack.popNode(); 516 } 517 518 BinOp makeBinOp(int op) { 519 exprType right = makeExpr(); 520 exprType left = makeExpr(); 521 return new BinOp(left, op, right); 522 } 523 524 argumentsType makeArguments(int l) throws Exception { 525 String kwarg = null; 526 String stararg = null; 527 if (l > 0 && peekNode().getId() == JJTEXTRAKEYWORDLIST) { 528 kwarg = ((ExtraArg) popNode()).name; 529 l--; 530 } 531 if (l > 0 && peekNode().getId() == JJTEXTRAARGLIST) { 532 stararg = ((ExtraArg) popNode()).name; 533 l--; 534 } 535 int startofdefaults = l; 536 exprType fpargs[] = new exprType[l]; 537 exprType defaults[] = new exprType[l]; 538 for (int i = l-1; i >= 0; i--) { 539 DefaultArg node = (DefaultArg) popNode(); 540 fpargs[i] = node.parameter; 541 ctx.setStore(fpargs[i]); 542 defaults[i] = node.value; 543 if (node.value != null) 544 startofdefaults = i; 545 } 546 exprType[] newdefs = new exprType[l-startofdefaults]; 548 System.arraycopy(defaults, startofdefaults, newdefs, 0, newdefs.length); 549 550 return new argumentsType(fpargs, stararg, kwarg, newdefs); 551 } 552 } 553 554 class DefaultArg extends SimpleNode { 555 public exprType parameter; 556 public exprType value; 557 DefaultArg(exprType parameter, exprType value) { 558 this.parameter = parameter; 559 this.value = value; 560 } 561 } 562 563 class ExtraArg extends SimpleNode { 564 public String name; 565 public int id; 566 ExtraArg(String name, int id) { 567 this.name = name; 568 this.id = id; 569 } 570 public int getId() { 571 return id; 572 } 573 } 574 575 576 class ExtraArgValue extends SimpleNode { 577 public exprType value; 578 public int id; 579 ExtraArgValue(exprType value, int id) { 580 this.value = value; 581 this.id = id; 582 } 583 public int getId() { 584 return id; 585 } 586 } 587 588 589 class IdentityNode extends SimpleNode { 590 public int id; 591 public Object image; 592 593 IdentityNode(int id) { 594 this.id = id; 595 } 596 597 public int getId() { 598 return id; 599 } 600 601 public void setImage(Object image) { 602 this.image = image; 603 } 604 605 public Object getImage() { 606 return image; 607 } 608 609 public String toString() { 610 return "IdNode[" + PythonGrammarTreeConstants.jjtNodeName[id] + ", " + 611 image + "]"; 612 } 613 } 614 615 class CtxVisitor extends Visitor { 616 private int ctx; 617 618 public CtxVisitor() { } 619 620 public void setStore(SimpleNode node) throws Exception { 621 this.ctx = expr_contextType.Store; 622 visit(node); 623 } 624 625 public void setStore(SimpleNode[] nodes) throws Exception { 626 for (int i = 0; i < nodes.length; i++) 627 setStore(nodes[i]); 628 } 629 630 public void setDelete(SimpleNode node) throws Exception { 631 this.ctx = expr_contextType.Del; 632 visit(node); 633 } 634 635 public void setDelete(SimpleNode[] nodes) throws Exception { 636 for (int i = 0; i < nodes.length; i++) 637 setDelete(nodes[i]); 638 } 639 640 public void setAugStore(SimpleNode node) throws Exception { 641 this.ctx = expr_contextType.AugStore; 642 visit(node); 643 } 644 645 public Object visitName(Name node) throws Exception { 646 node.ctx = ctx; 647 return null; 648 } 649 650 public Object visitAttribute(Attribute node) throws Exception { 651 node.ctx = ctx; 652 return null; 653 } 654 655 public Object visitSubscript(Subscript node) throws Exception { 656 node.ctx = ctx; 657 return null; 658 } 659 660 public Object visitList(List node) throws Exception { 661 if (ctx == expr_contextType.AugStore) { 662 throw new ParseException( 663 "augmented assign to list not possible", node); 664 } 665 node.ctx = ctx; 666 traverse(node); 667 return null; 668 } 669 670 public Object visitTuple(Tuple node) throws Exception { 671 if (ctx == expr_contextType.AugStore) { 672 throw new ParseException( 673 "augmented assign to tuple not possible", node); 674 } 675 node.ctx = ctx; 676 traverse(node); 677 return null; 678 } 679 680 public Object visitCall(Call node) throws Exception { 681 throw new ParseException("can't assign to function call", node); 682 } 683 684 public Object visitListComp(Call node) throws Exception { 685 throw new ParseException("can't assign to list comprehension call", 686 node); 687 } 688 689 public Object unhandled_node(SimpleNode node) throws Exception { 690 throw new ParseException("can't assign to operator", node); 691 } 692 } 693 | Popular Tags |