Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes an issue related to prefix shared alternatives with nesting restrictions #1919

Merged
merged 1 commit into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ public str newGenerate(str package, str name, Grammar gr) {
' protected static class <value2id(s)> {
' public final static AbstractStackNode\<IConstructor\>[] EXPECTS;
' static{
' ExpectBuilder\<IConstructor\> builder = new ExpectBuilder\<IConstructor\>(_resultStoreIdMappings);
' ExpectBuilder\<IConstructor\> builder = new ExpectBuilder\<IConstructor\>(_dontNest, _resultStoreIdMappings);
' init(builder);
' EXPECTS = builder.buildExpectArray();
' }
Expand Down
278 changes: 139 additions & 139 deletions src/org/rascalmpl/library/lang/rascal/syntax/RascalParser.java

Large diffs are not rendered by default.

15 changes: 11 additions & 4 deletions src/org/rascalmpl/parser/gtd/preprocessing/ExpectBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

import org.rascalmpl.parser.gtd.stack.AbstractStackNode;
import org.rascalmpl.parser.gtd.util.DoubleArrayList;
import org.rascalmpl.parser.gtd.util.IntegerKeyedHashMap;
import org.rascalmpl.parser.gtd.util.IntegerList;
import org.rascalmpl.parser.gtd.util.IntegerMap;
import org.rascalmpl.parser.gtd.util.ObjectIntegerKeyedHashMap;
import org.rascalmpl.parser.gtd.util.SortedIntegerObjectList;
Expand All @@ -26,13 +28,15 @@
*/
@SuppressWarnings("cast")
public class ExpectBuilder<P>{
private final IntegerKeyedHashMap<IntegerList> dontNest;
private final IntegerMap resultStoreMappings;

private final SortedIntegerObjectList<DoubleArrayList<P, AbstractStackNode<P>[]>> alternatives;

public ExpectBuilder(IntegerMap resultStoreMappings){
public ExpectBuilder(IntegerKeyedHashMap<IntegerList> dontNest, IntegerMap resultStoreMappings){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Propose to include the old constructor as well @deprecated, such that we can bootstrap without too many issues.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a constructor with the old signature, which uses an empty dontNest map, would make the change backwards compatible and should make everything work as before.
I considered this myself, but ultimately decided against it, since it (naturally) also retains the bug. Making this a breaking change forces people to regenerate any existing parsers and prevents them from continuing to use a deprecated/buggy version.
But feel free to add one if this is preferred.

super();


this.dontNest = dontNest;
this.resultStoreMappings = resultStoreMappings;

alternatives = new SortedIntegerObjectList<DoubleArrayList<P, AbstractStackNode<P>[]>>();
Expand Down Expand Up @@ -86,7 +90,7 @@ public AbstractStackNode<P>[] buildExpectArray(){
AbstractStackNode<P> first = alternative[0];
int firstItemResultStoreId = resultStoreMappings.get(first.getId());

if(isSharable(production)){
if(isSharable(production) && dontNest.get(first.getId()) == null){
// Check if the first symbol in the alternative, with the same nesting restrictions, has been encountered before in another alternative.
sharedExpect = constructedExpects.get(first, firstItemResultStoreId);
}
Expand All @@ -105,10 +109,13 @@ public AbstractStackNode<P>[] buildExpectArray(){
int k = 1;
CHAIN: for(; k < alternative.length; ++k){
AbstractStackNode<P> alternativeItem = alternative[k];
if(dontNest.get(alternativeItem.getId()) != null) {
break; // Don't share items with nesting restrictions associated with them
}
int alternativeItemResultStoreId = resultStoreMappings.get(alternativeItem.getId());

AbstractStackNode<P> sharedExpectItem = sharedExpect[k];

// Can't share the current alternative's symbol with the shared alternative we are currently matching against; try all other possible continuations to find a potential match.
if(!alternativeItem.isEqual(sharedExpectItem) || alternativeItemResultStoreId != resultStoreMappings.get(sharedExpectItem.getId())){
AbstractStackNode<P>[][] otherSharedExpects = sharedExpectItem.getAlternateProductions();
Expand Down
9 changes: 5 additions & 4 deletions test/org/rascalmpl/test/parser/Ambiguous8.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.rascalmpl.parser.gtd.stack.AbstractStackNode;
import org.rascalmpl.parser.gtd.stack.LiteralStackNode;
import org.rascalmpl.parser.gtd.stack.NonTerminalStackNode;
import org.rascalmpl.parser.gtd.util.IntegerKeyedHashMap;
import org.rascalmpl.parser.gtd.util.IntegerMap;
import org.rascalmpl.parser.uptr.UPTRNodeFactory;
import io.usethesource.vallang.IConstructor;
Expand Down Expand Up @@ -64,29 +65,29 @@ public class Ambiguous8 extends SGTDBF<IConstructor, ITree, ISourceLocation> imp

private final static AbstractStackNode<IConstructor>[] S_EXPECTS;
static{
ExpectBuilder<IConstructor> sExpectBuilder = new ExpectBuilder<IConstructor>(new IntegerMap());
ExpectBuilder<IConstructor> sExpectBuilder = new ExpectBuilder<IConstructor>(new IntegerKeyedHashMap<>(), new IntegerMap());
sExpectBuilder.addAlternative(PROD_S_AB, (AbstractStackNode<IConstructor>[]) new AbstractStackNode[]{NONTERMINAL_A0, NONTERMINAL_B1});
sExpectBuilder.addAlternative(PROD_S_AC, (AbstractStackNode<IConstructor>[]) new AbstractStackNode[]{NONTERMINAL_A0, NONTERMINAL_C2});
S_EXPECTS = sExpectBuilder.buildExpectArray();
}

private final static AbstractStackNode<IConstructor>[] A_EXPECTS;
static{
ExpectBuilder<IConstructor> aExpectBuilder = new ExpectBuilder<IConstructor>(new IntegerMap());
ExpectBuilder<IConstructor> aExpectBuilder = new ExpectBuilder<IConstructor>(new IntegerKeyedHashMap<>(), new IntegerMap());
aExpectBuilder.addAlternative(PROD_A_a, (AbstractStackNode<IConstructor>[]) new AbstractStackNode[]{LITERAL_a3});
A_EXPECTS = aExpectBuilder.buildExpectArray();
}

private final static AbstractStackNode<IConstructor>[] B_EXPECTS;
static{
ExpectBuilder<IConstructor> bExpectBuilder = new ExpectBuilder<IConstructor>(new IntegerMap());
ExpectBuilder<IConstructor> bExpectBuilder = new ExpectBuilder<IConstructor>(new IntegerKeyedHashMap<>(), new IntegerMap());
bExpectBuilder.addAlternative(PROD_B_a, (AbstractStackNode<IConstructor>[]) new AbstractStackNode[]{LITERAL_a4});
B_EXPECTS = bExpectBuilder.buildExpectArray();
}

private final static AbstractStackNode<IConstructor>[] C_EXPECTS;
static{
ExpectBuilder<IConstructor> cExpectBuilder = new ExpectBuilder<IConstructor>(new IntegerMap());
ExpectBuilder<IConstructor> cExpectBuilder = new ExpectBuilder<IConstructor>(new IntegerKeyedHashMap<>(), new IntegerMap());
cExpectBuilder.addAlternative(PROD_C_a, (AbstractStackNode<IConstructor>[]) new AbstractStackNode[]{LITERAL_a5});
C_EXPECTS = cExpectBuilder.buildExpectArray();
}
Expand Down
5 changes: 3 additions & 2 deletions test/org/rascalmpl/test/parser/Ambiguous9.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.rascalmpl.parser.gtd.stack.AbstractStackNode;
import org.rascalmpl.parser.gtd.stack.LiteralStackNode;
import org.rascalmpl.parser.gtd.stack.NonTerminalStackNode;
import org.rascalmpl.parser.gtd.util.IntegerKeyedHashMap;
import org.rascalmpl.parser.gtd.util.IntegerMap;
import org.rascalmpl.parser.uptr.UPTRNodeFactory;
import io.usethesource.vallang.IConstructor;
Expand Down Expand Up @@ -66,14 +67,14 @@ public class Ambiguous9 extends SGTDBF<IConstructor, ITree, ISourceLocation> imp

private final static AbstractStackNode<IConstructor>[] S_EXPECTS;
static{
ExpectBuilder<IConstructor> sExpectBuilder = new ExpectBuilder<IConstructor>(new IntegerMap());
ExpectBuilder<IConstructor> sExpectBuilder = new ExpectBuilder<IConstructor>(new IntegerKeyedHashMap<>(), new IntegerMap());
sExpectBuilder.addAlternative(PROD_S_E, (AbstractStackNode<IConstructor>[]) new AbstractStackNode[]{NONTERMINAL_E0});
S_EXPECTS = sExpectBuilder.buildExpectArray();
}

private final static AbstractStackNode<IConstructor>[] E_EXPECTS;
static{
ExpectBuilder<IConstructor> eExpectBuilder = new ExpectBuilder<IConstructor>(new IntegerMap());
ExpectBuilder<IConstructor> eExpectBuilder = new ExpectBuilder<IConstructor>(new IntegerKeyedHashMap<>(), new IntegerMap());
eExpectBuilder.addAlternative(PROD_E_EplusE, (AbstractStackNode<IConstructor>[]) new AbstractStackNode[]{NONTERMINAL_E1, LITERAL_4, NONTERMINAL_E2});
eExpectBuilder.addAlternative(PROD_E_EstarE, (AbstractStackNode<IConstructor>[]) new AbstractStackNode[]{NONTERMINAL_E1, LITERAL_5, NONTERMINAL_E3});
eExpectBuilder.addAlternative(PROD_E_1, (AbstractStackNode<IConstructor>[]) new AbstractStackNode[]{LITERAL_6});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.rascalmpl.parser.gtd.stack.AbstractStackNode;
import org.rascalmpl.parser.gtd.stack.LiteralStackNode;
import org.rascalmpl.parser.gtd.stack.NonTerminalStackNode;
import org.rascalmpl.parser.gtd.util.IntegerKeyedHashMap;
import org.rascalmpl.parser.gtd.util.IntegerMap;
import org.rascalmpl.parser.uptr.UPTRNodeFactory;
import io.usethesource.vallang.IConstructor;
Expand Down Expand Up @@ -50,7 +51,7 @@ public class AmbiguousRecursivePrefixShared extends SGTDBF<IConstructor, ITree,

private final static AbstractStackNode<IConstructor>[] S_EXPECTS;
static{
ExpectBuilder<IConstructor> sExpectBuilder = new ExpectBuilder<IConstructor>(new IntegerMap());
ExpectBuilder<IConstructor> sExpectBuilder = new ExpectBuilder<IConstructor>(new IntegerKeyedHashMap<>(), new IntegerMap());
sExpectBuilder.addAlternative(PROD_S_SSS, (AbstractStackNode<IConstructor>[]) new AbstractStackNode[]{NONTERMINAL_S0, NONTERMINAL_S1, NONTERMINAL_S2});
sExpectBuilder.addAlternative(PROD_S_SS, (AbstractStackNode<IConstructor>[]) new AbstractStackNode[]{NONTERMINAL_S0, NONTERMINAL_S1});
sExpectBuilder.addAlternative(PROD_S_a, (AbstractStackNode<IConstructor>[]) new AbstractStackNode[]{LITERAL_a5});
Expand Down
11 changes: 6 additions & 5 deletions test/org/rascalmpl/test/parser/DoubleLeftNullable.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.rascalmpl.parser.gtd.stack.ListStackNode;
import org.rascalmpl.parser.gtd.stack.LiteralStackNode;
import org.rascalmpl.parser.gtd.stack.NonTerminalStackNode;
import org.rascalmpl.parser.gtd.util.IntegerKeyedHashMap;
import org.rascalmpl.parser.gtd.util.IntegerMap;
import org.rascalmpl.parser.uptr.UPTRNodeFactory;
import org.rascalmpl.values.RascalValueFactory;
Expand Down Expand Up @@ -86,7 +87,7 @@ protected static IValue _read(java.lang.String s, io.usethesource.vallang.type.T
protected static class layouts_$default$ {
public final static AbstractStackNode<IConstructor>[] EXPECTS;
static{
ExpectBuilder<IConstructor> builder = new ExpectBuilder<IConstructor>(new IntegerMap());
ExpectBuilder<IConstructor> builder = new ExpectBuilder<IConstructor>(new IntegerKeyedHashMap<>(), new IntegerMap());
init(builder);
EXPECTS = builder.buildExpectArray();
}
Expand All @@ -107,7 +108,7 @@ public static void init(ExpectBuilder<IConstructor> builder){
protected static class start__Stmt {
public final static AbstractStackNode<IConstructor>[] EXPECTS;
static{
ExpectBuilder<IConstructor> builder = new ExpectBuilder<IConstructor>(new IntegerMap());
ExpectBuilder<IConstructor> builder = new ExpectBuilder<IConstructor>(new IntegerKeyedHashMap<>(), new IntegerMap());
init(builder);
EXPECTS = builder.buildExpectArray();
}
Expand All @@ -130,7 +131,7 @@ public static void init(ExpectBuilder<IConstructor> builder){
protected static class Expr {
public final static AbstractStackNode<IConstructor>[] EXPECTS;
static{
ExpectBuilder<IConstructor> builder = new ExpectBuilder<IConstructor>(new IntegerMap());
ExpectBuilder<IConstructor> builder = new ExpectBuilder<IConstructor>(new IntegerKeyedHashMap<>(), new IntegerMap());
init(builder);
EXPECTS = builder.buildExpectArray();
}
Expand All @@ -149,7 +150,7 @@ public static void init(ExpectBuilder<IConstructor> builder){
protected static class Stmt {
public final static AbstractStackNode<IConstructor>[] EXPECTS;
static{
ExpectBuilder<IConstructor> builder = new ExpectBuilder<IConstructor>(new IntegerMap());
ExpectBuilder<IConstructor> builder = new ExpectBuilder<IConstructor>(new IntegerKeyedHashMap<>(), new IntegerMap());
init(builder);
EXPECTS = builder.buildExpectArray();
}
Expand Down Expand Up @@ -211,7 +212,7 @@ public static void init(ExpectBuilder<IConstructor> builder){
protected static class layouts_WS {
public final static AbstractStackNode<IConstructor>[] EXPECTS;
static{
ExpectBuilder<IConstructor> builder = new ExpectBuilder<IConstructor>(new IntegerMap());
ExpectBuilder<IConstructor> builder = new ExpectBuilder<IConstructor>(new IntegerKeyedHashMap<>(), new IntegerMap());
init(builder);
EXPECTS = builder.buildExpectArray();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import org.rascalmpl.parser.gtd.stack.EmptyStackNode;
import org.rascalmpl.parser.gtd.stack.LiteralStackNode;
import org.rascalmpl.parser.gtd.stack.NonTerminalStackNode;
import org.rascalmpl.parser.gtd.util.IntegerKeyedHashMap;
import org.rascalmpl.parser.gtd.util.IntegerList;
import org.rascalmpl.parser.gtd.util.IntegerMap;
import org.rascalmpl.parser.uptr.UPTRNodeFactory;
import org.rascalmpl.values.RascalValueFactory;
Expand Down Expand Up @@ -40,6 +42,7 @@ protected static IValue _read(java.lang.String s, io.usethesource.vallang.type.T

protected static final TypeFactory _tf = TypeFactory.getInstance();

private static final IntegerKeyedHashMap<IntegerList> _dontNest = new IntegerKeyedHashMap<IntegerList>();
private static final IntegerMap _resultStoreIdMappings = new IntegerMap();

// Production declarations
Expand All @@ -58,7 +61,7 @@ protected static IValue _read(java.lang.String s, io.usethesource.vallang.type.T
protected static class Stmt {
public final static AbstractStackNode<IConstructor>[] EXPECTS;
static{
ExpectBuilder<IConstructor> builder = new ExpectBuilder<IConstructor>(_resultStoreIdMappings);
ExpectBuilder<IConstructor> builder = new ExpectBuilder<IConstructor>(_dontNest, _resultStoreIdMappings);
init(builder);
EXPECTS = builder.buildExpectArray();
}
Expand Down
12 changes: 8 additions & 4 deletions test/org/rascalmpl/test/parser/ParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,13 @@ public void testListSharing(){

public void testDoubleLeftNullable() {
executeParser(new DoubleLeftNullable());
}
}

public void testDoubleRightNullable() {
executeParser(new DoubleRightNullableWithPrefixSharing());
}

public void testDoubleRightNullable() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arnoldlankamp why is this test not useful anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's still there. This is just a tabs vs spaces formatting diff.

executeParser(new DoubleRightNullableWithPrefixSharing());
}
public void testPrefixSharedExcept() {
executeParser(new PrefixSharedExcept());
}
}
Loading
Loading