diff options
author | Kristóf Marussy <kristof@marussy.com> | 2021-10-11 01:42:22 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2021-10-31 19:26:10 +0100 |
commit | e1d6802843960e911f19c7e9c4a4b626ae854b90 (patch) | |
tree | e62d4d3fa0bc4f3ce1582eb2edb35b2d0d030994 | |
parent | fix(web): a11y issue reported by Lighthouse (diff) | |
download | refinery-e1d6802843960e911f19c7e9c4a4b626ae854b90.tar.gz refinery-e1d6802843960e911f19c7e9c4a4b626ae854b90.tar.zst refinery-e1d6802843960e911f19c7e9c4a4b626ae854b90.zip |
feat(web): simplify contextual parsing
* More relaxted parsing in the browser for stable variable/node
identifier classification.
* String support in the browser.
* contains, refers, and opposite keywords are no longer contextual,
which simplifies parsing in the browser.
6 files changed, 48 insertions, 21 deletions
diff --git a/language-web/src/main/js/editor/EditorParent.ts b/language-web/src/main/js/editor/EditorParent.ts index 316c5072..a2f6c266 100644 --- a/language-web/src/main/js/editor/EditorParent.ts +++ b/language-web/src/main/js/editor/EditorParent.ts | |||
@@ -65,6 +65,9 @@ export const EditorParent = styled('div')(({ theme }) => ({ | |||
65 | '.cmt-number': { | 65 | '.cmt-number': { |
66 | color: '#6188a6', | 66 | color: '#6188a6', |
67 | }, | 67 | }, |
68 | '.cmt-string': { | ||
69 | color: theme.palette.secondary.dark, | ||
70 | }, | ||
68 | '.cmt-keyword': { | 71 | '.cmt-keyword': { |
69 | color: theme.palette.primary.main, | 72 | color: theme.palette.primary.main, |
70 | }, | 73 | }, |
diff --git a/language-web/src/main/js/editor/problem.grammar b/language-web/src/main/js/editor/problem.grammar index 921cec53..cf940698 100644 --- a/language-web/src/main/js/editor/problem.grammar +++ b/language-web/src/main/js/editor/problem.grammar | |||
@@ -1,4 +1,3 @@ | |||
1 | |||
2 | @top Problem { statement* } | 1 | @top Problem { statement* } |
3 | 2 | ||
4 | statement { | 3 | statement { |
@@ -7,6 +6,7 @@ statement { | |||
7 | } | | 6 | } | |
8 | ClassDefinition { | 7 | ClassDefinition { |
9 | ckw<"abstract">? ckw<"class"> RelationName | 8 | ckw<"abstract">? ckw<"class"> RelationName |
9 | (ckw<"extends"> sep<",", RelationName>)? | ||
10 | (ClassBody { "{" ReferenceDeclaration* "}" } | ".") | 10 | (ClassBody { "{" ReferenceDeclaration* "}" } | ".") |
11 | } | | 11 | } | |
12 | EnumDefinition { | 12 | EnumDefinition { |
@@ -21,6 +21,9 @@ statement { | |||
21 | ckw<"default">? (NotOp | UnknownOp)? RelationName | 21 | ckw<"default">? (NotOp | UnknownOp)? RelationName |
22 | ParameterList<AssertionArgument> (":" LogicValue)? "." | 22 | ParameterList<AssertionArgument> (":" LogicValue)? "." |
23 | } | | 23 | } | |
24 | NodeValueAssertion { | ||
25 | UniqueNodeName ":" Constant "." | ||
26 | } | | ||
24 | UniqueDeclaration { | 27 | UniqueDeclaration { |
25 | ckw<"unique"> sep<",", UniqueNodeName> "." | 28 | ckw<"unique"> sep<",", UniqueNodeName> "." |
26 | } | | 29 | } | |
@@ -30,18 +33,17 @@ statement { | |||
30 | } | 33 | } |
31 | 34 | ||
32 | ReferenceDeclaration { | 35 | ReferenceDeclaration { |
33 | ((kw<"refers"> | kw<"contains">) !times RelationName | !plus RelationName) | 36 | (kw<"refers"> | kw<"contains">)? |
37 | RelationName | ||
34 | RelationName | 38 | RelationName |
35 | ( "[" Multiplicity? "]" )? | 39 | ( "[" Multiplicity? "]" )? |
36 | (kw<"opposite"> RelationName)? | 40 | (kw<"opposite"> RelationName)? |
37 | ";"? | 41 | ";"? |
38 | } | 42 | } |
39 | 43 | ||
40 | @precedence { times @left, plus } | ||
41 | |||
42 | Parameter { RelationName? VariableName } | 44 | Parameter { RelationName? VariableName } |
43 | 45 | ||
44 | Conjunction { sep1<",", Literal> } | 46 | Conjunction { ("," | Literal)+ } |
45 | 47 | ||
46 | OrOp { ";" } | 48 | OrOp { ";" } |
47 | 49 | ||
@@ -49,9 +51,11 @@ Literal { NotOp? Atom } | |||
49 | 51 | ||
50 | Atom { RelationName ParameterList<Argument>? } | 52 | Atom { RelationName ParameterList<Argument>? } |
51 | 53 | ||
52 | Argument { VariableName | Real } | 54 | Argument { VariableName | Constant } |
53 | 55 | ||
54 | AssertionArgument { NodeName | StarArgument | Real } | 56 | AssertionArgument { NodeName | StarArgument | Constant } |
57 | |||
58 | Constant { Real | String } | ||
55 | 59 | ||
56 | LogicValue { | 60 | LogicValue { |
57 | ckw<"true"> | ckw<"false"> | ckw<"unknown"> | ckw<"error"> | 61 | ckw<"true"> | ckw<"false"> | ckw<"unknown"> | ckw<"error"> |
@@ -108,6 +112,11 @@ sep1<separator, content> { content (separator content?)* } | |||
108 | 112 | ||
109 | exponential { int ("e" | "E") ("+" | "-")? int } | 113 | exponential { int ("e" | "E") ("+" | "-")? int } |
110 | 114 | ||
115 | String { | ||
116 | "'" (![\\'\n] | "\\" ![\n] | "\\\n")+ "'" | | ||
117 | "\"" (![\\"\n] | "\\" (![\n] | "\n"))* "\"" | ||
118 | } | ||
119 | |||
111 | NotOp { "!" } | 120 | NotOp { "!" } |
112 | 121 | ||
113 | UnknownOp { "?" } | 122 | UnknownOp { "?" } |
diff --git a/language-web/src/main/js/editor/problemLanguageSupport.ts b/language-web/src/main/js/editor/problemLanguageSupport.ts index 2bf7c7a4..c9e61b31 100644 --- a/language-web/src/main/js/editor/problemLanguageSupport.ts +++ b/language-web/src/main/js/editor/problemLanguageSupport.ts | |||
@@ -26,7 +26,7 @@ const parserWithMetadata = (parser as LRParser).configure({ | |||
26 | LineComment: t.lineComment, | 26 | LineComment: t.lineComment, |
27 | BlockComment: t.blockComment, | 27 | BlockComment: t.blockComment, |
28 | 'problem class enum pred unique scope': t.definitionKeyword, | 28 | 'problem class enum pred unique scope': t.definitionKeyword, |
29 | 'abstract refers contains opposite error default': t.modifier, | 29 | 'abstract extends refers contains opposite error default': t.modifier, |
30 | 'true false unknown error': t.keyword, | 30 | 'true false unknown error': t.keyword, |
31 | NotOp: t.keyword, | 31 | NotOp: t.keyword, |
32 | UnknownOp: t.keyword, | 32 | UnknownOp: t.keyword, |
@@ -34,6 +34,7 @@ const parserWithMetadata = (parser as LRParser).configure({ | |||
34 | StarArgument: t.keyword, | 34 | StarArgument: t.keyword, |
35 | 'IntMult StarMult Real': t.number, | 35 | 'IntMult StarMult Real': t.number, |
36 | StarMult: t.number, | 36 | StarMult: t.number, |
37 | String: t.string, | ||
37 | 'RelationName/QualifiedName': t.typeName, | 38 | 'RelationName/QualifiedName': t.typeName, |
38 | 'UniqueNodeName/QualifiedName': t.atom, | 39 | 'UniqueNodeName/QualifiedName': t.atom, |
39 | 'VariableName/QualifiedName': t.variableName, | 40 | 'VariableName/QualifiedName': t.variableName, |
diff --git a/language-web/src/main/js/index.tsx b/language-web/src/main/js/index.tsx index 1b24eadb..9316db4d 100644 --- a/language-web/src/main/js/index.tsx +++ b/language-web/src/main/js/index.tsx | |||
@@ -26,7 +26,7 @@ enum TaxStatus { | |||
26 | % A child cannot have any dependents. | 26 | % A child cannot have any dependents. |
27 | error invalidTaxStatus(Person p) <-> | 27 | error invalidTaxStatus(Person p) <-> |
28 | taxStatus(p, child), | 28 | taxStatus(p, child), |
29 | children(p, _q) | 29 | children(p, _q), |
30 | ; taxStatus(p, retired), | 30 | ; taxStatus(p, retired), |
31 | parent(p, q), | 31 | parent(p, q), |
32 | !taxStatus(q, retired). | 32 | !taxStatus(q, retired). |
diff --git a/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2 b/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2 index 79eb79a7..58620d6a 100644 --- a/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2 +++ b/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2 | |||
@@ -3,35 +3,39 @@ module tools.refinery.language.GenerateProblem | |||
3 | import org.eclipse.xtext.xtext.generator.* | 3 | import org.eclipse.xtext.xtext.generator.* |
4 | import org.eclipse.xtext.xtext.generator.model.project.* | 4 | import org.eclipse.xtext.xtext.generator.model.project.* |
5 | 5 | ||
6 | var rootPath = ".." | 6 | var rootPath = '..' |
7 | 7 | ||
8 | Workflow { | 8 | Workflow { |
9 | component = XtextGenerator { | 9 | component = XtextGenerator { |
10 | configuration = { | 10 | configuration = { |
11 | project = StandardProjectConfig { | 11 | project = StandardProjectConfig { |
12 | baseName = "language" | 12 | baseName = 'language' |
13 | rootPath = rootPath | 13 | rootPath = rootPath |
14 | runtimeTest = { | 14 | runtimeTest = { |
15 | enabled = true | 15 | enabled = true |
16 | srcGen = 'src/testFixtures/xtext-gen' | 16 | srcGen = 'src/testFixtures/xtext-gen' |
17 | } | 17 | } |
18 | genericIde = { | 18 | genericIde = { |
19 | name = "language-ide" | 19 | name = 'language-ide' |
20 | } | ||
21 | web = { | ||
22 | enabled = true | ||
23 | name = 'language-web' | ||
20 | } | 24 | } |
21 | mavenLayout = true | 25 | mavenLayout = true |
22 | } | 26 | } |
23 | code = { | 27 | code = { |
24 | encoding = "UTF-8" | 28 | encoding = 'UTF-8' |
25 | lineDelimiter = "\n" | 29 | lineDelimiter = '\n' |
26 | fileHeader = "/*\n * generated by Xtext \${version}\n */" | 30 | fileHeader = '/*\n * generated by Xtext \${version}\n */' |
27 | preferXtendStubs = false | 31 | preferXtendStubs = false |
28 | } | 32 | } |
29 | } | 33 | } |
30 | 34 | ||
31 | language = StandardLanguage { | 35 | language = StandardLanguage { |
32 | name = "tools.refinery.language.Problem" | 36 | name = 'tools.refinery.language.Problem' |
33 | fileExtensions = "problem" | 37 | fileExtensions = 'problem' |
34 | referencedResource = "platform:/resource/refinery-language-model/model/problem.genmodel" | 38 | referencedResource = 'platform:/resource/refinery-language-model/model/problem.genmodel' |
35 | serializer = { | 39 | serializer = { |
36 | generateStub = false | 40 | generateStub = false |
37 | } | 41 | } |
@@ -44,7 +48,17 @@ Workflow { | |||
44 | junitSupport = { | 48 | junitSupport = { |
45 | generateStub = false | 49 | generateStub = false |
46 | skipXbaseTestingPackage = true | 50 | skipXbaseTestingPackage = true |
47 | junitVersion = "5" | 51 | junitVersion = '5' |
52 | } | ||
53 | webSupport = { | ||
54 | // We only generate the {@code AbstractProblemWebModule}, | ||
55 | // because we write our own integration code for CodeMirror 6. | ||
56 | framework = 'codemirror' | ||
57 | generateHtmlExample = false | ||
58 | generateJettyLauncher = false | ||
59 | generateJsHighlighting = false | ||
60 | generateServlet = false | ||
61 | generateWebXml = false | ||
48 | } | 62 | } |
49 | } | 63 | } |
50 | } | 64 | } |
diff --git a/language/src/main/java/tools/refinery/language/Problem.xtext b/language/src/main/java/tools/refinery/language/Problem.xtext index c4c890e3..6f6a8588 100644 --- a/language/src/main/java/tools/refinery/language/Problem.xtext +++ b/language/src/main/java/tools/refinery/language/Problem.xtext | |||
@@ -26,7 +26,7 @@ EnumLiteral returns Node: | |||
26 | name=Identifier; | 26 | name=Identifier; |
27 | 27 | ||
28 | ReferenceDeclaration: | 28 | ReferenceDeclaration: |
29 | (-> (containment?="contains" | "refers"))? | 29 | (containment?="contains" | "refers")? |
30 | referenceType=[Relation|QualifiedName] | 30 | referenceType=[Relation|QualifiedName] |
31 | ("[" multiplicity=Multiplicity "]")? | 31 | ("[" multiplicity=Multiplicity "]")? |
32 | name=Identifier | 32 | name=Identifier |
@@ -184,7 +184,7 @@ QualifiedName hidden(): | |||
184 | 184 | ||
185 | Identifier: | 185 | Identifier: |
186 | ID | "true" | "false" | "unknown" | "error" | "class" | "abstract" | "extends" | "enum" | "pred" | "scope" | | 186 | ID | "true" | "false" | "unknown" | "error" | "class" | "abstract" | "extends" | "enum" | "pred" | "scope" | |
187 | "unique" | "default" | "problem" | "contains" | "refers" | "new" | "delete"; | 187 | "unique" | "default" | "problem" | "new" | "delete"; |
188 | 188 | ||
189 | Integer returns ecore::EInt hidden(): | 189 | Integer returns ecore::EInt hidden(): |
190 | "-"? INT; | 190 | "-"? INT; |