diff --git a/src/org/rascalmpl/library/util/ErrorRecovery.java b/src/org/rascalmpl/library/util/ErrorRecovery.java index b1d3aa6783f..5d116f0e70e 100644 --- a/src/org/rascalmpl/library/util/ErrorRecovery.java +++ b/src/org/rascalmpl/library/util/ErrorRecovery.java @@ -48,17 +48,17 @@ public ScoredTree(IConstructor tree, int score) { */ public IConstructor disambiguateErrors(IConstructor arg, IBool allowAmbiguity) { - return disambiguate(arg, allowAmbiguity.getValue(), new HashMap<>()).tree; + return disambiguate(arg, allowAmbiguity.getValue(), true, new HashMap<>()).tree; } - private ScoredTree disambiguate(IConstructor tree, boolean allowAmbiguity, Map processedTrees) { + private ScoredTree disambiguate(IConstructor tree, boolean allowAmbiguity, boolean buildTree, Map processedTrees) { Type type = tree.getConstructorType(); ScoredTree result; if (type == RascalValueFactory.Tree_Appl) { - result = disambiguateAppl((ITree) tree, allowAmbiguity, processedTrees); + result = disambiguateAppl((ITree) tree, allowAmbiguity, buildTree, processedTrees); } else if (type == RascalValueFactory.Tree_Amb) { - result = disambiguateAmb((ITree) tree, allowAmbiguity, processedTrees); + result = disambiguateAmb((ITree) tree, allowAmbiguity, buildTree, processedTrees); } else { // Other trees (cycle, char) do not have subtrees so they have a score of 0 result = new ScoredTree(tree, 0); @@ -67,7 +67,7 @@ private ScoredTree disambiguate(IConstructor tree, boolean allowAmbiguity, Map processedTrees) { + private ScoredTree disambiguateAppl(ITree appl, boolean allowAmbiguity, boolean buildTree, Map processedTrees) { ScoredTree result = processedTrees.get(appl); if (result != null) { return result; @@ -83,9 +83,9 @@ private ScoredTree disambiguateAppl(ITree appl, boolean allowAmbiguity, Map processedTrees) { + private ScoredTree disambiguateAmb(ITree amb, boolean allowAmbiguity, boolean buildTree, Map processedTrees) { ScoredTree result = processedTrees.get(amb); if (result != null) { return result; @@ -124,9 +124,10 @@ private ScoredTree disambiguateAmb(ITree amb, boolean allowAmbiguity, Map 1 && !allowAmbiguity) { // We have an ambiguity between non-error trees - if (!allowAmbiguity) { - throw new Ambiguous(resultTree); + resultTree = rascalValues.amb(remainingAlts); + throw new Ambiguous(resultTree); + } + + if (buildTree) { + if (remainingAlts.size() == originalAlts.size()) { + // All children are without errors, return the original tree + resultTree = amb; + } else if (remainingAlts.size() == 1) { + // One child without errors remains, dissolve the amb tree + resultTree = (ITree) remainingAlts.iterator().next(); + } else { + // Create a new amb tree with the remaining non-error trees + resultTree = rascalValues.amb(remainingAlts); } } @@ -219,6 +224,6 @@ private void collectAmbErrors(ITree amb, IListWriter errors, Set p } public void checkForRegularAmbiguities(IConstructor parseForest) { - disambiguate(parseForest, false, new HashMap<>()); + disambiguate(parseForest, false, false, new HashMap<>()); } }