To understand my reasoning behind what I do requires a bit of a history lesson.
When I started expanding my use of Prolog by going from just a few short exercise cases that were less than a hundred lines to to code that would work on a real world problem with multiple files I turned to using SWI-Prolog and asking questions on StackOverflow. Turns out that using StackOverflow examples to learn DCGs with SWI-Prolog for parsing will give you lots of headaches because SWI-Prolog uses double quotes differently.
The string type and its double quoted syntax
So many of the examples for DCGs for parsing on StackOverflow and in many blogs, etc. don’t mention this and thus parse differently. If you take that code as is and try in on SWI-Prolog it sometimes works, and sometimes fails.
So after many months came to realize that to ensure that my DCGs were parsing as I expected I would add
:- set_prolog_flag(double_quotes, <something>).
:- set_prolog_flag(back_quotes, <something different>).
in all the code, even the code I created, copied from StackOverflow or other places, and answer I would give on StackOverflow, and even if it was not really changing the meaning.
Then as time went on I started using test cases with
:- begin_tests(abc).
:- end_tests(abc).
and that started a second set of problems because I did not know that
:- begin_tests(abc).
:- end_tests(abc).
are actually creating a new module and the flags are scoped to a module.
So now any time I write a DCG for use by others I follow these steps.
- Create a module using
module/2
- Set Prolog flags for
double_quotes
andback_quotes
at the top of the module. - Add the DCGs
- Create unit test section with
begin_tests/1
andend_tests/1
- Set Prolog flags for
double_quotes
andback_quotes
in the test section at the top of the section. - Add the tests.
Example: How to use DCG in Prolog. See the variation with module/2
Another place you have to be concerned about all of this but I have yet to reason it all out is when you are developing code using the top-level and using assert/N to add the predicates. How does all of this work since you are probably not using modules.
To avoid that problem I write all of my code the traditional way with files, an editor and then consult/make to load the files.
Related Q&A
What type is a single quoted string?
Prolog DCG set_prolog_flag double_quotes source code directive location matters; documentation?
With regards to the Prolog flags double_quotes
and back_quotes
, none now.
There are many other problems in the area related to parsing with DCGs, but I could write a few chapters on that.