KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > python > parser > TreeBuilder


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 JavaDoc makeIdentifier() {
50         return ((Name) stack.popNode()).id;
51     }
52
53     private String JavaDoc[] makeIdentifiers() {
54         int l = stack.nodeArity();
55         String JavaDoc[] ids = new String JavaDoc[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 JavaDoc {
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 JavaDoc 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 JavaDoc 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 /*
197         case JJTFPLIST:
198             fpdefType[] list = new fpdefType[arity];
199             for (int i = arity-1; i >= 0; i--) {
200                 list[i] = popFpdef();
201             }
202             return new FpList(list);
203 */

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 JavaDoc("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             //if (arity == 1)
324
// return new Call(makeExpr(), null, null, null, null);
325
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 JavaDoc str2 = ((Str) popNode()).s;
394             String JavaDoc 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 JavaDoc module = makeIdentifier();
463             return new ImportFrom(module, aliases);
464         case JJTIMPORT:
465             return new Import(makeAliases());
466     
467         case JJTDOTTED_NAME:
468             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
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 JavaDoc 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 JavaDoc {
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 JavaDoc {
525         String JavaDoc kwarg = null;
526         String JavaDoc 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 //System.out.println("start "+ startofdefaults + " " + l);
547
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 JavaDoc name;
565     public int id;
566     ExtraArg(String JavaDoc 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 JavaDoc 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 JavaDoc image) {
602         this.image = image;
603     }
604
605     public Object JavaDoc getImage() {
606         return image;
607     }
608
609     public String JavaDoc 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 JavaDoc {
621         this.ctx = expr_contextType.Store;
622         visit(node);
623     }
624
625     public void setStore(SimpleNode[] nodes) throws Exception JavaDoc {
626         for (int i = 0; i < nodes.length; i++)
627             setStore(nodes[i]);
628     }
629
630     public void setDelete(SimpleNode node) throws Exception JavaDoc {
631         this.ctx = expr_contextType.Del;
632         visit(node);
633     }
634
635     public void setDelete(SimpleNode[] nodes) throws Exception JavaDoc {
636         for (int i = 0; i < nodes.length; i++)
637             setDelete(nodes[i]);
638     }
639
640     public void setAugStore(SimpleNode node) throws Exception JavaDoc {
641         this.ctx = expr_contextType.AugStore;
642         visit(node);
643     }
644
645     public Object JavaDoc visitName(Name node) throws Exception JavaDoc {
646         node.ctx = ctx;
647         return null;
648     }
649
650     public Object JavaDoc visitAttribute(Attribute node) throws Exception JavaDoc {
651         node.ctx = ctx;
652         return null;
653     }
654
655     public Object JavaDoc visitSubscript(Subscript node) throws Exception JavaDoc {
656         node.ctx = ctx;
657         return null;
658     }
659
660     public Object JavaDoc visitList(List node) throws Exception JavaDoc {
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 JavaDoc visitTuple(Tuple node) throws Exception JavaDoc {
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 JavaDoc visitCall(Call node) throws Exception JavaDoc {
681         throw new ParseException("can't assign to function call", node);
682     }
683
684     public Object JavaDoc visitListComp(Call node) throws Exception JavaDoc {
685         throw new ParseException("can't assign to list comprehension call",
686                                  node);
687     }
688
689     public Object JavaDoc unhandled_node(SimpleNode node) throws Exception JavaDoc {
690         throw new ParseException("can't assign to operator", node);
691     }
692 }
693
Popular Tags