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/api
|
||||||
nabl2/runtime
|
nabl2/runtime
|
||||||
|
nabl2/shared/-
|
||||||
|
|
||||||
statics
|
statics
|
||||||
|
|
||||||
@ -11,7 +12,9 @@ imports
|
|||||||
|
|
||||||
rules // Analysis
|
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
|
rules // Debugging
|
||||||
|
|
||||||
|
@ -48,12 +48,92 @@ to produce
|
|||||||
```
|
```
|
||||||
{! ../syntax/examples/sec4.2_test3.dnf.aterm !}
|
{! ../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
|
However, we also want to use this second example to show another method of
|
||||||
running Stratego strategies from the Eclipse IDE.
|
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