Commit 7a48912a authored by René Schöne's avatar René Schöne
Browse files

Merge branch 'extendj'

parents a044e6b2 9b86ba17
Pipeline #5075 passed with stage
in 2 minutes and 28 seconds
......@@ -153,6 +153,13 @@ test.dependsOn compileRelationTest
compileRelationTest.dependsOn doublePreprocessRelationTest
doublePreprocessRelationTest.dependsOn preprocessRelationTest
task compileConstructorTest(type: RelastTest) {
relastFiles 'src/test/jastadd/constructors/Constructors.relast'
grammarName = 'src/test/jastadd/constructors/Constructors'
packageName = 'constructors.ast'
moreInputFiles 'src/test/jastadd/constructors/Constructors.jrag'
}
task compileDefaultNamesTest(type: RelastTest) {
relastFiles 'src/test/jastadd/relations/Relations.relast'
grammarName = 'src/test/jastadd/relations/Relations3'
......@@ -247,7 +254,6 @@ task compileSerializerDefaultNamesTest(type: RelastTest) {
}
task compileSerializerPointerTest(type: RelastTest) {
verbose = true
resolverHelper = true
relastFiles 'src/test/jastadd/serializer-pointer/Serializer.relast'
grammarName = 'src/test/jastadd/serializer-pointer/Serializer'
......@@ -257,7 +263,6 @@ task compileSerializerPointerTest(type: RelastTest) {
}
task compileSerializerManualTest(type: RelastTest) {
verbose = true
resolverHelper = true
relastFiles 'src/test/jastadd/serializer-manual/Serializer.relast'
grammarName = 'src/test/jastadd/serializer-manual/Serializer'
......@@ -267,7 +272,6 @@ task compileSerializerManualTest(type: RelastTest) {
}
task compileSerializerManualRelativeTest(type: RelastTest) {
verbose = true
resolverHelper = true
relastFiles 'src/test/jastadd/serializer-manual-relative/Serializer.relast'
grammarName = 'src/test/jastadd/serializer-manual-relative/Serializer'
......
......@@ -105,6 +105,11 @@ aspect ComponentAnalysis {
//--- isEqual ---
syn boolean Component.isEqual(Component c) = this.getClass() == c.getClass() && getTypeUse().isEqual(c.getTypeUse());
/**
* TokenComponents may be specialized by NTATokenComponents and vice versa
*/
eq TokenComponent.isEqual(Component c) = (c instanceof TokenComponent) && getTypeUse().isEqual(c.getTypeUse());
syn boolean TypeUse.isEqual(TypeUse u);
eq SimpleTypeUse.isEqual(TypeUse u) = u instanceof SimpleTypeUse && getID().equals(u.getID());
eq ParameterizedTypeUse.isEqual(TypeUse u) {
......@@ -228,17 +233,7 @@ aspect Constructors {
}
//--- needsConstructor ---
syn boolean TypeDecl.needsConstructor() {
if (componentsTransitive().isEmpty()) {
return false;
}
if (!relationComponents().isEmpty()) {
return true;
}
return hasSuper()
&& getSuper().decl() != null
&& getSuper().decl().needsConstructor();
}
syn boolean TypeDecl.needsConstructor() = !componentsTransitive().isEmpty() && !relationComponentsTransitive().isEmpty();
//--- inConstructor ---
/**
......@@ -248,6 +243,7 @@ aspect Constructors {
eq NTAComponent.inConstructor() = false;
eq NTAOptComponent.inConstructor() = false;
eq NTAListComponent.inConstructor() = false;
eq NTATokenComponent.inConstructor() = false;
}
aspect Utils {
......
......@@ -111,6 +111,9 @@ aspect BackendAbstractGrammar {
public String TokenComponent.generateAbstractGrammar() {
return "<" + getID() + ":" + getTypeUse() + ">";
}
public String NTATokenComponent.generateAbstractGrammar() {
return "/<" + getID() + ":" + getTypeUse() + ">/";
}
public String RelationComponent.generateAbstractGrammar() {
return "<" + getImplAttributeName() + ":" + ofTypeDecl() + ">";
......
......@@ -11,6 +11,7 @@ NTAComponent : SimpleTypeComponent;
NTAOptComponent : SimpleTypeComponent;
NTAListComponent : SimpleTypeComponent;
TokenComponent : Component ::= TypeUse;
NTATokenComponent : TokenComponent ::= TypeUse;
abstract TypeUse ::= <ID>;
SimpleTypeUse : TypeUse;
......
......@@ -37,7 +37,7 @@ import org.jastadd.relast.parser.RelAstParser.Terminals;
WhiteSpace = [ ] | \t | \f | \n | \r | \r\n
TraditionalComment = [/][*][^*]*[*]+([^*/][^*]*[*]+)*[/]
EndOfLineComment = "//" [^\n|\r|\r\n]*
EndOfLineComment = "//" [^\n\r]*
Comment = {TraditionalComment} | {EndOfLineComment}
ID = [a-zA-Z$_][a-zA-Z0-9$_]*
......
......@@ -34,9 +34,16 @@ SimpleTypeUse s_type_use =
ID {: return new SimpleTypeUse(ID); :}
;
ArrayList inner_type_use
= ID
| inner_type_use DOT ID
;
TypeUse type_use =
s_type_use.u {: return u; :}
| parameterized_type_use.p {: return p; :}
// s_type_use.u {: return u; :}
// |
parameterized_type_use.p {: return p; :}
| inner_type_use.p {: return new SimpleTypeUse((String)p.stream().map( x -> ((Symbol)x).value.toString()).collect(java.util.stream.Collectors.joining("."))); :}
;
ParameterizedTypeUse parameterized_type_use =
ID LT type_use_list.l GT {: return new ParameterizedTypeUse(ID, l); :}
......@@ -63,11 +70,11 @@ Component component =
| ID COL s_type_use.u STAR {: return new ListComponent(ID, u); :}
| s_type_use.u STAR {: return new ListComponent(u.getID(), u); :}
// Opt
| LBRACKET ID COL s_type_use.u RBRACKET {: return new OptComponent(ID, u); :}
| LBRACKET s_type_use.u RBRACKET {: return new OptComponent(u.getID(), u); :}
| LBRACKET ID COL s_type_use.u RBRACKET {: return new OptComponent(ID, u); :}
| LBRACKET s_type_use.u RBRACKET {: return new OptComponent(u.getID(), u); :}
// NTA list
| SLASH ID COL s_type_use.u STAR SLASH {: return new NTAListComponent(ID, u); :}
| SLASH s_type_use.u STAR SLASH {: return new NTAListComponent(u.getID(), u); :}
| SLASH ID COL s_type_use.u STAR SLASH {: return new NTAListComponent(ID, u); :}
| SLASH s_type_use.u STAR SLASH {: return new NTAListComponent(u.getID(), u); :}
// NTA opt
| SLASH LBRACKET ID COL s_type_use.u RBRACKET SLASH {: return new NTAOptComponent(ID, u); :}
| SLASH LBRACKET s_type_use.u RBRACKET SLASH {: return new NTAOptComponent(u.getID(), u); :}
......@@ -75,8 +82,8 @@ Component component =
| SLASH ID COL s_type_use.u SLASH {: return new NTAComponent(ID, u); :}
| SLASH s_type_use.u SLASH {: return new NTAComponent(u.getID(), u); :}
// NTA Token (same as NTA)
| SLASH LT ID COL s_type_use.u GT SLASH {: return new NTAComponent(ID, u); :}
| SLASH LT s_type_use.u GT SLASH {: return new NTAComponent(u.getID(), u); :}
| SLASH LT ID COL s_type_use.u GT SLASH {: return new NTATokenComponent(ID, u); :}
| SLASH LT ID GT SLASH {: return new NTATokenComponent(ID, new SimpleTypeUse("String")); :}
// Token
| LT ID COL type_use.u GT {: return new TokenComponent(ID, u); :}
| LT ID GT {: return new TokenComponent(ID, new SimpleTypeUse("String")); :}
......
aspect NTAs {
syn A S.getS4() = new A();
syn List<A> S.getS5List() = new List<>();
syn Opt<A> S.getS6Opt() = new Opt<>();
syn String S.getS7() = "";
syn long S.getS8() = 1L;
syn A B.getB4() = new A();
syn List<A> B.getB5List() = new List<>();
syn Opt<A> B.getB6Opt() = new Opt<>();
syn String B.getB7() = "";
syn long B.getB8() = 1L;
}
A;
S ::= S1:A S2:A* [S3:A] /S4:A/ /S5:A*/ /[S6:A]/ /<S7>/ /<S8:long>/;
B : S ::= B1:A B2:A* [B3:A] /B4:A/ /B5:A*/ /[B6:A]/ /<B7>/ /<B8:long>/;
X;
Y;
rel A.r1 -> X;
rel S.r2* <-> Y.r2;
rel B.r3? -> X;
Errors:
$FILENAME Line 4, column 12: Token 'X' is an invalid redefinition for type 'B3', conflicts with supertype 'A'
$FILENAME Line 7, column 5: Role 'X' is an invalid redefinition for type 'B2', conflicts with supertype 'A'
$FILENAME Line 4, column 23: Token 'MyName' is an invalid redefinition for type 'B3', conflicts with supertype 'A'
$FILENAME Line 11, column 5: Role 'X' is an invalid redefinition for type 'B2', conflicts with supertype 'A'
$FILENAME Line 12, column 5: Role 'X' is an invalid redefinition for type 'B2', conflicts with supertype 'A'
$FILENAME Line 13, column 5: Role 'X' is an invalid redefinition for type 'B2', conflicts with supertype 'A'
$FILENAME Line 14, column 5: Role 'X' is an invalid redefinition for type 'B2', conflicts with supertype 'A'
$FILENAME Line 15, column 5: Role 'X' is an invalid redefinition for type 'B2', conflicts with supertype 'A'
$FILENAME Line 16, column 5: Role 'X' is an invalid redefinition for type 'B2', conflicts with supertype 'A'
$FILENAME Line 12, column 5: Role 'X' is already declared for type 'B2'
$FILENAME Line 13, column 5: Role 'X' is already declared for type 'B2'
$FILENAME Line 14, column 5: Role 'X' is already declared for type 'B2'
$FILENAME Line 15, column 5: Role 'X' is already declared for type 'B2'
$FILENAME Line 16, column 5: Role 'X' is already declared for type 'B2'
$FILENAME Line 18, column 5: Role 'MyName' is an invalid redefinition for type 'B2', conflicts with supertype 'A'
$FILENAME Line 19, column 5: Role 'MyName' is an invalid redefinition for type 'B2', conflicts with supertype 'A'
$FILENAME Line 20, column 5: Role 'MyName' is an invalid redefinition for type 'B2', conflicts with supertype 'A'
$FILENAME Line 21, column 5: Role 'MyName' is an invalid redefinition for type 'B2', conflicts with supertype 'A'
$FILENAME Line 22, column 5: Role 'MyName' is an invalid redefinition for type 'B2', conflicts with supertype 'A'
$FILENAME Line 23, column 5: Role 'MyName' is an invalid redefinition for type 'B2', conflicts with supertype 'A'
$FILENAME Line 19, column 5: Role 'MyName' is already declared for type 'B2'
$FILENAME Line 20, column 5: Role 'MyName' is already declared for type 'B2'
$FILENAME Line 21, column 5: Role 'MyName' is already declared for type 'B2'
$FILENAME Line 22, column 5: Role 'MyName' is already declared for type 'B2'
$FILENAME Line 23, column 5: Role 'MyName' is already declared for type 'B2'
$FILENAME Line 28, column 12: Token 'X' is an invalid redefinition for type 'D3', conflicts with supertype 'C'
$FILENAME Line 30, column 5: Role 'X' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 31, column 5: Role 'X' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 32, column 5: Role 'X' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 33, column 5: Role 'X' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 34, column 5: Role 'X' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 35, column 5: Role 'X' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 31, column 5: Role 'X' is already declared for type 'D2'
$FILENAME Line 32, column 5: Role 'X' is already declared for type 'D2'
$FILENAME Line 33, column 5: Role 'X' is already declared for type 'D2'
$FILENAME Line 34, column 5: Role 'X' is already declared for type 'D2'
$FILENAME Line 35, column 5: Role 'X' is already declared for type 'D2'
$FILENAME Line 37, column 5: Role 'MyName' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 38, column 5: Role 'MyName' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 39, column 5: Role 'MyName' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 40, column 5: Role 'MyName' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 41, column 5: Role 'MyName' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 42, column 5: Role 'MyName' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 38, column 5: Role 'MyName' is already declared for type 'D2'
$FILENAME Line 39, column 5: Role 'MyName' is already declared for type 'D2'
$FILENAME Line 40, column 5: Role 'MyName' is already declared for type 'D2'
$FILENAME Line 41, column 5: Role 'MyName' is already declared for type 'D2'
$FILENAME Line 42, column 5: Role 'MyName' is already declared for type 'D2'
$FILENAME Line 44, column 5: Role 'X2' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 45, column 5: Role 'X2' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 46, column 5: Role 'X2' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 47, column 5: Role 'X2' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 48, column 5: Role 'X2' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 49, column 5: Role 'X2' is an invalid redefinition for type 'D2', conflicts with supertype 'C'
$FILENAME Line 45, column 5: Role 'X2' is already declared for type 'D2'
$FILENAME Line 46, column 5: Role 'X2' is already declared for type 'D2'
$FILENAME Line 47, column 5: Role 'X2' is already declared for type 'D2'
$FILENAME Line 48, column 5: Role 'X2' is already declared for type 'D2'
$FILENAME Line 49, column 5: Role 'X2' is already declared for type 'D2'
A ::= X;
B1 : A ::= X;
A ::= X MyName:X;
B1 : A ::= X MyName:X MyName:Y;
B2 : A;
B3 : A ::= <X:String>;
B3 : A ::= <X:String> <MyName:String>;
// B4 has a child named X of type SubX
B4 : A ::= X:SubX;
X;
SubX : X;
Y;
rel B2.X -> X;
rel B2.X -> Y;
rel B2.X? -> X;
rel B2.X? -> Y;
rel B2.X* -> X;
rel B2.X* -> Y;
rel B2.MyName -> X;
rel B2.MyName -> Y;
rel B2.MyName? -> X;
rel B2.MyName? -> Y;
rel B2.MyName* -> X;
rel B2.MyName* -> Y;
C ::= /X/ /MyName:X/ /<X2:long>/ ;
D1 : C ::= X;
D2 : C;
D3 : C ::= <X:String> ;
rel D2.X -> X;
rel D2.X -> Y;
rel D2.X? -> X;
rel D2.X? -> Y;
rel D2.X* -> X;
rel D2.X* -> Y;
rel D2.MyName -> X;
rel D2.MyName -> Y;
rel D2.MyName? -> X;
rel D2.MyName? -> Y;
rel D2.MyName* -> X;
rel D2.MyName* -> Y;
rel D2.X2 -> X;
rel D2.X2 -> Y;
rel D2.X2? -> X;
rel D2.X2? -> Y;
rel D2.X2* -> X;
rel D2.X2* -> Y;
......@@ -41,3 +41,23 @@ rel A <- Root.AaLeft?;
rel B <- A.Di1Left ;
rel B <- A.Di2Left?;
rel B <- A.Di3Left*;
// empty productions
C ;
// production with nonterminals of different kinds
D ::= SingleA:A ListOfA:A* [OptionalA:A] /NTAA:A/ ;
// production with tokens, nonterminal-tokens, multi-line
E ::= <T1> <T2:String> <T3:boolean> <T4:int> <T5:float> <T6:double> <T7:long>
/<NT2:String>/ /<NT3:boolean>/ /<NT4:int>/ /<NT5:float>/ /<NT6:double>/ /<NT7:long>/ ;
rel E.NT1 -> A ;
// inheritance and empty
F : A ;
// inheritance and more on RHS
G : C ::= [D] ;
// line comment with special symbols like |, *, ->, <-, <->, [A], B ::= C, :, \n, \r, ~, #, /A/
/* block comment with special symbols like |, *, ->, <-, <->, [A], B ::= C, :, \n, \r, ~, #, /A/ */
package org.jastadd.relast.tests;
import constructors.ast.*;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
/**
* Testing generated constructors.
*
* @author rschoene - Initial contribution
*/
@SuppressWarnings("unused")
public class ConstructorsTest {
@Test
public void testX() {
X x = new X();
Assertions.assertEquals(1, numberOfConstructors(X.class));
}
@Test
public void testY() {
Y y0 = new Y();
Y y1 = new Y(new S());
Assertions.assertEquals(2, numberOfConstructors(Y.class));
}
@Test
public void testA() {
A a0 = new A();
A a1 = new A(new X());
Assertions.assertEquals(2, numberOfConstructors(A.class));
}
@Test
public void testS() {
A a = new A();
S s0 = new S();
S s1 = new S(a, new List<>(), new Opt<>());
S s2 = new S(a, new List<>(), new Opt<>(), new ArrayList<>());
Assertions.assertEquals(3, numberOfConstructors(S.class));
}
@Test
public void testB() {
A a = new A();
B b0 = new B();
B b1 = new B(a, new List<>(), new Opt<>(), a, new List<>(), new Opt<>());
B b2 = new B(a, new List<>(), new Opt<>(), new ArrayList<>(), a, new List<>(), new Opt<>(), null);
Assertions.assertEquals(3, numberOfConstructors(B.class));
}
private int numberOfConstructors(Class<?> clazz) {
return clazz.getConstructors().length;
}
}
......@@ -10,6 +10,7 @@ import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
......@@ -23,32 +24,32 @@ class Errors {
private static final String FILENAME_PATTERN = "$FILENAME";
@Test
void test1() throws IOException {
void testStandardErrors() throws IOException {
test("Errors");
}
@Test
void test1Left() throws IOException {
void testStandardErrorsLeft() throws IOException {
test("ErrorsLeft");
}
@Test
void test2() throws IOException {
void testInheritance() throws IOException {
test("Inheritance");
}
@Test
void test2Left() throws IOException {
void testInheritanceLeft() throws IOException {
test("InheritanceLeft");
}
@Test
void test3() throws IOException {
void testMultipleFiles() throws IOException {
test("Multiple", "Multiple_1", "Multiple_2");
}
@Test
void test3Left() throws IOException {
void testMultipleFilesLeft() throws IOException {
test("MultipleLeft", "MultipleLeft_1", "MultipleLeft_2");
}
......@@ -60,7 +61,7 @@ class Errors {
String expectedFile = "./src/test/jastadd/errors/" + name + ".expected";
try {
System.out.println(System.getProperty("user.dir"));
logger.debug("user.dir: {}", System.getProperty("user.dir"));
int returnValue = exec(Compiler.class, inFiles.toArray(new String[0]), new File(outFile));
Assertions.assertEquals(1, returnValue, "Relast did not return with value 1");
} catch (IOException | InterruptedException e) {
......@@ -76,7 +77,14 @@ class Errors {
expected = expected.replace(FILENAME_PATTERN + (i + 1), inFiles.get(i));
}
}
Assertions.assertEquals(expected, out);
List<String> outList = Arrays.asList(out.split("\n"));
Collections.sort(outList);
List<String> expectedList = Arrays.stream(expected.split("\n"))
.sorted()
.filter(s -> !s.isEmpty() && !s.startsWith("//"))
.collect(Collectors.toList());
Assertions.assertLinesMatch(expectedList, outList);
logger.info("relast for " + name + " returned \n{}", out);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment