diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/ATNSimulator.java b/runtime/Java/src/org/antlr/v4/runtime/atn/ATNSimulator.java index ccea2d07d..733fb5a39 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ATNSimulator.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ATNSimulator.java @@ -262,9 +262,11 @@ public abstract class ATNSimulator { int ndecisions = toInt(data[p++]); for (int i=1; i<=ndecisions; i++) { int s = toInt(data[p++]); + int nonGreedy = toInt(data[p++]); DecisionState decState = (DecisionState)atn.states.get(s); atn.decisionToState.add(decState); decState.decision = i-1; + decState.nonGreedy = nonGreedy != 0; } verifyATN(atn); diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/DecisionState.java b/runtime/Java/src/org/antlr/v4/runtime/atn/DecisionState.java index 161c978a1..38eb13173 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/DecisionState.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/DecisionState.java @@ -31,4 +31,5 @@ package org.antlr.v4.runtime.atn; public class DecisionState extends ATNState { public int decision = -1; + public boolean nonGreedy; } diff --git a/tool/src/org/antlr/v4/automata/ATNSerializer.java b/tool/src/org/antlr/v4/automata/ATNSerializer.java index 274e8b4af..4f3f28140 100644 --- a/tool/src/org/antlr/v4/automata/ATNSerializer.java +++ b/tool/src/org/antlr/v4/automata/ATNSerializer.java @@ -226,6 +226,7 @@ public class ATNSerializer { data.add(ndecisions); for (DecisionState decStartState : atn.decisionToState) { data.add(decStartState.stateNumber); + data.add(decStartState.nonGreedy ? 1 : 0); } return data; } @@ -299,6 +300,7 @@ public class ATNSerializer { int ndecisions = ATNSimulator.toInt(data[p++]); for (int i=1; i<=ndecisions; i++) { int s = ATNSimulator.toInt(data[p++]); + boolean nonGreedy = ATNSimulator.toInt(data[p++]) != 0; buf.append(i-1).append(":").append(s).append("\n"); } return buf.toString(); diff --git a/tool/src/org/antlr/v4/automata/ParserATNFactory.java b/tool/src/org/antlr/v4/automata/ParserATNFactory.java index ec16ad1b1..84a686f7f 100644 --- a/tool/src/org/antlr/v4/automata/ParserATNFactory.java +++ b/tool/src/org/antlr/v4/automata/ParserATNFactory.java @@ -425,10 +425,11 @@ public class ParserATNFactory implements ATNFactory { BlockStartState blkStart = (BlockStartState)blk.left; BlockAST blkAST = (BlockAST)optAST.getChild(0); - if (isGreedy(blkAST)) { + blkStart.nonGreedy = !isGreedy(blkAST); + + if (!blkStart.nonGreedy) { epsilon(blkStart, blk.right); - } - else { + } else { Transition existing = blkStart.removeTransition(0); epsilon(blkStart, blk.right); blkStart.addTransition(existing); @@ -463,7 +464,8 @@ public class ParserATNFactory implements ATNFactory { epsilon(blkEnd, loop); // blk can see loop back BlockAST blkAST = (BlockAST)plusAST.getChild(0); - if ( isGreedy(blkAST) ) { + loop.nonGreedy = !isGreedy(blkAST); + if ( !loop.nonGreedy ) { epsilon(loop, blkStart); // loop back to start epsilon(loop, end); // or exit } @@ -502,7 +504,8 @@ public class ParserATNFactory implements ATNFactory { end.loopBackState = loop; BlockAST blkAST = (BlockAST)starAST.getChild(0); - if ( isGreedy(blkAST) ) { + entry.nonGreedy = !isGreedy(blkAST); + if ( !entry.nonGreedy ) { epsilon(entry, blkStart); // loop enter edge (alt 1) epsilon(entry, end); // bypass loop edge (alt 2) }