@@ -184,25 +184,28 @@ import java.util.Arrays;
184
184
185
185
186
186
@parser::members {
187
+ private static class LoopState {
188
+ public boolean containsBreak;
189
+ public boolean containsContinue;
190
+ }
187
191
private PythonSSTNodeFactory factory;
188
192
private ScopeEnvironment scopeEnvironment;
189
- boolean containsBreak;
190
- boolean containsContinue;
191
-
192
- public final boolean startLoopBreak() {
193
- try {
194
- return containsBreak;
195
- } finally {
196
- containsBreak = false ;
197
- }
193
+ private LoopState loopState;
194
+
195
+ public final LoopState startLoop() {
196
+ try {
197
+ return loopState;
198
+ } finally {
199
+ loopState = new LoopState();
200
+ }
198
201
}
199
202
200
- public final boolean startLoopContinue () {
203
+ public final LoopState saveLoopState () {
201
204
try {
202
- return containsContinue ;
203
- } finally {
204
- containsContinue = false ;
205
- }
205
+ return loopState ;
206
+ } finally {
207
+ loopState = null ;
208
+ }
206
209
}
207
210
208
211
private Object[] stack = new Object[8];
@@ -326,6 +329,7 @@ locals
326
329
scopeEnvironment.pushScope(_localctx.toString(), ScopeInfo.ScopeKind.Module);
327
330
}
328
331
}
332
+ { loopState = null; }
329
333
{ int start = start(); }
330
334
(
331
335
NEWLINE
@@ -345,6 +349,7 @@ locals
345
349
[ com.oracle.graal.python.parser.ScopeInfo scope, ArrayList<StatementNode> list ]
346
350
:
347
351
{ _localctx.scope = scopeEnvironment.pushScope(_localctx.toString(), ScopeInfo.ScopeKind.Module); }
352
+ { loopState = null; }
348
353
{ int start = start(); }
349
354
(
350
355
NEWLINE
@@ -411,13 +416,15 @@ funcdef
411
416
ScopeInfo enclosingScope = scopeEnvironment.getCurrentScope();
412
417
String enclosingClassName = enclosingScope.isInClassScope() ? enclosingScope.getScopeId() : null;
413
418
ScopeInfo functionScope = scopeEnvironment.pushScope(name, ScopeInfo.ScopeKind.Function);
419
+ LoopState savedLoopState = saveLoopState();
414
420
functionScope.setHasAnnotations(true );
415
421
$parameters.result.defineParamsInScope(functionScope);
416
422
}
417
423
s = suite
418
424
{
419
425
SSTNode funcDef = new FunctionDefSSTNode(scopeEnvironment.getCurrentScope(), name, enclosingClassName, $parameters.result, $s.result, getStartIndex(_localctx), getStopIndex(((FuncdefContext)_localctx).s));
420
- scopeEnvironment.popScope();
426
+ scopeEnvironment.popScope();
427
+ loopState = savedLoopState;
421
428
push(funcDef);
422
429
}
423
430
;
@@ -675,14 +682,20 @@ del_stmt
675
682
flow_stmt
676
683
:
677
684
b=' break'
678
- {
685
+ {
686
+ if (loopState == null) {
687
+ throw new PythonRecognitionException(" 'break' outside loop" , this, _input, _localctx, getCurrentToken());
688
+ }
679
689
push(new SimpleSSTNode(SimpleSSTNode.Type.BREAK , getStartIndex($b), getStopIndex($b)));
680
- containsBreak = true ;
690
+ loopState. containsBreak = true;
681
691
}
682
692
| c=' continue'
683
- {
693
+ {
694
+ if (loopState == null) {
695
+ throw new PythonRecognitionException(" 'continue' not properly in loop" , this, _input, _localctx, getCurrentToken());
696
+ }
684
697
push(new SimpleSSTNode(SimpleSSTNode.Type.CONTINUE , getStartIndex($c), getStopIndex($c)));
685
- containsContinue = true ;
698
+ loopState. containsContinue = true;
686
699
}
687
700
| return_stmt
688
701
| raise_stmt
@@ -853,12 +866,11 @@ elif_stmt returns [SSTNode result]
853
866
while_stmt
854
867
:
855
868
' while' test ' :'
856
- { boolean bFlag = startLoopBreak(); boolean cFlag = startLoopContinue (); }
869
+ { LoopState savedState = startLoop (); }
857
870
suite
858
871
{
859
- WhileSSTNode result = new WhileSSTNode($test.result, $suite.result, containsContinue, containsBreak, getStartIndex($ctx),getStopIndex($suite.stop));
860
- containsContinue = cFlag;
861
- containsBreak = bFlag;
872
+ WhileSSTNode result = new WhileSSTNode($test.result, $suite.result, loopState.containsContinue, loopState.containsBreak, getStartIndex($ctx),getStopIndex($suite.stop));
873
+ loopState = savedState;
862
874
}
863
875
(
864
876
' else' ' :' suite
@@ -875,13 +887,12 @@ while_stmt
875
887
for_stmt
876
888
:
877
889
' for' exprlist ' in' testlist ' :'
878
- { boolean bFlag = startLoopBreak(); boolean cFlag = startLoopContinue (); }
890
+ { LoopState savedState = startLoop (); }
879
891
suite
880
892
{
881
- ForSSTNode result = factory.createForSSTNode($exprlist.result, $testlist.result, $suite.result, containsContinue, getStartIndex($ctx),getStopIndex($suite.stop));
882
- result.setContainsBreak(containsBreak);
883
- containsContinue = cFlag;
884
- containsBreak = bFlag;
893
+ ForSSTNode result = factory.createForSSTNode($exprlist.result, $testlist.result, $suite.result, loopState.containsContinue, getStartIndex($ctx),getStopIndex($suite.stop));
894
+ result.setContainsBreak(loopState.containsBreak);
895
+ loopState = savedState;
885
896
}
886
897
(
887
898
' else' ' :' suite
@@ -1478,9 +1489,11 @@ locals [ com.oracle.graal.python.parser.ScopeInfo scope ]
1478
1489
factory.getScopeEnvironment().createLocal($NAME.text);
1479
1490
ScopeInfo classScope = scopeEnvironment.pushScope($NAME.text, ScopeInfo.ScopeKind.Class);
1480
1491
}
1492
+ { LoopState savedLoopState = saveLoopState(); }
1481
1493
' :' suite
1482
1494
{ push(factory.createClassDefinition($NAME.text, baseClasses, $suite.result, getStartIndex($ctx), getStopIndex($suite.stop))); }
1483
- {scopeEnvironment.popScope(); }
1495
+ { scopeEnvironment.popScope(); }
1496
+ { loopState = savedLoopState; }
1484
1497
;
1485
1498
1486
1499
arglist returns [ArgListBuilder result]
0 commit comments