Skip to content

Commit

Permalink
Merge pull request #1 from specs-feup/feature/antlr-support
Browse files Browse the repository at this point in the history
Feature/antlr support
  • Loading branch information
joaobispo authored Aug 2, 2024
2 parents c764aad + 38c45b3 commit 9afc507
Show file tree
Hide file tree
Showing 39 changed files with 1,438 additions and 155 deletions.
49 changes: 26 additions & 23 deletions AnyAst/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id 'distribution'
id 'distribution'
}

// Java project
Expand All @@ -17,34 +17,37 @@ repositories {
}

dependencies {
testImplementation "junit:junit:4.11"

implementation ':SpecsUtils'
implementation ':jOptions'

implementation group: 'com.google.code.gson', name: 'gson', version: '2.4'
testImplementation "junit:junit:4.11"

implementation ':SpecsUtils'
implementation ':jOptions'

implementation group: 'com.google.code.gson', name: 'gson', version: '2.4'

implementation group: 'org.antlr', name: 'antlr4-runtime', version: '4.13.1'
//antlr "org.antlr:antlr4:4.5.3"
}

java {
withSourcesJar()
withSourcesJar()
}


// Project sources
sourceSets {
main {
java {
srcDir 'src'
}
}

test {
java {
srcDir 'test'
}
resources {
srcDir 'resources'
}
}
main {
java {
srcDir 'src'
}
}

test {
java {
srcDir 'test'
}

resources {
srcDir 'resources'
}
}
}
6 changes: 6 additions & 0 deletions AnyAst/resources/pt/up/fe/specs/anycompiler/srl-ast.json.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
GenericAnyNode: STREAM::store: {args=[outputStream], id=node::1, type=STREAM::store}
GenericAnyNode: OP::+: {id=node::2, type=OP::+}
GenericAnyNode: STREAM::load: {args=[S2], id=node::3, type=STREAM::load}
GenericAnyNode: OP::*: {id=node::4, type=OP::*}
GenericAnyNode: STREAM::load: {args=[S1], id=node::5, type=STREAM::load}
GenericAnyNode: INPUT::VALUE: {args=[mult_factor], id=node::6, type=INPUT::VALUE}
88 changes: 79 additions & 9 deletions AnyAst/src/pt/up/fe/specs/anycompiler/ast/AnyNode.java
Original file line number Diff line number Diff line change
@@ -1,34 +1,104 @@
/**
* Copyright 2024 SPeCS.
*
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
*
* <p>
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License. under the License.
*/

package pt.up.fe.specs.anycompiler.ast;

import java.util.Collection;

import pt.up.fe.specs.util.collections.Attributes;
import pt.up.fe.specs.util.treenode.ATreeNode;

public abstract class AnyNode extends ATreeNode<AnyNode> {
import java.util.Arrays;
import java.util.Collection;
import java.util.Optional;

public abstract class AnyNode extends ATreeNode<AnyNode> implements Attributes {

public AnyNode(Collection<? extends AnyNode> children) {
super(children);
}

/**
* @return the kind of this node (e.g. MethodDeclaration, ClassDeclaration, etc.)
*/
public abstract String getKind();

public abstract Object getValue(String attribute);
/**
* @return a ordered collection of Strings with the hierarchy of the node, starting from the most specific class
* (e.g. a node that is an expr and a binaryExpr will return ['binaryExpr', 'expr']
*/
public Collection<String> getHierarchy() {
return Arrays.asList(getKind());
}

public abstract Object putValue(String attribute, Object value);
public abstract void setHierarchy(Collection<String> hierarchy);

/**
* @param attribute
* @returns the value of an attribute. To see all the attributes iterate the list provided by
* {@link AnyNode#getAttributes()}
* @deprecated use getObject() instead
*/
public Object getValue(String attribute) {
return getObject(attribute);
}

/**
* Sets the value of an attribute.
*
* @param attribute
* @param value
* @deprecated use putObject instead
*/
public Object putValue(String attribute, Object value) {
return putObject(attribute, value);
}

public abstract Collection<String> getAttributes();
// public abstract Collection<String> getAttributes();

/**
* This method receives a string, getAncestor methods that receive a class will not check the kind of the AnyNode.
*
* @param kind
* @return the first ancestor of the given kind, or Optional.empty() if no ancestor of that kind was found
*/
public Optional<AnyNode> getAncestor(String kind) {
var currentParent = getParent();
while (currentParent != null) {

if (currentParent.isInstance(kind)) {
return Optional.of(currentParent);
}

currentParent = currentParent.getParent();
}

return Optional.empty();
}

/**
* @param kind
* @return true if the node is an instance of the given kind
*/
public boolean isInstance(String kind) {
return getHierarchy().contains(kind);
}

/**
* Helper method which calls .toString() over the argument 'kind'.
*
* @param kind
* @return true if the node is an instance of the given kind
*/
public boolean isInstance(Object kind) {
return isInstance(kind.toString());
}
}
31 changes: 22 additions & 9 deletions AnyAst/src/pt/up/fe/specs/anycompiler/ast/GenericAnyNode.java
Original file line number Diff line number Diff line change
@@ -1,33 +1,32 @@
/**
* Copyright 2024 SPeCS.
*
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
*
* <p>
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License. under the License.
*/

package pt.up.fe.specs.anycompiler.ast;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.*;

public class GenericAnyNode extends AnyNode {

private final String kind;

private final Map<String, Object> attributes;
private Collection<String> hierarchy;

private GenericAnyNode(String kind, Map<String, Object> attributes, Collection<? extends AnyNode> children) {
super(children);
this.kind = kind;
this.attributes = attributes;
this.hierarchy = Arrays.asList(kind);
}

public GenericAnyNode(String kind, Collection<? extends AnyNode> children) {
Expand All @@ -38,6 +37,15 @@ public GenericAnyNode(String kind) {
this(kind, Collections.emptyList());
}

@Override
public Collection<String> getHierarchy() {
return hierarchy;
}

public void setHierarchy(Collection<String> hierarchy) {
this.hierarchy = hierarchy;
}

@Override
public String toContentString() {
return kind + ": " + attributes.toString();
Expand All @@ -48,15 +56,20 @@ public String getKind() {
return kind;
}

/*
public void setKind(String kind) {
this.kind = kind;
}
*/
@Override
public Object getValue(String attribute) {
public Object getObject(String attribute) {
// System.out.println("GENERIC: " + attributes);
// System.out.println("GET: " + attributes.get(attribute));
return attributes.get(attribute);
}

@Override
public Object putValue(String attribute, Object value) {
public Object putObject(String attribute, Object value) {
return attributes.put(attribute, value);
}

Expand Down
76 changes: 76 additions & 0 deletions AnyAst/src/pt/up/fe/specs/anycompiler/ast/visit/AVisitor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package pt.up.fe.specs.anycompiler.ast.visit;

import pt.up.fe.specs.anycompiler.ast.AnyNode;
import pt.up.fe.specs.util.SpecsCheck;

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;

/**
* @param <D>
* @param <R>
* @author Joao Bispo
*/
public abstract class AVisitor<D, R> implements Visitor<D, R> {

private final Map<String, BiFunction<AnyNode, D, R>> visitMap;
private BiFunction<AnyNode, D, R> defaultVisit;

public AVisitor() {
this.visitMap = new HashMap<>();

// Initialize visitors
buildVisitor();
}

protected abstract void buildVisitor();

@Override
public void addVisit(String kind, BiFunction<AnyNode, D, R> method) {
this.visitMap.put(kind, method);
}

@Override
public void setDefaultVisit(BiFunction<AnyNode, D, R> defaultVisit) {
this.defaultVisit = defaultVisit;
}

/**
* @param kind
* @return the visit method to use, or default if no visit method was found
*/
protected BiFunction<AnyNode, D, R> getVisit(AnyNode node) {

// Iterate over node hierarchy, in order, until a visitor is found
for (var kind : node.getHierarchy()) {
var visitMethod = visitMap.get(kind);

if (visitMethod != null) {
return visitMethod;
}
}

SpecsCheck.checkNotNull(defaultVisit,
() -> "Could not find a suitable visit method for node of kind " + node.getKind()
+ ", and no default visitor is set");

return defaultVisit;
}

@Override
public R visit(AnyNode node, D data) {
SpecsCheck.checkNotNull(node, () -> "Node should not be null");

return getVisit(node).apply(node, data);
}

protected R visitAllChildren(AnyNode node, D data) {
for (var child : node.getChildren()) {
visit(child, data);
}

return null;

}
}
Loading

0 comments on commit 9afc507

Please sign in to comment.