From 19d38b03de9af68e6234a2a07ac54c36d73edaa7 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Sun, 20 Nov 2022 20:52:17 +0100 Subject: refactor(language): simplify syntax --- .../java/tools/refinery/language/Problem.xtext | 48 +++++++++++----------- .../language/formatting2/ProblemFormatter.java | 43 ++++++++----------- ...ferShortAssertionsProblemSemanticSequencer.java | 8 ++-- .../refinery/language/utils/SymbolCollector.java | 2 +- 4 files changed, 46 insertions(+), 55 deletions(-) (limited to 'subprojects/language/src/main/java') diff --git a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext index 8b13a693..95a64737 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext +++ b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext @@ -33,7 +33,8 @@ enum ReferenceKind: REFERENCE="refers" | CONTAINMENT="contains" | CONTAINER="container"; ReferenceDeclaration: - kind=ReferenceKind referenceType=[Relation|QualifiedName] + (referenceType=[Relation|NonContainmentQualifiedName] | + kind=ReferenceKind referenceType=[Relation|QualifiedName]) ("[" multiplicity=Multiplicity "]")? name=Identifier ("opposite" opposite=[ReferenceDeclaration|QualifiedName])?; @@ -64,7 +65,7 @@ Conjunction: literals+=Expr ("," literals+=Expr)*; FunctionDefinition: - functionType=PrimitiveType name=Identifier + "fn" functionType=PrimitiveType name=Identifier "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")" ("=" cases+=Case (";" cases+=Case)*)? "."; @@ -106,7 +107,8 @@ Expr: ComparisonExpr; enum ComparisonOp: - LESS="<" | LESS_EQ="<=" | GREATER=">" | GREATER_EQ=">=" | EQ="==" | NOT_EQ="!=" | IN="in"; + LESS="<" | LESS_EQ="<=" | GREATER=">" | GREATER_EQ=">=" | EQ="==" | NOT_EQ="!=" | + IN="in" | SUBSUMES=":>" | SUBSUMED_BY="<:" | ABS_EQ="===" | ABS_NOT_EQ="!=="; ComparisonExpr returns Expr: LatticeExpr ({ComparisonExpr.left=current} @@ -163,7 +165,7 @@ NegationExpr: "!" body=UnaryExpr; CountExpr: - "#" body=UnaryExpr; + "count" body=UnaryExpr; enum AggregationOp: SUM="sum" | PROD="prod" | MIN="min" | MAX="max"; @@ -180,7 +182,7 @@ VariableOrNodeExpr: variableOrNode=[VariableOrNode|QualifiedName]; Constant: - RealConstant | IntConstant | InfConstant | StringConstant; + RealConstant | IntConstant | InfConstant | StringConstant | LogicConstant; IntConstant: intValue=INT; @@ -194,12 +196,18 @@ InfConstant: StringConstant: stringValue=STRING; +enum LogicValue: + TRUE="true" | FALSE="false" | UNKNOWN="unknown" | ERROR="error"; + +LogicConstant: + logicValue=LogicValue; + Assertion: default?="default"? (relation=[Relation|QualifiedName] "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")" - value=AssertionValue | - value=ShortLogicAssertionValue + ":" value=Expr | + value=ShortLogicConstant relation=[Relation|QualifiedName] "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")") "."; @@ -213,23 +221,11 @@ NodeAssertionArgument: WildcardAssertionArgument: {WildcardAssertionArgument} "*"; -AssertionValue: - LogicAssertionValue | ExprAssertionValue; - -enum LogicValue: - TRUE="true" | FALSE="false" | UNKNOWN="unknown" | ERROR="error"; - -LogicAssertionValue: - ":" logicValue=LogicValue; - -ExprAssertionValue: - (range?="in" | "=") body=Expr; - enum ShortLogicValue returns LogicValue: FALSE="!" | UNKNOWN="?"; -ShortLogicAssertionValue returns LogicAssertionValue: - {LogicAssertionValue} logicValue=ShortLogicValue?; +ShortLogicConstant returns LogicConstant: + {LogicConstant} logicValue=ShortLogicValue?; ScopeDeclaration: "scope" typeScopes+=TypeScope ("," typeScopes+=TypeScope)* "."; @@ -255,7 +251,7 @@ ExactMultiplicity: exactValue=INT; IndividualDeclaration: - "individual" nodes+=EnumLiteral ("," nodes+=EnumLiteral)* "."; + "indiv" nodes+=EnumLiteral ("," nodes+=EnumLiteral)* "."; UpperBound returns ecore::EInt: INT | "*"; @@ -263,8 +259,14 @@ UpperBound returns ecore::EInt: QualifiedName hidden(): Identifier ("::" Identifier)*; +NonContainmentQualifiedName hidden(): + NonContainmentIdentifier ("::" Identifier)*; + Identifier: - ID | "contains" | "contained" | "sum" | "prod" | "min" | "max"; + NonContainmentIdentifier | "contains"; + +NonContainmentIdentifier: + ID | "contained" | "sum" | "prod" | "min" | "max"; Real returns ecore::EDouble: EXPONENTIAL | INT "." (INT | EXPONENTIAL); diff --git a/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java b/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java index 46870edb..797535ea 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java +++ b/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java @@ -3,7 +3,6 @@ */ package tools.refinery.language.formatting2; -import com.google.inject.Inject; import org.eclipse.emf.ecore.EObject; import org.eclipse.xtext.formatting2.AbstractJavaFormatter; import org.eclipse.xtext.formatting2.IFormattableDocument; @@ -11,15 +10,10 @@ import org.eclipse.xtext.formatting2.IHiddenRegionFormatter; import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegionsFinder; import org.eclipse.xtext.formatting2.regionaccess.ISequentialRegion; import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; - import tools.refinery.language.model.problem.*; -import tools.refinery.language.services.ProblemGrammarAccess; @SuppressWarnings("UnstableApiUsage") public class ProblemFormatter extends AbstractJavaFormatter { - @Inject - private ProblemGrammarAccess problemGrammarAccess; - protected void format(Problem problem, IFormattableDocument doc) { doc.prepend(problem, this::noSpace); var region = regionFor(problem); @@ -37,31 +31,26 @@ public class ProblemFormatter extends AbstractJavaFormatter { doc.append(region.feature(ProblemPackage.Literals.ASSERTION__DEFAULT), this::oneSpace); doc.append(region.feature(ProblemPackage.Literals.ASSERTION__RELATION), this::noSpace); formatParenthesizedList(region, doc); + for (var argument : assertion.getArguments()) { + doc.format(argument); + } + var colon = region.keyword(":"); + boolean abbreviated = colon == null; + if (!abbreviated) { + doc.prepend(colon, this::noSpace); + doc.append(colon, this::oneSpace); + } var value = assertion.getValue(); if (value != null) { - doc.append(value, this::noSpace); + var valueRegion = regionForEObject(value); + // Avoid clash between noSpace after ASSERTION_DEFAULT and noSpace after the 0-length region + // for a true LogicAssertionValue if the abbreviated form of assertion (no : operator) is used. + if (abbreviated && valueRegion != null && valueRegion.getLength() > 0) { + doc.append(value, this::noSpace); + } doc.format(value); } doc.prepend(region.keyword("."), this::noSpace); - for (var argument : assertion.getArguments()) { - doc.format(argument); - } - } - - protected void format(LogicAssertionValue assertionValue, IFormattableDocument doc) { - var region = regionFor(assertionValue); - doc.prepend(region.keyword(":"), this::noSpace); - doc.append(region.keyword(":"), this::oneSpace); - } - - protected void format(ExprAssertionValue assertionValue, IFormattableDocument doc) { - var region = regionFor(assertionValue); - doc.surround(region.keyword("="), this::oneSpace); - doc.surround(region.keyword("in"), this::oneSpace); - var body = assertionValue.getBody(); - if (body != null) { - doc.format(body); - } } protected void format(ClassDeclaration classDeclaration, IFormattableDocument doc) { @@ -128,7 +117,7 @@ public class ProblemFormatter extends AbstractJavaFormatter { protected void format(IndividualDeclaration individualDeclaration, IFormattableDocument doc) { surroundNewLines(doc, individualDeclaration, this::singleNewLine); var region = regionFor(individualDeclaration); - doc.append(region.keyword("individual"), this::oneSpace); + doc.append(region.keyword("indiv"), this::oneSpace); formatList(region, ",", doc); doc.prepend(region.keyword("."), this::noSpace); } diff --git a/subprojects/language/src/main/java/tools/refinery/language/serializer/PreferShortAssertionsProblemSemanticSequencer.java b/subprojects/language/src/main/java/tools/refinery/language/serializer/PreferShortAssertionsProblemSemanticSequencer.java index c51a5e28..27ce1521 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/serializer/PreferShortAssertionsProblemSemanticSequencer.java +++ b/subprojects/language/src/main/java/tools/refinery/language/serializer/PreferShortAssertionsProblemSemanticSequencer.java @@ -5,7 +5,7 @@ import org.eclipse.xtext.serializer.ISerializationContext; import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ListTransient; import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient; import tools.refinery.language.model.problem.Assertion; -import tools.refinery.language.model.problem.LogicAssertionValue; +import tools.refinery.language.model.problem.LogicConstant; import tools.refinery.language.model.problem.LogicValue; import tools.refinery.language.model.problem.ProblemPackage; import tools.refinery.language.services.ProblemGrammarAccess; @@ -17,8 +17,8 @@ public class PreferShortAssertionsProblemSemanticSequencer extends ProblemSemant @Override protected void sequence_Assertion(ISerializationContext context, Assertion semanticObject) { if (semanticObject.isDefault() || - !(semanticObject.getValue() instanceof LogicAssertionValue logicAssertionValue) || - logicAssertionValue.getLogicValue() == LogicValue.ERROR) { + !(semanticObject.getValue() instanceof LogicConstant logicConstant) || + logicConstant.getLogicValue() == LogicValue.ERROR) { super.sequence_Assertion(context, semanticObject); return; } @@ -34,7 +34,7 @@ public class PreferShortAssertionsProblemSemanticSequencer extends ProblemSemant } var feeder = createSequencerFeeder(context, semanticObject); var access = grammarAccess.getAssertionAccess(); - feeder.accept(access.getValueShortLogicAssertionValueParserRuleCall_1_1_0_0(), logicAssertionValue); + feeder.accept(access.getValueShortLogicConstantParserRuleCall_1_1_0_0(), logicConstant); feeder.accept(access.getRelationRelationQualifiedNameParserRuleCall_1_1_1_0_1(), semanticObject.getRelation()); var iterator = semanticObject.getArguments().iterator(); if (iterator.hasNext()) { diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java b/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java index 5412f620..65167ed6 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java +++ b/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java @@ -242,7 +242,7 @@ class SymbolCollector { } assertion.getArguments().add(argument); } - var value = ProblemFactory.eINSTANCE.createLogicAssertionValue(); + var value = ProblemFactory.eINSTANCE.createLogicConstant(); value.setLogicValue(logicValue); assertion.setValue(value); collectAssertion(assertion); -- cgit v1.2.3-54-g00ecf