Grammar rules can be tested using plunit_assert. For example:
?- assert_output(phrase(position(Ordinal), ['the', 'last', 'digit'], []), [Ordinal], [third]).
[plunit_assert] Output does not match expected: expected [third], got [fourth]
false.
?- assert_output(phrase(position(Ordinal), ['the', 'last', 'digit'], []), [Ordinal], [fourth]).
Ordinal = fourth.
But the syntax is clunky and easy to mess up. Perhaps:
- detect it's a grammar rule rather than a predicate within an assert_* test predicate and transparently wrap the call in
phrase/3
- treat them as explicitly different and begin a family of eg. dcg_assert_* tests (nb below)
- implement a DSL, something like
position(['the', 'last', 'digit']) should_parse_to fourth.
- ...
nb.
assert_grammar_output(GrammarRule, Vars, Expected) :-
phrase(GrammarRule, Input, []),
GrammarRule =.. [Functor|Args],
Vars = Args,
Vars = Expected.