Commit aac22a6d authored by Sebastian Nickels's avatar Sebastian Nickels

Renamed VariableSymbol to ParameterSymbol, introduced layer variable...

Renamed VariableSymbol to ParameterSymbol, introduced layer variable declarations and changed IOSymbol to VariableSymbol which now combines IO variables and layer variables
parent 4a2199ac
......@@ -61,13 +61,15 @@ grammar CNNArch extends de.monticore.CommonExpressions, de.monticore.lang.Math,
methodDeclaration:LayerDeclaration*
instructions:(Instruction || ";")+ ";";
interface Instruction;
Instruction = (LayerVariableDeclaration | Stream);
Stream implements Instruction = elements:(ArchitectureElement || "->")+;
LayerVariableDeclaration = "layer" Layer Name;
Stream = elements:(ArchitectureElement || "->")+;
interface ArchitectureElement;
IOElement implements ArchitectureElement = Name ("[" index:ArchSimpleExpression "]")?;
Variable implements ArchitectureElement = Name ("." (member:"output" | member:Name))? ("[" index:ArchSimpleExpression "]")?;
Constant implements ArchitectureElement = ArchSimpleExpression;
......@@ -86,11 +88,11 @@ grammar CNNArch extends de.monticore.CommonExpressions, de.monticore.lang.Math,
/* ====== Variables/Arguments ======*/
interface Variable;
interface ArchParameter;
ArchitectureParameter implements Variable = Name ("=" default:ArchSimpleExpression)? ;
ArchitectureParameter implements ArchParameter = Name ("=" default:ArchSimpleExpression)? ;
LayerParameter implements Variable = Name ("=" default:ArchSimpleExpression)? ;
LayerParameter implements ArchParameter = Name ("=" default:ArchSimpleExpression)? ;
interface ArchArgument;
......@@ -119,7 +121,7 @@ grammar CNNArch extends de.monticore.CommonExpressions, de.monticore.lang.Math,
(serial2:"->" | parallel2:"|")
end:ArchSimpleExpression "]";
/**
Expressions for variable values.
Expressions for parameter and variable values.
*/
ArchSimpleExpression = (arithmeticExpression:ArchArithmeticExpression
| booleanExpression:ArchBooleanExpression
......@@ -168,7 +170,7 @@ grammar CNNArch extends de.monticore.CommonExpressions, de.monticore.lang.Math,
/* =================================*/
/* ============ ASTRULES ===========*/
/* =================================*/
ast Variable = method String getName(){};
ast ArchParameter = method String getName(){};
ast ArchSpecialArgument = method public String getName(){return "";}; //Override is necessary
ast ArchArgument = method String getName(){}
method ASTArchExpression getRhs(){};
......
......@@ -67,13 +67,17 @@ public class CNNArchCocos {
.addCoCo(new CheckElementInputs())
.addCoCo(new CheckIOAccessAndIOMissing())
.addCoCo(new CheckArchitectureFinished())
.addCoCo(new CheckNetworkStreamMissing());
.addCoCo(new CheckNetworkStreamMissing())
.addCoCo(new CheckVariableMember())
.addCoCo(new CheckLayerVariableDeclarationLayerType())
.addCoCo(new CheckLayerVariableDeclarationIsUsed());
}
//checks cocos based on symbols before the resolve method of the ArchitectureSymbol is called
public static CNNArchSymbolCoCoChecker createCNNArchPreResolveSymbolChecker() {
return new CNNArchSymbolCoCoChecker()
.addCoCo(new CheckIOName())
.addCoCo(new CheckVariableDeclarationName())
.addCoCo(new CheckVariableName())
.addCoCo(new CheckExpressions());
}
......@@ -82,7 +86,7 @@ public class CNNArchCocos {
return new CNNArchCoCoChecker()
.addCoCo(new CheckLayer())
.addCoCo(new CheckRangeOperators())
.addCoCo(new CheckVariableName())
.addCoCo(new CheckParameterName())
.addCoCo(new CheckLayerName())
.addCoCo(new CheckArgument())
.addCoCo(new CheckLayerRecursion());
......
......@@ -45,8 +45,8 @@ public class CNNArchSymbolCoCo {
else if (sym instanceof ArchTypeSymbol){
check((ArchTypeSymbol) sym);
}
else if (sym instanceof VariableSymbol){
check((VariableSymbol) sym);
else if (sym instanceof ParameterSymbol){
check((ParameterSymbol) sym);
}
else if (sym instanceof ArgumentSymbol){
check((ArgumentSymbol) sym);
......@@ -54,8 +54,8 @@ public class CNNArchSymbolCoCo {
else if (sym instanceof CNNArchCompilationUnitSymbol){
check((CNNArchCompilationUnitSymbol) sym);
}
else if (sym instanceof IODeclarationSymbol){
check((IODeclarationSymbol) sym);
else if (sym instanceof VariableDeclarationSymbol){
check((VariableDeclarationSymbol) sym);
}
else if (sym instanceof MathExpressionSymbol){
check((MathExpressionSymbol) sym);
......@@ -91,7 +91,7 @@ public class CNNArchSymbolCoCo {
//Override if needed
}
public void check(VariableSymbol sym){
public void check(ParameterSymbol sym){
//Override if needed
}
......@@ -103,7 +103,7 @@ public class CNNArchSymbolCoCo {
//Override if needed
}
public void check(IODeclarationSymbol sym){
public void check(VariableDeclarationSymbol sym){
//Override if needed
}
......
......@@ -33,7 +33,7 @@ public class CheckArchitectureFinished extends CNNArchSymbolCoCo {
if (!stream.getOutputTypes().isEmpty()){
Log.error("0" + ErrorCodes.UNFINISHED_ARCHITECTURE + " The architecture is not finished. " +
"There are still open streams at the end of the architecture. "
, architecture.getSourcePosition());
, stream.getSourcePosition());
}
}
if (architecture.getInputs().isEmpty()){
......
......@@ -24,7 +24,7 @@ import de.monticore.lang.math._symboltable.expression.MathExpressionSymbol;
import de.monticore.lang.math._symboltable.expression.MathNameExpressionSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchExpressionSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchSimpleExpressionSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.VariableSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.ParameterSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.lang.monticar.cnnarch.helper.Utils;
import de.se_rwth.commons.logging.Log;
......@@ -47,11 +47,11 @@ public class CheckExpressions extends CNNArchSymbolCoCo {
for (MathExpressionSymbol subMathExp : Utils.createSubExpressionList(mathExpression)){
if (subMathExp instanceof MathNameExpressionSymbol){
String name = ((MathNameExpressionSymbol) subMathExp).getNameToAccess();
Collection<VariableSymbol> variableCollection = expression.getEnclosingScope().resolveMany(name, VariableSymbol.KIND);
Collection<ParameterSymbol> parameterCollection = expression.getEnclosingScope().resolveMany(name, ParameterSymbol.KIND);
if (variableCollection.isEmpty()){
Log.error("0" + ErrorCodes.UNKNOWN_VARIABLE_NAME + " Unknown variable name. " +
"The variable '" + name + "' does not exist. "
if (parameterCollection.isEmpty()){
Log.error("0" + ErrorCodes.UNKNOWN_PARAMETER_NAME + " Unknown parameter name. " +
"The parameter '" + name + "' does not exist. "
, subMathExp.getSourcePosition());
}
}
......
......@@ -22,7 +22,7 @@ package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchitectureSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.IODeclarationSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.IOSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.VariableSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.Joiners;
import de.se_rwth.commons.logging.Log;
......@@ -53,7 +53,7 @@ public class CheckIOAccessAndIOMissing extends CNNArchSymbolCoCo {
, ioDeclaration.getSourcePosition());
}
else {
for (IOSymbol ioElement : ioDeclaration.getConnectedElements()){
for (VariableSymbol ioElement : ioDeclaration.getConnectedElements()){
if (ioElement.getArrayAccess().isPresent()){
Log.error("0" + ErrorCodes.INVALID_ARRAY_ACCESS + " Invalid IO array access. " +
"This input or output is not an array."
......@@ -67,7 +67,7 @@ public class CheckIOAccessAndIOMissing extends CNNArchSymbolCoCo {
private void checkIOArray(IODeclarationSymbol ioDeclaration){
List<Integer> unusedIndices = IntStream.range(0, ioDeclaration.getArrayLength()).boxed().collect(Collectors.toList());
for (IOSymbol ioElement : ioDeclaration.getConnectedElements()){
for (VariableSymbol ioElement : ioDeclaration.getConnectedElements()){
if (ioElement.getArrayAccess().isPresent()){
Optional<Integer> arrayAccess = ioElement.getArrayAccess().get().getIntValue();
if (arrayAccess.isPresent() && arrayAccess.get() >= 0 && arrayAccess.get() < ioDeclaration.getArrayLength()){
......
......@@ -46,8 +46,8 @@ public class CheckIOType extends CNNArchSymbolCoCo {
"Type has to be rational or whole number.");
}
if (type.getDimensionSymbols().size() == 2 || type.getDimensionSymbols().size() > 3){
Log.error("0" + ErrorCodes.INVALID_IO_TYPE + " Invalid dimension shape. Shape has to be either of size 1 or 3 (e.g. {number_of_channels, height, width})."
if (type.getDimensionSymbols().size() > 3){
Log.error("0" + ErrorCodes.INVALID_IO_TYPE + " Invalid dimension shape. Shape has to be an tuple either of size 1, 2 or 3 (e.g. {number_of_channels, height, width})."
, ioDeclaration.getSourcePosition());
}
else {
......@@ -60,19 +60,6 @@ public class CheckIOType extends CNNArchSymbolCoCo {
}
}
}
if (Log.getFindings().isEmpty()){
if (ioDeclaration.isInput() && type.getChannels() != 3 && type.getChannels() != 1){
if (type.getHeight() > 1 || type.getWidth() > 1){
Log.warn("The number of channels of input '" +
ioDeclaration.getName() + "' is: " + type.getChannels() +
". Heigth: " + type.getHeight() + ". Width: " + type.getWidth() + ". " +
"This is unusual and a sign of an error. " +
"The standard data format of this language is CHW and not HWC. "
, ioDeclaration.getSourcePosition());
}
}
}
}
}
......@@ -25,7 +25,7 @@ import de.monticore.lang.monticar.cnnarch._ast.ASTLayer;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchitectureSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.LayerDeclarationSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.LayerSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.VariableSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.ParameterSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.Joiners;
import de.se_rwth.commons.logging.Log;
......@@ -60,7 +60,7 @@ public class CheckLayer implements CNNArchASTLayerCoCo{
}
else {
Set<String> requiredArguments = new HashSet<>();
for (VariableSymbol param : layerDeclaration.getParameters()){
for (ParameterSymbol param : layerDeclaration.getParameters()){
if (!param.getDefaultExpression().isPresent()){
requiredArguments.add(param.getName());
}
......
/**
*
* ******************************************************************************
* 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._symboltable.*;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.logging.Log;
import java.util.Collection;
public class CheckLayerVariableDeclarationIsUsed extends CNNArchSymbolCoCo {
@Override
public void check(VariableDeclarationSymbol sym) {
if (sym instanceof LayerVariableDeclarationSymbol) {
LayerVariableDeclarationSymbol layerVariableDeclaration = (LayerVariableDeclarationSymbol) sym;
boolean isUsed = false;
for (SerialCompositeElementSymbol stream : layerVariableDeclaration.getLayer().getArchitecture().getStreams()) {
Collection<ArchitectureElementSymbol> elements =
stream.getSpannedScope().resolveMany(layerVariableDeclaration.getName(), ArchitectureElementSymbol.KIND);
for (ArchitectureElementSymbol element : elements) {
if (element instanceof VariableSymbol && ((VariableSymbol) element).getMember() == VariableSymbol.Member.NONE) {
isUsed = true;
break;
}
}
if (isUsed) {
break;
}
}
if (!isUsed) {
Log.error("0" + ErrorCodes.UNUSED_LAYER + " Unused layer. " +
"Declared layer variables need to be used as layer at least once.",
sym.getSourcePosition());
}
}
}
}
/**
*
* ******************************************************************************
* 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._symboltable.*;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.logging.Log;
public class CheckLayerVariableDeclarationLayerType extends CNNArchSymbolCoCo {
@Override
public void check(VariableDeclarationSymbol sym) {
if (sym instanceof LayerVariableDeclarationSymbol) {
LayerVariableDeclarationSymbol layerVariableDeclaration = (LayerVariableDeclarationSymbol) sym;
// Only allow predefined layers to be declared as layer variable
if (!layerVariableDeclaration.getLayer().getDeclaration().isPredefined()) {
Log.error("0" + ErrorCodes.ILLEGAL_LAYER_USE + " Illegal layer use. " +
"Only predefined layers can be used as a type for a layer variable.",
sym.getSourcePosition());
}
}
}
}
......@@ -29,14 +29,14 @@ public class CheckNetworkStreamMissing extends CNNArchSymbolCoCo {
@Override
public void check(ArchitectureSymbol architecture) {
boolean hasNetworkStream = false;
boolean hasTrainableStream = false;
for (CompositeElementSymbol stream : architecture.getStreams()) {
hasNetworkStream |= stream.isNetwork();
hasTrainableStream |= stream.isTrainable();
}
if (!hasNetworkStream) {
Log.error("0" + ErrorCodes.MISSING_NETWORK_STREAM + " The architecture has no network stream. "
if (!hasTrainableStream) {
Log.error("0" + ErrorCodes.MISSING_TRAINABLE_STREAM + " The architecture has no trainable stream. "
, architecture.getSourcePosition());
}
}
......
/**
*
* ******************************************************************************
* 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.ASTLayerParameter;
import de.monticore.lang.monticar.cnnarch._ast.ASTArchParameter;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.lang.monticar.cnnarch.predefined.AllPredefinedVariables;
import de.monticore.symboltable.Symbol;
import de.se_rwth.commons.logging.Log;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class CheckParameterName implements CNNArchASTArchParameterCoCo {
Set<String> parameterNames = new HashSet<>();
@Override
public void check(ASTArchParameter node) {
checkForIllegalNames(node);
checkForDuplicates(node);
}
private void checkForIllegalNames(ASTArchParameter node){
String name = node.getName();
if (name.isEmpty() || !Character.isLowerCase(name.codePointAt(0))){
Log.error("0" + ErrorCodes.ILLEGAL_NAME + " Illegal name: " + name +
". All new parameter and method names have to start with a lowercase letter. "
, node.get_SourcePositionStart());
}
else if (name.equals(AllPredefinedVariables.TRUE_NAME) || name.equals(AllPredefinedVariables.FALSE_NAME)){
Log.error("0" + ErrorCodes.ILLEGAL_NAME + " Illegal name: " + name +
". No parameter can be named 'true' or 'false'"
, node.get_SourcePositionStart());
}
else if (name.equals(AllPredefinedVariables.CONDITIONAL_ARG_NAME.toLowerCase())){
Log.error("0" + ErrorCodes.ILLEGAL_NAME + " Illegal name: " + name +
". No parameter can be named 'if'"
, node.get_SourcePositionStart());
}
}
private void checkForDuplicates(ASTArchParameter node){
String name = node.getName();
if (parameterNames.contains(name)){
if (node instanceof ASTLayerParameter){
Collection<Symbol> allParametersWithSameName = node.getEnclosingScopeOpt().get().getLocalSymbols().get(name);
if (allParametersWithSameName.size() > 1){
duplicationError(node);
}
}
else {
duplicationError(node);
}
}
else{
parameterNames.add(name);
}
}
private void duplicationError(ASTArchParameter node){
Log.error("0" + ErrorCodes.DUPLICATED_NAME + " Duplicated parameter name. " +
"The name '" + node.getName() + "' is already used."
, node.get_SourcePositionStart());
}
}
\ No newline at end of file
......@@ -20,10 +20,7 @@
*/
package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.commonexpressions._ast.ASTArguments;
import de.monticore.lang.monticar.cnnarch._ast.ASTArchArgument;
import de.monticore.lang.monticar.cnnarch._ast.ASTLayer;
import de.monticore.lang.monticar.cnnarch._ast.ASTLayerParameter;
import de.monticore.lang.monticar.cnnarch._ast.ASTUnroll;
import de.monticore.lang.monticar.cnnarch._symboltable.*;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
......@@ -62,7 +59,7 @@ public class CheckUnroll implements CNNArchASTUnrollCoCo{
}
else {
Set<String> requiredArguments = new HashSet<>();
for (VariableSymbol param : layerDeclaration.getParameters()){
for (ParameterSymbol param : layerDeclaration.getParameters()){
if (!param.getDefaultExpression().isPresent()){
requiredArguments.add(param.getName());
}
......
/**
*
* ******************************************************************************
* 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._symboltable.*;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.logging.Log;
import java.util.HashSet;
import java.util.Set;
public class CheckVariableDeclarationName extends CNNArchSymbolCoCo {
Set<String> variableNames = new HashSet<>();
@Override
public void check(VariableDeclarationSymbol sym) {
String name = sym.getName();
if (name.isEmpty() || name.endsWith("_")) {
Log.error("0" + ErrorCodes.ILLEGAL_NAME + " Illegal variable name. " +
"Variable names cannot end with \"_\"",
sym.getSourcePosition());
}
if (variableNames.contains(name)) {
Log.error("0" + ErrorCodes.DUPLICATED_NAME + " Duplicated variable name. " +
"The name '" + name + "' is already used.",
sym.getSourcePosition());
}
else {
variableNames.add(name);
}
}
}
......@@ -21,52 +21,38 @@
package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchitectureElementSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.IODeclarationSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.IOSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.LayerDeclarationSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.PredefinedLayerDeclaration;
import de.monticore.lang.monticar.cnnarch._symboltable.VariableSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.logging.Log;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class CheckIOName extends CNNArchSymbolCoCo {
private Set<IODeclarationSymbol> checkedIODeclarations = new HashSet<>();
public class CheckVariableMember extends CNNArchSymbolCoCo {
@Override
public void check(ArchitectureElementSymbol sym) {
if (sym instanceof IOSymbol){
checkIOElement((IOSymbol) sym);
if (sym instanceof VariableSymbol) {
checkVariable((VariableSymbol) sym);
}
}
public void checkIOElement(IOSymbol ioElement) {
Collection<IODeclarationSymbol> ioDeclarations = ioElement.getEnclosingScope().resolveMany(ioElement.getName(), IODeclarationSymbol.KIND);
public void checkVariable(VariableSymbol variable) {
if (variable.getType() == VariableSymbol.Type.LAYER) {
LayerDeclarationSymbol layerDeclaration = variable.getLayerVariableDeclaration().getLayer().getDeclaration();
if (ioDeclarations.isEmpty()){
Log.error("0" + ErrorCodes.UNKNOWN_IO + " Unknown input or output name. " +
"The input or output '" + ioElement.getName() + "' does not exist"
, ioElement.getSourcePosition());
}
else {
IODeclarationSymbol ioDeclaration = ioDeclarations.iterator().next();
if (ioDeclarations.size() > 1) {
if (!checkedIODeclarations.contains(ioDeclaration)) {
Log.error("0" + ErrorCodes.DUPLICATED_NAME + " Duplicated IO name. " +
"The name '" + ioDeclaration.getName() + "' is already used."
, ioDeclaration.getSourcePosition());
checkedIODeclarations.addAll(ioDeclarations);
}
if (layerDeclaration.isPredefined() && !((PredefinedLayerDeclaration) layerDeclaration).isValidMember(variable.getMember())) {
Log.error("0" + ErrorCodes.INVALID_MEMBER + " Layer has no member " + variable.getMember().toString().toLowerCase() + ". ",
variable.getSourcePosition());
}
else {
if (ioDeclaration.getName().endsWith("_")){
Log.error("0" + ErrorCodes.ILLEGAL_NAME + " Illegal IO name. " +
"Input and output names cannot end with \"_\"",
ioDeclaration.getSourcePosition());
}
if (variable.getArrayAccess().isPresent()) {
Log.error("0" + ErrorCodes.INVALID_MEMBER + " Currently layer variable array access is not implemented. ",
variable.getSourcePosition());
}
}
}
if (variable.getType() == VariableSymbol.Type.IO && variable.getMember() != VariableSymbol.Member.NONE) {
Log.error("0" + ErrorCodes.INVALID_MEMBER + " IO variables have no member. ", variable.getSourcePosition());
}
}
}
......@@ -20,69 +20,30 @@
*/
package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._ast.ASTLayerParameter;
import de.monticore.lang.monticar.cnnarch._ast.ASTVariable;
import de.monticore.lang.monticar.cnnarch._symboltable.*;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.lang.monticar.cnnarch.predefined.AllPredefinedVariables;
import de.monticore.symboltable.Symbol;
import de.se_rwth.commons.logging.Log;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class CheckVariableName implements CNNArchASTVariableCoCo {
Set<String> variableNames = new HashSet<>();
public class CheckVariableName extends CNNArchSymbolCoCo {
@Override
public void check(ASTVariable node) {
checkForIllegalNames(node);
checkForDuplicates(node);
}