feat: Add SPT as an alternate means of running Stratego strategies
Also completed and documented Sec 4.2 of the Stratego Tutorial/Reference manual
This commit is contained in:
parent
2357e1f220
commit
28a3370d03
12
test/manual-suite.spt
Normal file
12
test/manual-suite.spt
Normal file
@ -0,0 +1,12 @@
|
||||
module manual-suite
|
||||
language Spoofax-Propositional-Language
|
||||
|
||||
test sec4_2_test3 [[
|
||||
(r -> p & q) & p
|
||||
]] run dnf to Atom("x")
|
||||
|
||||
test sec4_2_test3_ex [[
|
||||
(r -> p & q) & p
|
||||
]] run dnf to Or(And(Not(Atom("r")),Atom("p")),And(And(Atom("p"),Atom("q")),Atom("p")))
|
||||
|
||||
|
@ -4,6 +4,7 @@ imports
|
||||
|
||||
nabl2/api
|
||||
nabl2/runtime
|
||||
nabl2/shared/-
|
||||
|
||||
statics
|
||||
|
||||
@ -11,7 +12,9 @@ imports
|
||||
|
||||
rules // Analysis
|
||||
|
||||
editor-analyze = nabl2-analyze(id)
|
||||
// editor-analyze = nabl2-analyze(id)
|
||||
strip-indices : AnalysisResult([(r,Full(y,a,l,m,n))]) -> AnalysisResult([(r,Full(<nabl2--erase-ast-indices>y,a,l,m,n))])
|
||||
editor-analyze = nabl2-analyze(id); strip-indices
|
||||
|
||||
rules // Debugging
|
||||
|
||||
|
@ -48,12 +48,92 @@ to produce
|
||||
```
|
||||
{! ../syntax/examples/sec4.2_test3.dnf.aterm !}
|
||||
```
|
||||
as verified in the manual (again, modulo the"ATom" typo in the manual).
|
||||
as verified in the manual (again, modulo the "ATom" typo in the manual).
|
||||
|
||||
However, we also want to use this second example to show another method of
|
||||
running Stratego strategies from the Eclipse IDE.
|
||||
|
||||
## Spoofax Testing Language
|
||||
### Spoofax Testing Language
|
||||
|
||||
CONTINUE FROM HERE
|
||||
**/
|
||||
The
|
||||
[Spoofax Testing Language](http://www.metaborg.org/en/latest/source/langdev/meta/lang/spt/index.html)
|
||||
(SPT) is a declarative language that provides for a full range of tests
|
||||
for a Spoofax language project. As such, it includes the ability to run an
|
||||
arbitrary Stratego strategy on the results of parsing an arbitrary piece of
|
||||
the language you're working with -- seemingly perfect for our interest in
|
||||
trying our different Stratego transformations.
|
||||
|
||||
So, we can just take our `test3` expression above and make it a part of
|
||||
an SPT test suite, which we will call `test/manual-suite.spt`:
|
||||
```SPT
|
||||
{! ../test/manual-suite.spt terminate: '(.*run dnf)' !}
|
||||
```
|
||||
|
||||
Once we have saved this file, the tests run automatically. What does this mean?
|
||||
The file seems to be just "sitting there;" there's no indication that anything
|
||||
is happening. That's because this test we've just written **succeeds**. All we
|
||||
asked is that Spoofax run the `dnf` transformation on the results of parsing
|
||||
the test expression. It did that, and the transformation succeeded. So all is
|
||||
well, and no output is generated.
|
||||
|
||||
But of course, we want to see what the _result_ of the transformation was. One
|
||||
way of arranging that is to ask that SPT compare that result to a given AST.
|
||||
If we use an AST like `Atom("x")` that can't possibly be the actual output
|
||||
(since "x" does not occur in the input), then the error message will show
|
||||
what the transformation actually produced. So we add just a bit to
|
||||
`test/manual-suite.spt`:
|
||||
```SPT
|
||||
{! ../test/manual-suite.spt terminate: '(.*run dnf.*)$' !}
|
||||
```
|
||||
|
||||
and now sure enough a little error symbol appears next to the test. If you hover
|
||||
over it, a popup will show up, indicating that SPT was expecting `Atom("x")`,
|
||||
but got... wait! What's this monstrosity?
|
||||
```
|
||||
Got: Or(And(Not(Atom("r"{TermIndex("test/manual-suite.spt",1)}){TermIndex
|
||||
("test/manual-suite.spt",2)}),Atom("p"{TermIndex("test/manual-suite.spt",9)})
|
||||
{TermIndex("test/manual-suite.spt",10)}),And(And(Atom("p"{TermIndex("test/manual-
|
||||
suite.spt",3)}){TermIndex("test/manual-suite.spt",4)},Atom("q"{TermIndex
|
||||
("test/manual-suite.spt",5)}){TermIndex("test/manual-suite.spt",6)}){TermIndex
|
||||
("test/manual-suite.spt",7)},Atom("p"{TermIndex("test/manual-suite.spt",9)})
|
||||
{TermIndex("test/manual-suite.spt",10)}))
|
||||
```
|
||||
|
||||
Well, it is actually the result of running the `dnf` strategy on the result of
|
||||
parsing ` {! ../syntax/examples/sec4.2_test3.spl !} `. It's just that Spoofax
|
||||
automatically annotates every subterm of the parsed term with its location in
|
||||
the input, and those annotations are carried through the Stratego
|
||||
transformation. While this can be very helpful in figuring out exactly what
|
||||
happened in the course of the transformation, it can also make the output
|
||||
practically unreadable.
|
||||
|
||||
Fortunately, we can strip this annotation if we like, by modifying the
|
||||
`editor-analyze` rule in `trans/analysis.str` like so:
|
||||
```Stratego
|
||||
{! ../trans/analysis.str terminate: Debugging!} [rest of file omitted]
|
||||
```
|
||||
|
||||
Now rebuild the project and re-run the SPT manual suite. (You may need to
|
||||
do an irrelevant edit and save of the `test/manual-suite.spt` file, or
|
||||
you can select this file in the project explorer and select the menu item
|
||||
"Spoofax (meta) > Run all selected tests" to pop up a convenient window of
|
||||
all test results.) Now you should see the much more readable
|
||||
```
|
||||
Got: Or(And(Not(Atom("r")),Atom("p")),And(And(Atom("p"),Atom("q")),Atom("p")))
|
||||
```
|
||||
in the error message for the `sec4_2_test3` test.
|
||||
|
||||
Of course, if you know the AST you expect to generate with your transformation,
|
||||
you can also just tell SPT to compare against that, for example in our case
|
||||
by adding a test to the manual suite like this:
|
||||
```SPT
|
||||
{! ../test/manual-suite.spt extract:
|
||||
start: '(test sec4_2_test3_ex.*\n?)$'
|
||||
stop: '^(.*run.*)$'
|
||||
!}
|
||||
```
|
||||
|
||||
Now if there is no error or warning on this test then you know the
|
||||
`dnf` strategy produced the result shown in the `to` clause, and otherwise,
|
||||
the actual result will be shown in the error popup.
|
||||
**/
|
||||
|
Loading…
Reference in New Issue
Block a user