forked from JavaTX/JavaCompilerCore
Alternativ-labels in grammatik & neuen ast-generator auf basis von antlr visitor
This commit is contained in:
parent
cb564dc436
commit
c78a148766
@ -34,8 +34,8 @@ parser grammar Java17Parser;
|
||||
options { tokenVocab=Java17Lexer; }
|
||||
|
||||
sourceFile
|
||||
: packageDeclaration? importDeclaration* classOrInterface*
|
||||
| moduleDeclaration EOF
|
||||
: packageDeclaration? importDeclaration* classOrInterface* # srcfile
|
||||
| moduleDeclaration EOF # moduledecl
|
||||
;
|
||||
|
||||
packageDeclaration
|
||||
@ -48,16 +48,16 @@ importDeclaration
|
||||
|
||||
classOrInterface
|
||||
: classOrInterfaceModifier*
|
||||
(classDeclaration | enumDeclaration | interfaceDeclaration | annotationTypeDeclaration | recordDeclaration)
|
||||
| ';'
|
||||
(classDeclaration | enumDeclaration | interfaceDeclaration | annotationTypeDeclaration | recordDeclaration) # classorinterfacedecl
|
||||
| ';' # noclassorinterface
|
||||
;
|
||||
|
||||
modifier
|
||||
: classOrInterfaceModifier
|
||||
| NATIVE
|
||||
| SYNCHRONIZED
|
||||
| TRANSIENT
|
||||
| VOLATILE
|
||||
| NATIVE
|
||||
| SYNCHRONIZED
|
||||
| TRANSIENT
|
||||
| VOLATILE
|
||||
;
|
||||
|
||||
classOrInterfaceModifier
|
||||
@ -67,15 +67,15 @@ classOrInterfaceModifier
|
||||
| PRIVATE
|
||||
| STATIC
|
||||
| ABSTRACT
|
||||
| FINAL // FINAL for class only -- does not apply to interfaces
|
||||
| FINAL // FINAL for class only -- does not apply to interfaces
|
||||
| STRICTFP
|
||||
| SEALED // Java17
|
||||
| NON_SEALED // Java17
|
||||
| SEALED // Java17
|
||||
| NON_SEALED // Java17
|
||||
;
|
||||
|
||||
variableModifier
|
||||
: FINAL
|
||||
| annotation
|
||||
: FINAL # finalvarmod
|
||||
| annotation # annotationvarmod
|
||||
;
|
||||
|
||||
classDeclaration
|
||||
@ -127,21 +127,21 @@ interfaceBody
|
||||
;
|
||||
|
||||
classBodyDeclaration
|
||||
: ';'
|
||||
| STATIC? block
|
||||
| modifier* memberDeclaration
|
||||
: ';' # emptyclassbody
|
||||
| STATIC? block # classblock
|
||||
| modifier* memberDeclaration # memberdecl
|
||||
;
|
||||
|
||||
memberDeclaration
|
||||
: classOrInterface
|
||||
| fieldDeclaration
|
||||
| method
|
||||
| constructor
|
||||
: classOrInterface # memberclassorinterface
|
||||
| fieldDeclaration # memberfield
|
||||
| method # membermethod
|
||||
| constructor # memberconstructor
|
||||
;
|
||||
|
||||
method
|
||||
: methodDeclaration
|
||||
| genericMethodDeclaration
|
||||
: methodDeclaration # methoddecl
|
||||
| genericMethodDeclaration # genericmethod
|
||||
;
|
||||
|
||||
/* We use rule this even for void methods which cannot have [] after parameters.
|
||||
@ -150,19 +150,23 @@ method
|
||||
for invalid return type after parsing.
|
||||
*/
|
||||
methodDeclaration
|
||||
: refType? identifier formalParameters ('[' ']')*
|
||||
: methodHeader
|
||||
(THROWS exceptionList)?
|
||||
methodBody
|
||||
;
|
||||
|
||||
methodHeader
|
||||
: refType? identifier formalParameters ('[' ']')*
|
||||
;
|
||||
|
||||
methodBody
|
||||
: block
|
||||
| ';'
|
||||
: block # methodblock
|
||||
| ';' # emptymethod
|
||||
;
|
||||
|
||||
refType
|
||||
: typeType
|
||||
| VOID
|
||||
: typeType # reftype
|
||||
| VOID # refvoid
|
||||
;
|
||||
|
||||
genericMethodDeclaration
|
||||
@ -170,8 +174,8 @@ genericMethodDeclaration
|
||||
;
|
||||
|
||||
constructor
|
||||
: genericConstructorDeclaration
|
||||
| constructorDeclaration
|
||||
: genericConstructorDeclaration # genericconstructor
|
||||
| constructorDeclaration # constructordecl
|
||||
;
|
||||
|
||||
genericConstructorDeclaration
|
||||
@ -187,19 +191,19 @@ fieldDeclaration
|
||||
;
|
||||
|
||||
interfaceBodyDeclaration
|
||||
: modifier* interfaceMemberDeclaration
|
||||
| ';'
|
||||
: modifier* interfaceMemberDeclaration # interfacemember
|
||||
| ';' # emptyinterface
|
||||
;
|
||||
|
||||
interfaceMemberDeclaration
|
||||
: constDeclaration
|
||||
| interfaceMethodDeclaration
|
||||
| genericInterfaceMethodDeclaration
|
||||
| interfaceDeclaration
|
||||
| annotationTypeDeclaration
|
||||
| classDeclaration
|
||||
| enumDeclaration
|
||||
| recordDeclaration // Java17
|
||||
: constDeclaration # interfaceconst
|
||||
| interfaceMethodDeclaration # interfacemethod
|
||||
| genericInterfaceMethodDeclaration # genericinterfacemethod
|
||||
| interfaceDeclaration # subinterface
|
||||
| annotationTypeDeclaration # interfaceannotationtype
|
||||
| classDeclaration # interfaceclass
|
||||
| enumDeclaration # interfaceenum
|
||||
| recordDeclaration # interfacerecord // Java17
|
||||
;
|
||||
|
||||
constDeclaration
|
||||
|
@ -0,0 +1,140 @@
|
||||
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.List;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import de.dhbwstuttgart.environment.PackageCrawler;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17ParserBaseVisitor;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.AnnotationclassmodContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassOrInterfaceModifierContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassorinterfacedeclContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassorinterfacemodContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.ModifierContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.NoclassorinterfaceContext;
|
||||
import de.dhbwstuttgart.parser.scope.GatherNames;
|
||||
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
||||
|
||||
public class ASTGen extends Java17ParserBaseVisitor<Object> {
|
||||
private JavaClassRegistry reg;
|
||||
private final GenericsRegistry globalGenerics;
|
||||
private String pkgName = "";
|
||||
Set<JavaClassName> imports = new HashSet<>();
|
||||
// PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH
|
||||
// bekommen
|
||||
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields = new HashMap<>();
|
||||
// PL 2019-10-23: Muss für jede Klasse neu initilisiert werden
|
||||
List<Statement> fieldInitializations = new ArrayList<>();
|
||||
|
||||
public ASTGen(JavaClassRegistry reg, GenericsRegistry globalGenerics) {
|
||||
// Die Generics müssen während des Bauens des AST erstellt werden,
|
||||
// da diese mit der Methode oder Klasse, in welcher sie deklariert werden
|
||||
// verknüpft sein müssen. Dennoch werden die Namen aller Generics in einer
|
||||
// globalen Datenbank benötigt.
|
||||
this.globalGenerics = globalGenerics;
|
||||
this.reg = reg;
|
||||
}
|
||||
|
||||
public JavaClassRegistry getReg() {
|
||||
return this.reg;
|
||||
}
|
||||
|
||||
public String convertQualifiedName(Java17Parser.QualifiedNameContext ctx) {
|
||||
String ret = "";
|
||||
for (Java17Parser.IdentifierContext ident : ctx.identifier()) {
|
||||
ret += ident.getText();
|
||||
if (ctx.identifier().iterator().hasNext()) {
|
||||
ret += '.';
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public SourceFile generate(Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler, ClassLoader classLoader)
|
||||
throws ClassNotFoundException {
|
||||
List<ClassOrInterface> classes = new ArrayList<>();
|
||||
Map<String, Integer> imports = GatherNames.getImports(ctx, packageCrawler, classLoader);
|
||||
this.imports = imports.keySet().stream().map(name -> reg.getName(name)).collect(Collectors.toSet());
|
||||
|
||||
return (SourceFile) this.visit(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceFile visitSrcfile(Java17Parser.SrcfileContext ctx) {
|
||||
for (Java17Parser.ClassOrInterfaceContext member : ctx.classOrInterface()) {
|
||||
ClassorinterfacedeclContext clsoif;
|
||||
if (member instanceof NoclassorinterfaceContext) {
|
||||
continue;
|
||||
} else {
|
||||
clsoif = new ClassorinterfacedeclContext(member);
|
||||
}
|
||||
ClassOrInterface newClass;
|
||||
int modifiers = 0;
|
||||
if (!clsoif.classOrInterfaceModifier().isEmpty()) {
|
||||
for (Java17Parser.ClassOrInterfaceModifierContext mod : clsoif.classOrInterfaceModifier()) {
|
||||
int newModifier = (Integer) visit(mod);
|
||||
modifiers += newModifier;
|
||||
}
|
||||
}
|
||||
fieldInitializations = new ArrayList<>(); // PL 2019-10-22: muss für jede Klasse neu initilisiert werden
|
||||
if (clsoif.classDeclaration() != null) {
|
||||
newClass = convertClass(clsoif.classDeclaration());
|
||||
} else {
|
||||
newClass = convertInterface(clsoif.interfaceDeclaration());
|
||||
}
|
||||
classes.add(newClass);
|
||||
}
|
||||
return new SourceFile(this.pkgName, classes, this.imports);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitModifier(ModifierContext ctx) {
|
||||
if (ctx.classOrInterfaceModifier() != null) {
|
||||
return visit(ctx.classOrInterfaceModifier());
|
||||
} else {
|
||||
return convertModifier(ctx.getText());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitClassOrInterfaceModifier(ClassOrInterfaceModifierContext ctx) {
|
||||
if (ctx.annotation() != null)
|
||||
return 0;
|
||||
return convertModifier(ctx.getText());
|
||||
}
|
||||
|
||||
public static int convertModifier(String modifier) {
|
||||
HashMap<String, Integer> modifiers = new HashMap<>();
|
||||
modifiers.put(Modifier.toString(Modifier.PUBLIC), Modifier.PUBLIC);
|
||||
modifiers.put(Modifier.toString(Modifier.PRIVATE), Modifier.PRIVATE);
|
||||
modifiers.put(Modifier.toString(Modifier.PROTECTED), Modifier.PROTECTED);
|
||||
modifiers.put(Modifier.toString(Modifier.ABSTRACT), Modifier.ABSTRACT);
|
||||
modifiers.put(Modifier.toString(Modifier.STATIC), Modifier.STATIC);
|
||||
modifiers.put(Modifier.toString(Modifier.STRICT), Modifier.STRICT);
|
||||
modifiers.put(Modifier.toString(Modifier.FINAL), Modifier.FINAL);
|
||||
modifiers.put(Modifier.toString(Modifier.TRANSIENT), Modifier.TRANSIENT);
|
||||
modifiers.put(Modifier.toString(Modifier.VOLATILE), Modifier.VOLATILE);
|
||||
modifiers.put(Modifier.toString(Modifier.SYNCHRONIZED), Modifier.SYNCHRONIZED);
|
||||
modifiers.put(Modifier.toString(Modifier.NATIVE), Modifier.NATIVE);
|
||||
modifiers.put(Modifier.toString(Modifier.INTERFACE), Modifier.INTERFACE);
|
||||
int ret = 0;
|
||||
for (String m : modifiers.keySet()) {
|
||||
if (modifier.contains(m))
|
||||
ret += modifiers.get(m);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user