2021-01-12 16:41:01 +00:00
|
|
|
/** md
|
|
|
|
Title: Running a Strategy
|
|
|
|
|
|
|
|
## Running a Strategy
|
|
|
|
|
|
|
|
The first example of running a Stratego strategy
|
2021-01-14 18:19:35 +00:00
|
|
|
in the {! ../docrefs/manual.md !} is that of _evaluating_ an AST,
|
2021-01-12 16:41:01 +00:00
|
|
|
via the `prop-eval-rules` module in {! ../docrefs/sec4.1.md !}. This page
|
|
|
|
describes the most straightforward way to run this same strategy
|
|
|
|
in the Spoofax Eclipse IDE.
|
|
|
|
|
|
|
|
In the current project structure, Stratego transformations and strategies go in
|
|
|
|
the `trans` directory. So, you can place the Stratego code for
|
|
|
|
this module in `trans/prop-eval-rules.str`, with the following contents:
|
|
|
|
|
|
|
|
```Stratego
|
|
|
|
[End the documentation block to avoid the comment close in the code] **/
|
|
|
|
/** md [restart processing to include the code in the documentation] */
|
|
|
|
module prop-eval-rules
|
|
|
|
imports signatures/-
|
|
|
|
rules
|
|
|
|
E : Not(True()) -> False()
|
|
|
|
E : Not(False()) -> True()
|
|
|
|
E : And(True(), x) -> x
|
|
|
|
E : And(x, True()) -> x
|
|
|
|
E : And(False(), x) -> False()
|
|
|
|
E : And(x, False()) -> False()
|
|
|
|
E : Or(True(), x) -> True()
|
|
|
|
E : Or(x, True()) -> True()
|
|
|
|
E : Or(False(), x) -> x
|
|
|
|
E : Or(x, False()) -> x
|
|
|
|
E : Impl(True(), x) -> x
|
|
|
|
E : Impl(x, True()) -> True()
|
|
|
|
E : Impl(False(), x) -> True()
|
|
|
|
E : Impl(x, False()) -> Not(x)
|
|
|
|
E : Eq(False(), x) -> Not(x)
|
|
|
|
E : Eq(x, False()) -> Not(x)
|
|
|
|
E : Eq(True(), x) -> x
|
|
|
|
E : Eq(x, True()) -> x
|
|
|
|
/* [stop to avoid the open-comment in the code block] **/
|
|
|
|
/** md [conclusion of the documentation]
|
|
|
|
```
|
|
|
|
|
|
|
|
Note an important difference between this code and the `prop-eval-rules` block
|
|
|
|
in {! ../docrefs/sec4.1.md !}: here, we import `signatures/-` rather than `prop`.
|
|
|
|
That's because the Spoofax IDE automatically generates the Spoofax Propositional
|
|
|
|
Language AST signature for us, from its concrete syntax definition. (The
|
|
|
|
evaluation rules in {! ../docrefs/sec4.1.md !} also happen to be missing the
|
|
|
|
fourth `Impl` rule, but that's less material; unsurprisingly, none of the examples
|
|
|
|
given in the manual happen to rely on that rule, but we include it here for the
|
|
|
|
sake of completeness.)
|
|
|
|
|
|
|
|
As in the {! ../docrefs/manual.md !}, we need an additional module, which we can
|
|
|
|
place in `trans/prop-eval.str`, to describe the strategy by which we want
|
|
|
|
to apply the above evaluation rules and to facilitate actually invoking
|
|
|
|
the strategy on an AST. This file starts out much like its counterpart in
|
|
|
|
{! ../docrefs/sec4.1.md !}:
|
|
|
|
|
|
|
|
```Stratego
|
|
|
|
{! prop-eval.str {terminate: '^\s*$'} !}
|
|
|
|
```
|
|
|
|
|
|
|
|
So far, we've included the evaluation rules and defined a strategy `eval` to
|
|
|
|
apply them exhaustively to an AST starting with inner subterms. Now we want to
|
|
|
|
be able to "run" this strategy on an actual AST.
|
|
|
|
|
|
|
|
### Editor Services
|
|
|
|
|
|
|
|
The most straightforward mechanism to execute a Stratego transformation
|
|
|
|
in the Spoofax IDE is by use of Editor Services (ESV). ESV is actually a full
|
|
|
|
declarative language in its own right, covering syntax coloring, menu items,
|
|
|
|
hover texts, and more, and with its own
|
|
|
|
[manual](http://www.metaborg.org/en/latest/source/langdev/meta/lang/esv.html).
|
|
|
|
We will not delve into the details of ESV here, but merely provide a recipe
|
|
|
|
for using it to add an item to the "Spoofax" Eclipse menu for running Stratego.
|
|
|
|
|
|
|
|
Actually, we'll create a submenu "Manual" for our examples. It's
|
|
|
|
cleanest to put our additions in a separate ESV module, which then must be
|
|
|
|
included into the `editor/Main.esv` file, like so:
|
|
|
|
```esv
|
2021-01-15 17:57:30 +00:00
|
|
|
{! ../editor/Main.esv extract:
|
|
|
|
replace: ['^\s*$']
|
|
|
|
terminate: 'provider\s*:' !} [ ... rest of file suppressed for brevity. ]
|
2021-01-12 16:41:01 +00:00
|
|
|
```
|
|
|
|
It's just the one line `Manual` in the `imports` section that we have added. The
|
|
|
|
`editor/Manual.esv` implementing the submenu is also very simple:
|
|
|
|
```esv
|
2021-01-15 17:57:30 +00:00
|
|
|
{! ../editor/Manual.esv terminate: dnf !}
|
2021-01-12 16:41:01 +00:00
|
|
|
```
|
|
|
|
Note that the quoted string on the `action` line is the text label of the menu
|
2021-01-17 16:43:03 +00:00
|
|
|
item in the "Manual" submenu, and the identifier on its right-hand side is the
|
2021-01-12 16:41:01 +00:00
|
|
|
Stratego action to call. But note that `do-eval` is not the same identifier as
|
|
|
|
`eval` in our last Stratego file above. That's because the Stratego invocation
|
|
|
|
caused by an ESV action item has a specific, multi-item argument list, whereas
|
|
|
|
`eval` above expects only a single Spoofax Propositional Language AST to operate
|
|
|
|
on. To bridge this gap, we must add one more item to `trans/prop-eval.str`,
|
|
|
|
namely:
|
|
|
|
```Stratego
|
2021-01-15 17:57:30 +00:00
|
|
|
{! prop-eval.str extract: {start: '^(.*Interface.*\s*)$'} !}
|
2021-01-12 16:41:01 +00:00
|
|
|
```
|
|
|
|
This "do-XXX" rule is pretty much boilerplate glue between ESV and your Stratego
|
|
|
|
strategy of interest. (Note that this "glue" being used here corresponds to
|
|
|
|
what's used in the example
|
|
|
|
[Calc language project](https://github.com/MetaBorgCube/metaborg-calc),
|
|
|
|
but is slightly different from what is described in the
|
|
|
|
[Menus section](http://www.metaborg.org/en/latest/source/langdev/meta/lang/esv.html#menus)
|
|
|
|
of the ESV Manual. I am unclear on the significance of this difference or which
|
|
|
|
form is "better" -- I simply modeled this Stratego code after the code in the
|
|
|
|
working Calc repository, and all seems to be well.)
|
|
|
|
|
|
|
|
There's one last step before you can run `eval` from inside the IDE.
|
|
|
|
Editor Services has to be able to find the `do-eval` rule. You can enable that
|
2021-01-15 17:57:30 +00:00
|
|
|
by importing the `prop-eval` module in the main Stratego file for our language,
|
2021-01-12 16:41:01 +00:00
|
|
|
in this case `trans/spoofax_propositional_language.str`:
|
|
|
|
```Stratego
|
2021-01-15 17:57:30 +00:00
|
|
|
{! spoofax_propositional_language.str extract:
|
2021-01-17 18:15:32 +00:00
|
|
|
- stop: 'prop-dnf'
|
|
|
|
- start: '^(.*rule.*)$'
|
2021-01-15 17:57:30 +00:00
|
|
|
terminate: debug-show
|
|
|
|
!}
|
2021-01-12 16:41:01 +00:00
|
|
|
[ ... rest of file suppressed. ]
|
|
|
|
```
|
|
|
|
(I am unclear on what triggers ESV to use this particular Stratego file, but
|
|
|
|
in any automatically-generated Spoofax project there will be a main language
|
|
|
|
Stratego file in the `trans` directory, and that's the file from which
|
|
|
|
the rule specified in an ESV `action` has to be visible.)
|
|
|
|
|
|
|
|
Ok, with all of these elements in place, you should now be able to invoke
|
|
|
|
the `eval` rule from the "Spoofax" menu. For example, to execute the next example
|
|
|
|
from the Spoofax Tutorial/Reference
|
|
|
|
{! ../docrefs/sec4.1.md !}, navigate to the
|
|
|
|
file `syntax/examples/sec4.1_test1.spl`:
|
|
|
|
```SPL
|
|
|
|
{! ../syntax/examples/sec4.1_test1.spl !}
|
|
|
|
```
|
|
|
|
and select "Spoofax > Manual > prop-eval" from the menu bar to produce:
|
2021-01-14 18:19:35 +00:00
|
|
|
```
|
|
|
|
{! ../syntax/examples/sec4.1_test1.eval.aterm !}
|
|
|
|
```
|
|
|
|
You can do the same with test2:
|
|
|
|
```SPL
|
|
|
|
{! ../syntax/examples/sec4.1_test2.spl !}
|
|
|
|
```
|
|
|
|
to produce
|
|
|
|
```
|
|
|
|
{! ../syntax/examples/sec4.1_test2.eval.aterm !}
|
|
|
|
```
|
2021-01-15 17:57:30 +00:00
|
|
|
|
|
|
|
Both of these results match the expected output of the `eval` transformation
|
|
|
|
as shown in {! ../docrefs/sec4.1.md !} (allowing for the typo "ATom" in the
|
|
|
|
manual in the latter case).
|
2021-01-12 16:41:01 +00:00
|
|
|
**/
|