Hi Pablo
It's hard ...
With OCL it's particularly hard since by itself OCL is almost
completely useless. OCL is only really useful once embedded in an
environment such as OCLinEcore, or UML OpaqueExpression, or M2M
languages that provides models and there is no standard tooling
level API. In principle OCL could be formulated as a set of
modules for different aspects such as Primitives, States,
Messages, Templates, Iterations, ... each with partial
grammars/libraries/name-rules/validations/execution-semantics. An
OCL user could then select the aspects that were appropriate and
define further modules for the embedding application and throw
them all at some auto-generators and out would pop a well tooled
language. The Pivot-based Eclipse OCL and QVTd go a long way in
this direction, but there is a long way still to go and I may
retire some day.
Stepping back from Utopia., when you have two grammars, you have
two choices.
You can nest one inside the other, which OCLinEcore does for the
Markup that may be used in the very disciplined nested context of
a multi-line comment. The outer grammar works normally and parses
a comment String that is then passed to a nested parser, from
which errors can contribute to red squiggles, but completion
assist is hard.
You can compound them as OCLinEcore does with EssentialOCL. Both
grammars now provide a larger grammar that parses
straightforwardly, except that the language philosophy must be
compatible; no conflicting punctuation, clear keywords which may
need escaping to allow usage in identifiers. For well designed
grammars this can be easy. EssentialOCL has some poor design
decisions in regard to the implicit sources of iterators that
allow declaration within expressions. These lead to difficulties
for Complete OCL and OCLinEcore. (Complete OCL error recovery is
really bad. OCLinEcore is better but has some uncomfortable syntax
design.)
Completion assist can be really good when the metamodel and
grammar are exploited, but only when the user's input is error
free and the grammar unambiguous. Unfortunately completion assist
is often wanted when the user has only partially typed a construct
or when the user's input is a mess. The parser consequently has no
idea, or worse a wrong idea, of what the user is trying to do and
produces completely off beam suggestions. Xtext with its
underlying LL technology backtracks and so does not naturally have
all alternatives available. I therefore find Xtext completion
assist poor and error recovery bad. In contrast an LALR grammar
flattens all the alternatives and so does see all possibilities
and also supports better error recovery. However it's hard and
considering another field, I find that the JDT completion assist
has got significantly worse over the last ten years despite the
efforts to make it better. I guess it lacks a decent metamodel and
all the complexities of yet another Java version break the
heuristics that worked in the old days.
Providing sensible names in completions relies on the parser
having a sensible idea of what's going on so that names in
declarations can be offered to / checked by references. Xtext has
a default and highly configurable ability to propagate
hierarchical declarations. OCL has some slightly irregular rules,
particularly in regard to implicit sources and imports, so I
elected to reimplement, and so understand, on top of the Xtext
IScope API. Not sure whether this was a good decision or a
disgraceful bit of Not-Invented-Here. Anyway, if you want declared
names to contribute to reference resolution you will need a
ScopeProvider subsystem.
You need to assess whether your application can be satisfied by a
very lightweight OCL embedded as a magic delimited String that is
passed to a nested Essential OCL parser or by a heavyweight
compound language such as OCLinEcore or QVTi. You might find QVTi
the simplest to 'clone'.
See
https://git.eclipse.org/r/plugins/gitiles/mmt/org.eclipse.qvtd/+/refs/heads/master/plugins/org.eclipse.qvtd.xtext.qvtimperative/src/org/eclipse/qvtd/xtext/qvtimperative/QVTimperative.xtext
Regards
Ed Willink
On 30/09/2021 16:02, Pablo Gómez Abajo
via mdt-ocl.dev wrote: