Commit 3450d47d authored by Thomas Michael Timmermanns's avatar Thomas Michael Timmermanns
Browse files

Added CoCos and tests.

Changed Split method and fixed Concatenate method.
Fixed the Alexnet example.
parent 683cbacd
......@@ -69,8 +69,9 @@ grammar CNNArch extends de.monticore.lang.math.Math {
ArchSimpleExpression = (arithmeticExpression:MathArithmeticExpression
| booleanExpression:MathBooleanExpression
| tupleExpression:TupleExpression);
| tupleExpression:TupleExpression
| string:StringLiteral);
TupleExpression implements MathExpression = "(" expressions:MathArithmeticExpression "," expressions:(MathArithmeticExpression || ",")* ")";
TupleExpression implements MathExpression = "(" expressions:MathExpression "," expressions:(MathExpression || ",")* ")";
}
\ No newline at end of file
......@@ -24,7 +24,8 @@ public class CNNArchPostResolveCocos {
public static CNNArchCoCoChecker createChecker() {
return new CNNArchCoCoChecker()
.addCoCo(new CheckVariableConstraints());
.addCoCo(new CheckLayerInputs())
.addCoCo(new CheckIOType());
}
}
......@@ -35,6 +35,14 @@ public class CheckArgument implements CNNArchASTArgumentCoCo {
"Parameter with name '" + node.getName() + "' does not exist."
, node.get_SourcePositionStart());
}
else {
//check argument constraints before resolve.
if (argument.getRhs().isResolvable()) {
argument.getRhs().resolveOrError();
argument.checkConstraints();
argument.getRhs().reset();
}
}
}
}
......@@ -20,31 +20,13 @@
*/
package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._ast.ASTVariable;
import de.monticore.lang.monticar.cnnarch._symboltable.VariableSymbol;
import de.monticore.lang.monticar.cnnarch.helper.Constraints;
import de.monticore.lang.monticar.cnnarch._ast.ASTArchitecture;
import java.util.HashSet;
import java.util.Set;
public class CheckVariableConstraints implements CNNArchASTVariableCoCo {
/*@Override
public void check(ASTArchitecture node) {
ArchitectureSymbol architecture = (ArchitectureSymbol) node.getSymbol().get();
}*/
Set<VariableSymbol> variableSet = new HashSet<>();
public class CheckIOType implements CNNArchASTArchitectureCoCo {
@Override
public void check(ASTVariable node) {
VariableSymbol variable = (VariableSymbol) node.getSymbol().get();
if (!variableSet.contains(variable)) {
if (variable.hasExpression() && variable.getExpression().isResolvable()) {
variable.getExpression().resolveOrError();
Constraints.check(variable);
}
}
variableSet.add(variable);
public void check(ASTArchitecture node) {
//todo:
}
}
\ No newline at end of file
}
/**
*
* ******************************************************************************
* MontiCAR Modeling Family, www.se-rwth.de
* Copyright (c) 2017, Software Engineering Group at RWTH Aachen,
* All rights reserved.
*
* This project is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
* *******************************************************************************
*/
package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._ast.ASTArchitecture;
public class CheckLayerInputs implements CNNArchASTArchitectureCoCo {
@Override
public void check(ASTArchitecture node) {
//todo:
}
}
......@@ -37,7 +37,7 @@ public class CheckMethodDeclaration implements CNNArchASTMethodDeclarationCoCo {
Set<String> methodNames = new HashSet<>();
//for recursion check
Set<MethodDeclarationSymbol> seenMethods = new HashSet<>();
boolean done = false;
boolean done;
@Override
......@@ -58,6 +58,7 @@ public class CheckMethodDeclaration implements CNNArchASTMethodDeclarationCoCo {
methodNames.add(name);
}
done = false;
MethodDeclarationSymbol method = (MethodDeclarationSymbol) node.getSymbol().get();
checkForRecursion(method, method.getBody());
}
......
......@@ -40,7 +40,7 @@ public class CheckMethodLayer implements CNNArchASTMethodLayerCoCo{
for (ASTArgument argument : node.getArguments()){
String name = argument.getName();
if (nameSet.contains(name)){
Log.error("0" + ErrorCodes.DUPLICATED_NAME_CODE + " Duplicated name: " + name +
Log.error("0" + ErrorCodes.DUPLICATED_ARG_CODE + " Duplicated name: " + name +
". Multiple values assigned to the same argument."
, argument.get_SourcePositionStart());
}
......
......@@ -22,6 +22,8 @@ package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._ast.ASTParameter;
import de.monticore.lang.monticar.cnnarch._ast.ASTVariable;
import de.monticore.lang.monticar.cnnarch._symboltable.VariableSymbol;
import de.monticore.lang.monticar.cnnarch.helper.Constraints;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.lang.monticar.cnnarch.helper.PredefinedVariables;
import de.monticore.symboltable.Symbol;
......@@ -38,6 +40,14 @@ public class CheckVariable implements CNNArchASTVariableCoCo {
@Override
public void check(ASTVariable node) {
checkForIllegalNames(node);
checkForDuplicates(node);
checkConstraints(node);
}
private void checkForIllegalNames(ASTVariable node){
String name = node.getName();
if (name.isEmpty() || !Character.isLowerCase(name.codePointAt(0))){
Log.error("0" + ErrorCodes.ILLEGAL_NAME_CODE + " Illegal name: " + name +
......@@ -49,7 +59,10 @@ public class CheckVariable implements CNNArchASTVariableCoCo {
". No variable can be named 'true' or 'false'"
, node.get_SourcePositionStart());
}
}
private void checkForDuplicates(ASTVariable node){
String name = node.getName();
boolean duplicated = false;
if (variableNames.contains(name)){
if (node instanceof ASTParameter){
......@@ -73,4 +86,12 @@ public class CheckVariable implements CNNArchASTVariableCoCo {
}
}
private void checkConstraints(ASTVariable node){
VariableSymbol variable = (VariableSymbol) node.getSymbol().get();
if (variable.hasExpression() && variable.getExpression().isResolvable()) {
variable.getExpression().resolveOrError();
Constraints.check(variable);
}
}
}
......@@ -84,6 +84,13 @@ abstract public class ArchExpressionSymbol extends CommonSymbol {
*/
abstract public boolean isTuple();
public boolean isString(){
if (getValue().isPresent()){
return getStringValue().isPresent();
}
return false;
}
/**
* Checks whether the value is an integer. This can only be checked if the expression is resolved.
* If true getRhs() will return an Integer.
......@@ -195,6 +202,14 @@ abstract public class ArchExpressionSymbol extends CommonSymbol {
return Optional.empty();
}
public Optional<String> getStringValue(){
Optional<Object> optValue = getValue();
if (optValue.isPresent() && (optValue.get() instanceof String)){
return Optional.of((String) optValue.get());
}
return Optional.empty();
}
public Optional<List<Integer>> getIntTupleValues(){
Optional<List<Object>> optValue = getTupleValues();
if (optValue.isPresent()){
......
......@@ -20,10 +20,7 @@
*/
package de.monticore.lang.monticar.cnnarch._symboltable;
import de.monticore.lang.math.math._symboltable.expression.MathArithmeticExpressionSymbol;
import de.monticore.lang.math.math._symboltable.expression.MathCompareExpressionSymbol;
import de.monticore.lang.math.math._symboltable.expression.MathExpressionSymbol;
import de.monticore.lang.math.math._symboltable.expression.MathNameExpressionSymbol;
import de.monticore.lang.math.math._symboltable.expression.*;
import de.monticore.lang.monticar.cnnarch.helper.Calculator;
import de.monticore.lang.monticar.cnnarch.helper.ExpressionHelper;
......@@ -58,8 +55,10 @@ public class ArchSimpleExpressionSymbol extends ArchExpressionSymbol {
@Override
public void reset(){
if (getMathExpression().isPresent()){
setValue(null);
setUnresolvableVariables(null);
if (getMathExpression().isPresent()){
setValue(null);
setUnresolvableVariables(null);
}
}
}
......@@ -71,31 +70,32 @@ public class ArchSimpleExpressionSymbol extends ArchExpressionSymbol {
@Override
public boolean isBoolean() {
if (getMathExpression().isPresent() && !(getMathExpression().get() instanceof MathNameExpressionSymbol)){
return getMathExpression().get().getRealMathExpressionSymbol() instanceof MathCompareExpressionSymbol;
}
else {
return getBooleanValue().isPresent();
if (getMathExpression().get().getRealMathExpressionSymbol() instanceof MathCompareExpressionSymbol){
return true;
}
}
return getBooleanValue().isPresent();
}
@Override
public boolean isNumber() {
if (getMathExpression().isPresent() && !(getMathExpression().get() instanceof MathNameExpressionSymbol)){
return getMathExpression().get().getRealMathExpressionSymbol() instanceof MathArithmeticExpressionSymbol;
}
else {
return getDoubleValue().isPresent();
if (getMathExpression().isPresent()){
MathExpressionSymbol mathExp = getMathExpression().get().getRealMathExpressionSymbol();
if (mathExp instanceof MathArithmeticExpressionSymbol || mathExp instanceof MathNumberExpressionSymbol){
return true;
}
}
return getDoubleValue().isPresent();
}
@Override
public boolean isTuple() {
if (getMathExpression().isPresent() && !(getMathExpression().get() instanceof MathNameExpressionSymbol)){
return getMathExpression().get().getRealMathExpressionSymbol() instanceof TupleExpressionSymbol;
}
else {
return getTupleValues().isPresent();
if (getMathExpression().get().getRealMathExpressionSymbol() instanceof TupleExpressionSymbol){
return true;
}
}
return getTupleValues().isPresent();
}
protected void computeUnresolvableVariables(Set<VariableSymbol> unresolvableVariables, Set<VariableSymbol> allVariables) {
......@@ -233,6 +233,12 @@ public class ArchSimpleExpressionSymbol extends ArchExpressionSymbol {
return res;
}
public static ArchSimpleExpressionSymbol of(String value){
ArchSimpleExpressionSymbol res = new ArchSimpleExpressionSymbol();
res.setValue(value);
return res;
}
public static ArchSimpleExpressionSymbol of(MathExpressionSymbol expressions){
ArchSimpleExpressionSymbol res = new ArchSimpleExpressionSymbol();
res.setMathExpression(expressions);
......
......@@ -67,7 +67,12 @@ public class ArchitectureSymbol extends ArchitectureSymbolTOP {
public void resolve(){
getBody().checkIfResolvable();
Set<VariableSymbol> set = getBody().resolve();
try{
getBody().resolve();
}
catch (ArchResolveException e){
//do nothing; error is already logged
}
}
public boolean isResolved(){
......
......@@ -90,16 +90,26 @@ public class ArgumentSymbol extends CommonSymbol {
//do not call if value is a sequence
public void set(){
if (getRhs().isSimpleValue()){
getRhs().resolveOrError();
Constraints.check(this);
if (getRhs().isResolved() && getRhs().isSimpleValue()){
getParameter().setExpression((ArchSimpleExpressionSymbol) getRhs());
}
else {
throw new IllegalStateException("The value of the parameter is set to a sequence. This should never happen.");
throw new IllegalStateException("The value of the parameter is set to a sequence or the expression is not resolved. This should never happen.");
}
}
public void resolveExpression() throws ArchResolveException {
getRhs().resolveOrError();
boolean valid = Constraints.check(this);
if (!valid){
throw new ArchResolveException();
}
}
public void checkConstraints(){
Constraints.check(this);
}
public List<List<ArgumentSymbol>> split(){
if (getRhs().isRange()){
getRhs().resolveOrError();
......@@ -116,6 +126,9 @@ public class ArgumentSymbol extends CommonSymbol {
}
ArgumentSymbol argument = new Builder().parameter(getParameter()).value(value).build();
if (getAstNode().isPresent()){
argument.setAstNode(getAstNode().get());
}
serialArgumentList.add(argument);
}
arguments.add(serialArgumentList);
......
......@@ -274,31 +274,22 @@ public class CNNArchSymbolTableCreator extends de.monticore.symboltable.CommonSy
addToScopeAndLinkWithNode(variable, node);
}
@Override
public void endVisit(ASTMathExpression node) {
boolean t = true;
boolean b = t;
}
@Override
public void visit(ASTArchSimpleExpression ast) {
ArchSimpleExpressionSymbol sym = new ArchSimpleExpressionSymbol();
addToScopeAndLinkWithNode(sym, ast);
}
@Override
public void endVisit(ASTArchSimpleExpression ast) {
MathExpressionSymbol mathExp;
ArchSimpleExpressionSymbol sym = new ArchSimpleExpressionSymbol();
MathExpressionSymbol mathExp = null;
if (ast.getArithmeticExpression().isPresent()) {
mathExp = (MathExpressionSymbol) ast.getArithmeticExpression().get().getSymbol().get();
}
else if (ast.getBooleanExpression().isPresent()) {
mathExp = (MathExpressionSymbol) ast.getBooleanExpression().get().getSymbol().get();
}
else {
else if (ast.getTupleExpression().isPresent()){
mathExp = (MathExpressionSymbol) ast.getTupleExpression().get().getSymbol().get();
}
ArchSimpleExpressionSymbol sym = new ArchSimpleExpressionSymbol();
else {
sym.setValue(ast.getString().get().getValue());
}
sym.setMathExpression(mathExp);
addToScopeAndLinkWithNode(sym, ast);
}
......@@ -475,6 +466,7 @@ public class CNNArchSymbolTableCreator extends de.monticore.symboltable.CommonSy
.parameter(methodLayer.getMethod().getParameter("index").get())
.value((ArchSimpleExpressionSymbol) node.getIndex().getSymbol().get())
.build();
indexArgument.setAstNode(node.getIndex());
addToScope(indexArgument);
methodLayer.setArguments(Collections.singletonList(indexArgument));
......
......@@ -91,7 +91,7 @@ public class CompositeLayerSymbol extends LayerSymbol {
}*/
@Override
public Set<VariableSymbol> resolve() {
public Set<VariableSymbol> resolve() throws ArchResolveException {
if (!isResolved()) {
if (isResolvable()) {
List<LayerSymbol> resolvedLayers = new ArrayList<>();
......@@ -104,7 +104,7 @@ public class CompositeLayerSymbol extends LayerSymbol {
}
@Override
protected void resolveExpressions() {
protected void resolveExpressions() throws ArchResolveException {
for (LayerSymbol layer : getLayers()){
layer.resolveExpressions();
}
......
......@@ -20,6 +20,7 @@
*/
package de.monticore.lang.monticar.cnnarch._symboltable;
import de.monticore.lang.monticar.cnnarch.helper.Constraints;
import de.monticore.symboltable.MutableScope;
import de.monticore.symboltable.Symbol;
......@@ -82,7 +83,7 @@ public class IOLayerSymbol extends LayerSymbol {
}*/
@Override
public Set<VariableSymbol> resolve() {
public Set<VariableSymbol> resolve() throws ArchResolveException {
if (!isResolved()) {
if (isResolvable()) {
resolveExpressions();
......@@ -100,7 +101,6 @@ public class IOLayerSymbol extends LayerSymbol {
isResolved = false;
}
}
//todo getShape().isResolved
if (!getDefinition().getShape().isResolved()){
isResolved = false;
}
......@@ -142,8 +142,6 @@ public class IOLayerSymbol extends LayerSymbol {
return Optional.of(Collections.nCopies(getParallelLength().get(), 1));
}
@Override
protected void putInScope(MutableScope scope) {
Collection<Symbol> symbolsInScope = scope.getLocalSymbols().get(getName());
......@@ -165,13 +163,22 @@ public class IOLayerSymbol extends LayerSymbol {
.definition(getDefinition())
.arrayAccess(arrayAccessCopy)
.build();
if (getAstNode().isPresent()){
copy.setAstNode(getAstNode().get());
}
return copy;
}
@Override
protected void resolveExpressions() {
protected void resolveExpressions() throws ArchResolveException {
if (getArrayAccess().isPresent()){
getArrayAccess().get().resolveOrError();
boolean valid = true;
valid = valid && Constraints.INTEGER.check(getArrayAccess().get(), getSourcePosition(), getName());
valid = valid && Constraints.NON_NEGATIVE.check(getArrayAccess().get(), getSourcePosition(), getName());
if (!valid){
throw new ArchResolveException();
}
}
}
......
......@@ -111,14 +111,14 @@ public abstract class LayerSymbol extends CommonScopeSpanningSymbol {
setUnresolvableVariables(unresolvableVariables);
}
public void resolveOrError(){
public void resolveOrError() throws ArchResolveException{
Set<VariableSymbol> names = resolve();
if (!isResolved()){
throw new IllegalStateException("The following names could not be resolved: " + Joiners.COMMA.join(getUnresolvableVariables()));
}
}
abstract public Set<VariableSymbol> resolve();
abstract public Set<VariableSymbol> resolve() throws ArchResolveException;
abstract protected List<ShapeSymbol> computeOutputShapes();
......@@ -151,7 +151,7 @@ public abstract class LayerSymbol extends CommonScopeSpanningSymbol {
abstract protected void putInScope(MutableScope scope);
abstract protected void resolveExpressions();
abstract protected void resolveExpressions() throws ArchResolveException;
/*abstract public void reset();*/
}
......@@ -108,13 +108,14 @@ public class MethodDeclarationSymbol extends CommonScopeSpanningSymbol {
}
public LayerSymbol call(MethodLayerSymbol layer) {
public LayerSymbol call(MethodLayerSymbol layer) throws ArchResolveException{
checkForSequence(layer.getArguments());
if (isPredefined()){
return layer;
}
else {
reset();
set(layer.getArguments());
CompositeLayerSymbol copy = getBody().copy();
......@@ -132,7 +133,6 @@ public class MethodDeclarationSymbol extends CommonScopeSpanningSymbol {
for (VariableSymbol param : getParameters()){
param.reset();
}
//getBody().reset();
}
private void set(List<ArgumentSymbol> arguments){
......
......@@ -131,11 +131,16 @@ public class MethodLayerSymbol extends LayerSymbol {
}
public boolean isResolved(){
return getResolvedThis().isPresent();
if (getResolvedThis().isPresent() && getResolvedThis().get() != this){
return getResolvedThis().get().isResolved();
}
else {
return getResolvedThis().isPresent();
}
}
@Override
public Set<VariableSymbol> resolve() {
public Set<VariableSymbol> resolve() throws ArchResolveException {
if (!isResolved()) {
if (isResolvable()) {
getMethod();
......@@ -172,9 +177,9 @@ public class MethodLayerSymbol extends LayerSymbol {
}
}
protected void resolveExpressions(){
protected void resolveExpressions() throws ArchResolveException{
for (ArgumentSymbol argument : getArguments()){
argument.getRhs().resolveOrError();
argument.resolveExpression();
}
}
......@@ -234,20 +239,24 @@ public class MethodLayerSymbol extends LayerSymbol {
@Override
protected List<ShapeSymbol> computeOutputShapes() {
if (getMethod().isPredefined()){
BiFunction<List<ShapeSymbol>, MethodLayerSymbol, List<ShapeSymbol>> shapeFunction = getMethod().getShapeFunction();
return shapeFunction.apply(getInputLayer().get().getOutputShapes(), this);
}
else {
Set<VariableSymbol> unresolvableVariables = resolve();
if (unresolvableVariables.isEmpty()){