-
Notifications
You must be signed in to change notification settings - Fork 29
Expand file tree
/
Copy pathOptionalOperators.mc4
More file actions
102 lines (83 loc) · 3.45 KB
/
Copy pathOptionalOperators.mc4
File metadata and controls
102 lines (83 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// (c) https://github.com/MontiCore/monticore
package de.monticore.ocl;
/* This is a MontiCore stable grammar.
* Adaptations -- if any -- are conservative. */
import de.monticore.expressions.*;
/**
* This grammar defines expressions that deal with
* optional values (i.e. potentially absent values).
* These operators are generally known as Elvis operators
* and include ?:, ?==, ?>=, etc.
*
* Optional expressions can savely (i.e. as conservative extension)
* be composed if with other forms of expressions
* given in the MontiCore core project.
*
* This grammar is part of a hierarchy of expressions, which can be found
* under
* https://github.com/MontiCore/monticore/blob/dev/monticore-grammar/
* src/main/grammars/de/monticore/expressions/Expressions.md
*
*/
component grammar OptionalOperators
extends CommonExpressions //InfixExpression
{
/**
* `val ?: 0W` equals to `val.isPresent ? val.get : 0W`
* this operator is right associative, so that multiple optionals can be
* chained:
* x ?: y ?: 0 is the same as x ?: (y ?: 0)
* and this means that if x is present it returns x.get other it tries if y is
* present if not it returns 0
*
* ?: has a prority between `==` and `<`
*/
OptionalExpressionPrefix implements Expression <140>, InfixExpression =
<rightassoc>
left:Expression
operator:"?:"
right:Expression;
/*=================================================================*/
/*
* `x ?== y` is the same as `x.isPresent && x.get == y`
* this is useful for underspecification relations, if it is underspecified
* (x.isAbsent) the term evaluates always to false.
*
* `x ?>= y` equals `x.isPresent && x.get >= y`
* all other operators are defined systematically the same way
*/
OptionalLessEqualExpression implements Expression <150>, InfixExpression =
left:Expression operator:"?<=" right:Expression;
OptionalGreaterEqualExpression implements Expression <150>, InfixExpression =
left:Expression operator:"?>=" right:Expression;
OptionalLessThanExpression implements Expression <150>, InfixExpression =
left:Expression operator:"?<" right:Expression;
OptionalGreaterThanExpression implements Expression <150>, InfixExpression =
left:Expression operator:"?>" right:Expression;
OptionalEqualsExpression implements Expression <130>, InfixExpression =
left:Expression operator:"?==" right:Expression;
OptionalNotEqualsExpression implements Expression <130>, InfixExpression =
left:Expression operator:"?!=" right:Expression;
/*=================================================================*/
/*
* x ?~~ y is the same as x ?== y,
* except that the types of x and y must not (statically checkable)
* be compatible. However, x ?~~ y only holds, if x and
* y are of the same actual type or both absent.
*
* This allows to compare values as if in an untyped language.
* This should be rarely needed.
*/
OptionalSimilarExpression implements Expression <130>, InfixExpression =
left:Expression operator:"?~~" right:Expression;
/*
* x ?!~ y is the same as x != y,
* except that the types of x and y must not
* be compatible (statically checkable)
*/
OptionalNotSimilarExpression implements Expression <130>, InfixExpression =
left:Expression operator:"?!~" right:Expression;
// Due to possible scanner clashes with "List<?>"
// we split the token:
splittoken "?>";
}