Skip to content

Commit

Permalink
Fix Pretty Printer handling of Constant Groups
Browse files Browse the repository at this point in the history
  • Loading branch information
MisterErwin committed Sep 24, 2024
1 parent 58a9ee3 commit 5bc7c37
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
import java.util.stream.Collectors;

// Note: We can't use symbol-table information for multiplicities due to GrammarTransformer#removeNonTerminalSeparators, etc
public class PrettyPrinterGenerationVisitor implements GrammarVisitor2 {
Expand Down Expand Up @@ -482,7 +483,9 @@ public void visit(ASTConstantGroup node) {
String humanName = node.isPresentUsageName() ? node.getUsageName() : node.getName();
String getter = getPlainGetterSymbol(humanName, Multiplicity.STANDARD);

boolean onlyOneConstant = node.getConstantList().size() == 1;
// The detection process of weather a constant groups AST attribute is an int or boolean
// must be able to handle u:[c:"a" | c:"b"], (op:["*"]|op:["/"]) and ASTRule shenanigans
boolean onlyOneConstant = !TransformationHelper.isConstGroupIterated(node.getSymbol());
if (onlyOneConstant) {
// catch (op:["*"]|op:["/"]) and ASTRule shenanigans
String nodeAttrName = node.isPresentUsageName() ? node.getUsageName() : node.getName();
Expand All @@ -501,6 +504,11 @@ public void visit(ASTConstantGroup node) {
this.failureMessage = "Unable to find good Constant name for " + getter + " and value " + constant.getHumanName();
}

if (onlyOneConstant) {
// in case of u:[c:"a" | c:"b"], limit the size of the used constants to 1
constants = constants.stream().limit(1).collect(Collectors.toSet());
}

PPGuardComponent component = PPGuardComponent.forCG(getter, constants);

AltData altData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,13 @@ grammar TestPrettyPrinters extends de.monticore.literals.MCCommonLiterals {
CPCGSingle = ["cg1"] ;
CPCGSingleU1 = [u:"cg1"] ;
CPCGSingleU2 = u:["cg1"] ;
CPCGSingleU3 = cg:[ a:"cg1" | a:"cg2"] ; // Note: Only the first constant is generated for the parser
CPCGSingleU4 = cg:["a" | a:"cg1" | a:"cg2"] ; // Note: Only the first constant is generated

CPCGMulti1 = cg:["cg1" | "cg2"] ;
CPCGMulti2 = cg:[u:"cg1" | v:"cg2"] ;
CPCGMulti3 = cg:[a:"cg1" | a:"cg2" | b: "b"] ;
CPCGMulti4 = (op:["*"] | op:["/"]); // special constand handling

MultiCGPlus = (["a"]| ["b"] | ["c"])+ D?;
MultiCGStar = (["a"] | ["b"] | ["c"])* D?;
Expand All @@ -55,6 +59,18 @@ grammar TestPrettyPrinters extends de.monticore.literals.MCCommonLiterals {

// Duplicate NonTerminal usagenames
DuplicateUsageName = Name ("=" value:Name |"=" value:String)? ;
DuplicateUsageName2 = a:Name a:Name;
DuplicateUsageName3 = a:Name (a:Name)*;

// Duplicate Token-NonTerminal usagenames
token MyToken = "MYTOKEN";
DuplicateTokenUsageName = MyToken ("=" value:MyToken |"+=" value:MyToken)? ;
DuplicateTokenUsageName2 = a:MyToken a:MyToken;
DuplicateTokenUsageName3 = a:MyToken (a:MyToken)*;

// Duplicate Terminal with usagenames
DuplicateTermUsageName2 = a:"a" a:"a";
DuplicateTermUsageName3 = a:"a" (a:"a")*;

CPAstList = (A | B | C)*; // Unsupported
astrule CPAstList = a:A max=1; // Unsupported
Expand All @@ -64,7 +80,6 @@ grammar TestPrettyPrinters extends de.monticore.literals.MCCommonLiterals {

CPCGSup = complete:["(c)"];
CPCGUnsupName = ending:[".dot"|".jpg"]; // Unsupported due to constants name
CPCGUnsuppDup = (op:["*"]|op:["/"]); // Unsupported

CPListInDList = B (B A*)*;
CPListInPList = B (B+ A*)*;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,19 @@ public void testCPCGSingleU2() throws IOException {
testPP("cg1", TestPrettyPrintersMill.parser()::parse_StringCPCGSingleU2);
}

@Test
public void testCPCGSingleU3() throws IOException {
testPP("cg1", TestPrettyPrintersMill.parser()::parse_StringCPCGSingleU3);
// testPP("cg2", TestPrettyPrintersMill.parser()::parse_StringCPCGSingleU3); // Note: Only the first constant is generated for the parser
}

@Test
public void testCPCGSingleU4() throws IOException {
testPP("a", TestPrettyPrintersMill.parser()::parse_StringCPCGSingleU4);
// testPP("cg1", TestPrettyPrintersMill.parser()::parse_StringCPCGSingleU4); // Note: Only the first constant is generated for the parser
// testPP("cg2", TestPrettyPrintersMill.parser()::parse_StringCPCGSingleU4); // Note: Only the first constant is generated for the parser
}

@Test
public void testCPCGMulti1() throws IOException {
testPP("cg1", TestPrettyPrintersMill.parser()::parse_StringCPCGMulti1);
Expand All @@ -213,6 +226,19 @@ public void testCPCGMulti2() throws IOException {
testPP("cg2", TestPrettyPrintersMill.parser()::parse_StringCPCGMulti2);
}

@Test
public void testCPCGMulti3() throws IOException {
testPP("cg1", TestPrettyPrintersMill.parser()::parse_StringCPCGMulti3);
testPP("cg2", TestPrettyPrintersMill.parser()::parse_StringCPCGMulti3);
testPP("b", TestPrettyPrintersMill.parser()::parse_StringCPCGMulti3);
}

@Test
public void testCPCGMulti4() throws IOException {
testPP("*", TestPrettyPrintersMill.parser()::parse_StringCPCGMulti4);
testPP("/", TestPrettyPrintersMill.parser()::parse_StringCPCGMulti4);
}

@Test
public void testCGs() throws IOException {
for (String input : Arrays.asList("a", "b", "c",
Expand Down Expand Up @@ -261,6 +287,49 @@ public void testDuplicateUsageName() throws IOException {
testPP("n1 = s1\n", TestPrettyPrintersMill.parser()::parse_StringDuplicateUsageName);
}

@Test
public void testDuplicateUsageName2() throws IOException {
testPP("n1 n2", TestPrettyPrintersMill.parser()::parse_StringDuplicateUsageName2);
}

@Test
public void testDuplicateUsageName3() throws IOException {
testPP("n1", TestPrettyPrintersMill.parser()::parse_StringDuplicateUsageName3);
testPP("n1 n2", TestPrettyPrintersMill.parser()::parse_StringDuplicateUsageName3);
testPP("n1 n2 n3", TestPrettyPrintersMill.parser()::parse_StringDuplicateUsageName3);
}

@Test
public void testDuplicateTokenUsageName() throws IOException {
testPP("MYTOKEN", TestPrettyPrintersMill.parser()::parse_StringDuplicateTokenUsageName);
testPP("MYTOKEN = MYTOKEN", TestPrettyPrintersMill.parser()::parse_StringDuplicateTokenUsageName);
testPP("MYTOKEN += MYTOKEN", TestPrettyPrintersMill.parser()::parse_StringDuplicateTokenUsageName);
}

@Test
public void testDuplicateTokenUsageName2() throws IOException {
testPP("MYTOKEN MYTOKEN", TestPrettyPrintersMill.parser()::parse_StringDuplicateTokenUsageName2);
}

@Test
public void testDuplicateTokenUsageName3() throws IOException {
testPP("MYTOKEN", TestPrettyPrintersMill.parser()::parse_StringDuplicateTokenUsageName3);
testPP("MYTOKEN MYTOKEN", TestPrettyPrintersMill.parser()::parse_StringDuplicateTokenUsageName3);
testPP("MYTOKEN MYTOKEN MYTOKEN", TestPrettyPrintersMill.parser()::parse_StringDuplicateTokenUsageName3);
}

@Test
public void testDuplicateTermUsageName2() throws IOException {
testPP("a a", TestPrettyPrintersMill.parser()::parse_StringDuplicateTermUsageName2);
}

@Test
public void testDuplicateTermUsageName3() throws IOException {
testPP("a", TestPrettyPrintersMill.parser()::parse_StringDuplicateTermUsageName3);
testPP("a a", TestPrettyPrintersMill.parser()::parse_StringDuplicateTermUsageName3);
testPP("a a a", TestPrettyPrintersMill.parser()::parse_StringDuplicateTermUsageName3);
}

@Test
@Ignore
public void testCPAstList() throws IOException {
Expand Down Expand Up @@ -292,16 +361,6 @@ public void testCPCGUnsupName() throws IOException {
}
}

@Test
public void testCPCGUnsuppDup() throws IOException {
try {
testPP("*", TestPrettyPrintersMill.parser()::parse_StringCPCGUnsuppDup);
Assert.fail();
} catch (IllegalStateException expected) {
Assert.assertEquals("Unable to handle ConstantGroup with size of 1, but multiple elements named op present", expected.getMessage());
}
}

@Test
public void testCPListInDList() throws IOException {
testPP("B", TestPrettyPrintersMill.parser()::parse_StringCPListInDList);
Expand Down

0 comments on commit 5bc7c37

Please sign in to comment.