| CODENOTIFIER | HelpYou are not signed inSign in |
Project: Jython
Revision: 5223
Author: fwierzbicki
Date: 20 Aug 2008 15:57:39
Changes:Start of list comprehensions and generator expressions.
Files:| ... | ...@@ -78,17 +78,7 @@ | |
| 78 | 78 | PYNODE; |
| 79 | 79 | Interactive; |
| 80 | 80 | Expression; |
| 81 | Ellipsis; | |
| 82 | ListComp; | |
| 83 | Target; | |
| 84 | 81 | GeneratorExp; |
| 85 | Ifs; | |
| 86 | Elts; | |
| 87 | ||
| 88 | GenFor; | |
| 89 | GenIf; | |
| 90 | ListIf; | |
| 91 | ||
| 92 | 82 | } |
| 93 | 83 | |
| 94 | 84 | @header { |
| ... | ...@@ -133,6 +123,7 @@ | |
| 133 | 123 | import org.python.antlr.ast.ImportFrom; |
| 134 | 124 | import org.python.antlr.ast.Index; |
| 135 | 125 | import org.python.antlr.ast.keywordType; |
| 126 | import org.python.antlr.ast.ListComp; | |
| 136 | 127 | import org.python.antlr.ast.Lambda; |
| 137 | 128 | import org.python.antlr.ast.modType; |
| 138 | 129 | import org.python.antlr.ast.Module; |
| ... | ...@@ -162,6 +153,7 @@ | |
| 162 | 153 | import org.python.core.PyUnicode; |
| 163 | 154 | |
| 164 | 155 | import java.math.BigInteger; |
| 156 | import java.util.Collections; | |
| 165 | 157 | import java.util.Iterator; |
| 166 | 158 | import java.util.ListIterator; |
| 167 | 159 | } |
| ... | ...@@ -1011,26 +1003,37 @@ | |
| 1011 | 1003 | ; |
| 1012 | 1004 | |
| 1013 | 1005 | //listmaker: test ( list_for | (',' test)* [','] ) |
| 1014 | listmaker returns [exprType etype] | |
| 1006 | listmaker | |
| 1007 | @init { | |
| 1008 | List gens = new ArrayList(); | |
| 1009 | exprType etype = null; | |
| 1010 | } | |
| 1015 | 1011 | @after { |
| 1016 | $listmaker.tree = $etype; | |
| 1012 | $listmaker.tree = etype; | |
| 1017 | 1013 | } |
| 1018 | 1014 | : t+=test[expr_contextType.Load] |
| 1019 | ( list_for -> ^(ListComp test list_for) | |
| 1015 | ( list_for[gens] { | |
| 1016 | Collections.reverse(gens); | |
| 1017 | comprehensionType[] c = (comprehensionType[])gens.toArray(new comprehensionType[gens.size()]); | |
| 1018 | etype = new ListComp($listmaker.start, (exprType)$t.get(0), c); | |
| 1019 | } | |
| 1020 | 1020 | | (options {greedy=true;}:COMMA t+=test[expr_contextType.Load])* { |
| 1021 | $etype = new org.python.antlr.ast.List($listmaker.start, actions.makeExprs($t), $expr::ctype); | |
| 1021 | etype = new org.python.antlr.ast.List($listmaker.start, actions.makeExprs($t), $expr::ctype); | |
| 1022 | 1022 | } |
| 1023 | 1023 | ) (COMMA)? |
| 1024 | 1024 | ; |
| 1025 | 1025 | |
| 1026 | 1026 | //testlist_gexp: test ( gen_for | (',' test)* [','] ) |
| 1027 | 1027 | testlist_gexp |
| 1028 | @init { | |
| 1029 | List gens = new ArrayList(); | |
| 1030 | } | |
| 1028 | 1031 | : t+=test[expr_contextType.Load] |
| 1029 | 1032 | ( ((options {k=2;}: c1=COMMA t+=test[expr_contextType.Load])* (c2=COMMA)? |
| 1030 | 1033 | -> { $c1 != null || $c2 != null }? ^(PYNODE<Tuple>[$testlist_gexp.start, actions.makeExprs($t), $expr::ctype]) |
| 1031 | 1034 | -> test |
| 1032 | 1035 | ) |
| 1033 | | ( gen_for -> ^(GeneratorExp test gen_for) | |
| 1036 | | ( gen_for[gens] -> ^(GeneratorExp test gen_for) | |
| 1034 | 1037 | ) |
| 1035 | 1038 | ) |
| 1036 | 1039 | ; |
| ... | ...@@ -1194,44 +1197,73 @@ | |
| 1194 | 1197 | |
| 1195 | 1198 | //argument: test [gen_for] | test '=' test # Really [keyword '='] test |
| 1196 | 1199 | argument[List arguments, List kws] |
| 1200 | @init { | |
| 1201 | List gens = new ArrayList(); | |
| 1202 | } | |
| 1197 | 1203 | : t1=test[expr_contextType.Load] |
| 1198 | 1204 | ( (ASSIGN t2=test[expr_contextType.Load]) { |
| 1199 | 1205 | $kws.add(new exprType[]{(exprType)$t1.tree, (exprType)$t2.tree}); |
| 1200 | 1206 | } |
| 1201 | | gen_for //FIXME | |
| 1207 | | gen_for[gens] //FIXME | |
| 1202 | 1208 | | {$arguments.add($t1.tree);} |
| 1203 | 1209 | ) |
| 1204 | 1210 | ; |
| 1205 | 1211 | |
| 1206 | 1212 | //list_iter: list_for | list_if |
| 1207 | list_iter : list_for | |
| 1208 | | list_if | |
| 1209 | ; | |
| 1213 | list_iter [List gens] returns [exprType etype] | |
| 1214 | : list_for[gens] | |
| 1215 | | list_if[gens] { | |
| 1216 | $etype = $list_if.etype; | |
| 1217 | } | |
| 1218 | ; | |
| 1210 | 1219 | |
| 1211 | 1220 | //list_for: 'for' exprlist 'in' testlist_safe [list_iter] |
| 1212 | list_for : FOR exprlist[expr_contextType.Load] IN testlist[expr_contextType.Load] (list_iter)? | |
| 1213 | -> ^(FOR<comprehensionType>[$FOR, $exprlist.etype, (exprType)$testlist.tree, null]) | |
| 1214 | ; | |
| 1221 | list_for [List gens] | |
| 1222 | : FOR exprlist[expr_contextType.Load] IN testlist[expr_contextType.Load] (list_iter[gens])? { | |
| 1223 | exprType[] e; | |
| 1224 | if ($list_iter.etype != null) { | |
| 1225 | e = new exprType[]{$list_iter.etype}; | |
| 1226 | } else { | |
| 1227 | e = new exprType[0]; | |
| 1228 | } | |
| 1229 | gens.add(new comprehensionType($FOR, $exprlist.etype, (exprType)$testlist.tree, e)); | |
| 1230 | } | |
| 1231 | ; | |
| 1215 | 1232 | |
| 1216 | 1233 | //list_if: 'if' test [list_iter] |
| 1217 | list_if : IF test[expr_contextType.Load] (list_iter)? | |
| 1218 | -> ^(ListIf ^(Target test) (Ifs list_iter)?) | |
| 1219 | ; | |
| 1234 | list_if[List gens] returns [exprType etype] | |
| 1235 | : IF test[expr_contextType.Load] (list_iter[gens])? { | |
| 1236 | $etype = (exprType)$test.tree; | |
| 1237 | } | |
| 1238 | ; | |
| 1220 | 1239 | |
| 1221 | 1240 | //gen_iter: gen_for | gen_if |
| 1222 | gen_iter: gen_for | |
| 1223 | | gen_if | |
| 1224 | ; | |
| 1241 | gen_iter [List gens] returns [exprType etype] | |
| 1242 | : gen_for[gens] | |
| 1243 | | gen_if[gens] { | |
| 1244 | $etype = $gen_if.etype; | |
| 1245 | } | |
| 1246 | ; | |
| 1225 | 1247 | |
| 1226 | 1248 | //gen_for: 'for' exprlist 'in' or_test [gen_iter] |
| 1227 | gen_for: FOR exprlist[expr_contextType.Load] IN or_test[expr_contextType.Load] gen_iter? | |
| 1228 | -> ^(GenFor ^(Target exprlist) ^(IN or_test) ^(Ifs gen_iter)?) | |
| 1249 | gen_for [List gens] | |
| 1250 | :FOR exprlist[expr_contextType.Load] IN or_test[expr_contextType.Load] gen_iter[gens]? { | |
| 1251 | exprType[] e; | |
| 1252 | if ($gen_iter.etype != null) { | |
| 1253 | e = new exprType[]{$gen_iter.etype}; | |
| 1254 | } else { | |
| 1255 | e = new exprType[0]; | |
| 1256 | } | |
| 1257 | gens.add(new comprehensionType($FOR, $exprlist.etype, (exprType)$or_test.tree, e)); | |
| 1258 | } | |
| 1229 | 1259 | ; |
| 1230 | 1260 | |
| 1231 | 1261 | //gen_if: 'if' old_test [gen_iter] |
| 1232 | gen_if: IF test[expr_contextType.Load] gen_iter? | |
| 1233 | -> ^(GenIf ^(Target test) ^(Ifs gen_iter)?) | |
| 1234 | ; | |
| 1262 | gen_if[List gens] returns [exprType etype] | |
| 1263 | : IF test[expr_contextType.Load] gen_iter[gens]? { | |
| 1264 | $etype = (exprType)$test.tree; | |
| 1265 | } | |
| 1266 | ; | |
| 1235 | 1267 | |
| 1236 | 1268 | //yield_expr: 'yield' [testlist] |
| 1237 | 1269 | yield_expr : YIELD testlist[expr_contextType.Load]? |
| ... | ...@@ -318,9 +318,7 @@ | |
| 318 | 318 | change to grammar files. If you are working on the grammars you might |
| 319 | 319 | want to comment this out, as a clean is really only needed if you change |
| 320 | 320 | the tokens defined in Python.g (and cleans make the build slow) --> |
| 321 | <antcall target="clean"/> | |
| 322 | 321 | <!-- force jarjar build --> |
| 323 | <property name="jarjar.needed" value="true" /> | |
| 324 | 322 | </target> |
| 325 | 323 | |
| 326 | 324 | <target name ="prepare-output" depends="init,needed-check,clean-if-antlr-needed,make-output-dirs"/> |