aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/frontend/src
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-11-19 21:39:00 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-11-22 16:40:03 +0100
commit3aa4a2b58221a3e83b17d0c04c9a6e9c41e5500c (patch)
tree1e25f513e3b34b2ea29dbcc6cc3795e5927a1362 /subprojects/frontend/src
parentfeat(language): numeric expressions (diff)
downloadrefinery-3aa4a2b58221a3e83b17d0c04c9a6e9c41e5500c.tar.gz
refinery-3aa4a2b58221a3e83b17d0c04c9a6e9c41e5500c.tar.zst
refinery-3aa4a2b58221a3e83b17d0c04c9a6e9c41e5500c.zip
refactor: separate primitive types from nodes
Diffstat (limited to 'subprojects/frontend/src')
-rw-r--r--subprojects/frontend/src/index.tsx21
-rw-r--r--subprojects/frontend/src/language/problem.grammar59
-rw-r--r--subprojects/frontend/src/language/problemLanguageSupport.ts5
-rw-r--r--subprojects/frontend/src/xtext/ContentAssistService.ts2
4 files changed, 48 insertions, 39 deletions
diff --git a/subprojects/frontend/src/index.tsx b/subprojects/frontend/src/index.tsx
index b42b8062..0165d7c1 100644
--- a/subprojects/frontend/src/index.tsx
+++ b/subprojects/frontend/src/index.tsx
@@ -10,27 +10,24 @@ const initialValue = `class Family {
10} 10}
11 11
12class Person { 12class Person {
13 Person[] children opposite parent 13 refers Person[] children opposite parent
14 Person[0..1] parent opposite children 14 refers Person[0..1] parent opposite children
15 int age 15 int age
16 TaxStatus taxStatus 16 refers TaxStatus taxStatus
17} 17}
18 18
19enum TaxStatus { 19enum TaxStatus {
20 child, student, adult, retired 20 child, student, adult, retired
21} 21}
22 22
23int ageDifference(Person p, Person q) =
24 children(p, q), age(p, pAge), age(q, qAge) -> qAge - pAge.
25
26error invalidAgeDifference(Person p, Person q) <->
27 children(p, q), ageDifference(p, q) <= 0.
28
29% A child cannot have any dependents. 23% A child cannot have any dependents.
30pred invalidTaxStatus(Person p) <-> 24pred invalidTaxStatus(Person p) <->
31 taxStatus(p, child), 25 taxStatus(p, child),
32 children(p, _q) 26 children(p, _q)
33; 27;
28 parent(p, q),
29 age(q) < age(p)
30;
34 taxStatus(p, retired), 31 taxStatus(p, retired),
35 parent(p, q), 32 parent(p, q),
36 !taxStatus(q, retired). 33 !taxStatus(q, retired).
@@ -44,10 +41,8 @@ children(anne, ciri).
44?children(bob, ciri). 41?children(bob, ciri).
45default children(ciri, *): false. 42default children(ciri, *): false.
46taxStatus(anne, adult). 43taxStatus(anne, adult).
47age(anne, 35). 44age(bob) in 21..35.
48bobAge: 27. 45age(ciri) = 10.
49age(bob, bobAge).
50!age(ciri, bobAge).
51 46
52scope Family = 1, Person += 5..10. 47scope Family = 1, Person += 5..10.
53`; 48`;
diff --git a/subprojects/frontend/src/language/problem.grammar b/subprojects/frontend/src/language/problem.grammar
index 4235c433..7c4098d5 100644
--- a/subprojects/frontend/src/language/problem.grammar
+++ b/subprojects/frontend/src/language/problem.grammar
@@ -3,11 +3,12 @@
3@external prop implicitCompletion from './props' 3@external prop implicitCompletion from './props'
4 4
5@precedence { 5@precedence {
6 containment @cut,
7 prefix, 6 prefix,
8 exponential @right, 7 exponential @right,
9 multiplicative @left, 8 multiplicative @left,
10 additive @left, 9 additive @left,
10 range @left,
11 lattice @left,
11 comparison @left 12 comparison @left
12} 13}
13 14
@@ -20,7 +21,7 @@ statement {
20 ClassDefinition { 21 ClassDefinition {
21 kw<"abstract">? kw<"class"> RelationName 22 kw<"abstract">? kw<"class"> RelationName
22 (kw<"extends"> sep<",", RelationName>)? 23 (kw<"extends"> sep<",", RelationName>)?
23 (ClassBody { "{" ReferenceDeclaration* "}" } | ".") 24 (ClassBody { "{" FeatureDeclaration* "}" } | ".")
24 } | 25 } |
25 EnumDefinition { 26 EnumDefinition {
26 kw<"enum"> RelationName 27 kw<"enum"> RelationName
@@ -35,7 +36,7 @@ statement {
35 PredicateBody { ("<->" sep<OrOp, Conjunction>)? "." } 36 PredicateBody { ("<->" sep<OrOp, Conjunction>)? "." }
36 } | 37 } |
37 FunctionDefinition { 38 FunctionDefinition {
38 RelationName RelationName ParameterList<Parameter>? 39 PrimitiveType RelationName ParameterList<Parameter>?
39 FunctionBody { ("=" sep<OrOp, Case>)? "." } 40 FunctionBody { ("=" sep<OrOp, Case>)? "." }
40 } | 41 } |
41 //RuleDefinition { 42 //RuleDefinition {
@@ -45,10 +46,8 @@ statement {
45 //} | 46 //} |
46 Assertion { 47 Assertion {
47 kw<"default">? (NotOp | UnknownOp)? RelationName 48 kw<"default">? (NotOp | UnknownOp)? RelationName
48 ParameterList<AssertionArgument> (":" LogicValue)? "." 49 ParameterList<AssertionArgument>
49 } | 50 (":" LogicValue | ("=" | kw<"in">) Expr)? "."
50 NodeValueAssertion {
51 QualifiedName ":" Constant "."
52 } | 51 } |
53 IndividualDeclaration { 52 IndividualDeclaration {
54 kw<"individual"> sep<",", IndividualNodeName> "." 53 kw<"individual"> sep<",", IndividualNodeName> "."
@@ -58,15 +57,8 @@ statement {
58 } 57 }
59} 58}
60 59
61ReferenceDeclaration { 60FeatureDeclaration {
62 ( 61 (ReferenceKind | PrimitiveType | kw<"bool">) RelationName
63 ExplicitContainmentReference {
64 !containment (kw<"refers"> | ckw<"contains"> | kw<"container">) RelationName
65 } |
66 ImplicitContainmentReference {
67 RelationName
68 }
69 )
70 ("[" Multiplicity? "]")? 62 ("[" Multiplicity? "]")?
71 RelationName 63 RelationName
72 (kw<"opposite"> RelationName)? 64 (kw<"opposite"> RelationName)?
@@ -75,7 +67,10 @@ ReferenceDeclaration {
75 67
76Parameter { Modality? RelationName? VariableName } 68Parameter { Modality? RelationName? VariableName }
77 69
78Conjunction { ("," | Expr)+ } 70// Use @dynamicPrecedence to prevent a(b) from being parsed as Expr { a } Expr { b }
71// instead of Atom { a(b) }
72// Being looser with token sequencing enables more consistent syntactic highlighting.
73Conjunction { ("," | NextConjunction[@dynamicPrecedence=-10] { Expr })+ }
79 74
80Case { Conjunction ("->" Expr)? } 75Case { Conjunction ("->" Expr)? }
81 76
@@ -85,8 +80,10 @@ Expr {
85 UnaryExpr | BinaryExpr | Aggregation | VariableName | Atom | Constant | "(" Expr ")" 80 UnaryExpr | BinaryExpr | Aggregation | VariableName | Atom | Constant | "(" Expr ")"
86} 81}
87 82
88BinaryExpr[@dynamicPrecedence=1] { 83BinaryExpr {
89 Expr !comparison ComparisonOp Expr | 84 Expr !comparison ComparisonOp Expr |
85 Expr !lattice (LatticeMeet | "\\/") Expr |
86 Expr !range ".." Expr |
90 Expr !additive ("+" | "-") Expr | 87 Expr !additive ("+" | "-") Expr |
91 Expr !multiplicative (StarMult | Divide) Expr | 88 Expr !multiplicative (StarMult | Divide) Expr |
92 Expr !exponential "**" Expr 89 Expr !exponential "**" Expr
@@ -110,12 +107,20 @@ Atom { RelationName "+"? ParameterList<Expr> }
110// Literal 107// Literal
111//} 108//}
112 109
113AssertionArgument { NodeName | StarArgument | Constant } 110AssertionArgument { NodeName | StarArgument }
111
112Constant { Real | String | StarMult }
114 113
115Constant { Real | String } 114ReferenceKind {
115 kw<"refers"> | ckw<"contains"> | kw<"container">
116}
117
118PrimitiveType {
119 kw<"int"> | kw<"real"> | kw<"string">
120}
116 121
117LogicValue { 122LogicValue {
118 ckw<"true"> | ckw<"false"> | kw<"unknown"> | kw<"error"> 123 kw<"true"> | kw<"false"> | kw<"unknown"> | kw<"error">
119} 124}
120 125
121Modality { 126Modality {
@@ -126,10 +131,16 @@ AggregationOp {
126 ckw<"sum"> | ckw<"prod"> | ckw<"min"> | ckw<"max"> 131 ckw<"sum"> | ckw<"prod"> | ckw<"min"> | ckw<"max">
127} 132}
128 133
134ComparisonOp { SymbolicComparisonOp | kw<"in"> }
135
129ScopeElement { RelationName ("=" | "+=") Multiplicity } 136ScopeElement { RelationName ("=" | "+=") Multiplicity }
130 137
131Multiplicity { (IntMult "..")? (IntMult | StarMult)} 138Multiplicity { (IntMult "..")? (IntMult | StarMult)}
132 139
140// The ~name handles the ambiguity between transitve closure a+(b, c) and addition a+(b)
141// in the grammar. We prefer the addition interpretation by applying @dynamicPrecedence=1
142// to the VariableName rule,
143// but will go with the transtive closure (and highlight `a` as a relation) if forced.
133RelationName { QualifiedName ~name } 144RelationName { QualifiedName ~name }
134 145
135//RuleName { QualifiedName } 146//RuleName { QualifiedName }
@@ -167,7 +178,9 @@ sep1<separator, content> { content (separator content)* }
167 178
168 Divide { "/" } 179 Divide { "/" }
169 180
170 @precedence { BlockComment, LineComment, Divide } 181 LatticeMeet { "/\\" }
182
183 @precedence { BlockComment, LineComment, LatticeMeet, Divide }
171 184
172 identifier { $[A-Za-z_] $[a-zA-Z0-9_]* } 185 identifier { $[A-Za-z_] $[a-zA-Z0-9_]* }
173 186
@@ -186,7 +199,7 @@ sep1<separator, content> { content (separator content)* }
186 "\"" (![\\"\n] | "\\" (![\n] | "\n"))* "\"" 199 "\"" (![\\"\n] | "\\" (![\n] | "\n"))* "\""
187 } 200 }
188 201
189 ComparisonOp { ">" | ">=" | "<" | "<=" | "==" | "!=" } 202 SymbolicComparisonOp { ">" | ">=" | "<" | "<=" | "==" | "!=" }
190 203
191 NotOp { "!" } 204 NotOp { "!" }
192 205
diff --git a/subprojects/frontend/src/language/problemLanguageSupport.ts b/subprojects/frontend/src/language/problemLanguageSupport.ts
index cde8b157..2a973c93 100644
--- a/subprojects/frontend/src/language/problemLanguageSupport.ts
+++ b/subprojects/frontend/src/language/problemLanguageSupport.ts
@@ -24,9 +24,10 @@ const parserWithMetadata = parser.configure({
24 'problem class enum pred individual scope': t.definitionKeyword, 24 'problem class enum pred individual scope': t.definitionKeyword,
25 'abstract extends refers contains container opposite': t.modifier, 25 'abstract extends refers contains container opposite': t.modifier,
26 'default error contained containment': t.modifier, 26 'default error contained containment': t.modifier,
27 'true false unknown error': t.operatorKeyword, 27 'true false unknown error': t.keyword,
28 'int real string bool': t.keyword,
28 'may must current': t.operatorKeyword, 29 'may must current': t.operatorKeyword,
29 'sum prod min max': t.operatorKeyword, 30 'sum prod min max in': t.operatorKeyword,
30 // 'new delete': t.keyword, 31 // 'new delete': t.keyword,
31 NotOp: t.operator, 32 NotOp: t.operator,
32 UnknownOp: t.operator, 33 UnknownOp: t.operator,
diff --git a/subprojects/frontend/src/xtext/ContentAssistService.ts b/subprojects/frontend/src/xtext/ContentAssistService.ts
index 101990af..fa894e4d 100644
--- a/subprojects/frontend/src/xtext/ContentAssistService.ts
+++ b/subprojects/frontend/src/xtext/ContentAssistService.ts
@@ -17,7 +17,7 @@ const PROPOSALS_LIMIT = 1000;
17 17
18const IDENTIFIER_REGEXP_STR = '[a-zA-Z0-9_]*'; 18const IDENTIFIER_REGEXP_STR = '[a-zA-Z0-9_]*';
19 19
20const HIGH_PRIORITY_KEYWORDS = ['<->', '==>']; 20const HIGH_PRIORITY_KEYWORDS = ['<->', '->', '==>'];
21 21
22const log = getLogger('xtext.ContentAssistService'); 22const log = getLogger('xtext.ContentAssistService');
23 23