As part of a project I need to write a parser that can read a file and parse into facts I can use in my program.
The file structure looks as follows:
p
as long as your file is in plain Prolog syntax, you're advised to use Prolog term IO. Fully structured terms are read with a single call. Using a DCG its' way more complicate, and a bit less efficient (not sure here, should measure, but read(Term) invokes a Prolog parser implemented in C...) See this other question, that uses the very same format (at least, you could check if some other guy got an answer here on SO about your same assignment...)
edit after comments...
You're right that DCG are the right way to handle general parse in Prolog. Arguments in DCG productions can be seen as semantic attributes, thus programming DCG can be seen as providing a working semantic analysis on the input (see Attribute Grammar, an important technique -also- in language engineering).
And indeed the presented examples can perfectly well be solved without the hacks required with term IO.
Here it is:
:- use_module(library(pio)). % autoload(ed), added just for easy browsing
:- use_module(library(dcg/basics)).
property(P) -->
b, "my props", b, "=", b, "{", elS(Es) , b, "}", b,
{ P =.. [property|Es] }.
elS([E|Es]) --> el(E), b, ("," -> elS(Es) ; {Es = []}).
el(N) --> number(N).
el(S) --> csym(S). % after Jeremy Knees comment...
b --> blanks.
% parse a C symbol
csym(S) -->
[F], { code_type(F, csymf) },
csym1(Cs),
!, { atom_codes(S, [F|Cs]) }.
csym1([C|Cs]) -->
[C], { code_type(C, csym) },
csym1(Cs).
csym1([]) --> [].
with that, we have
?- phrase(property(P), "my props = {1,2,3}").
P = property(1, 2, 3).
Thanks to library(pureio) we can apply semantic programming to Prolog streams, and be rewarded of the same behaviour of phrase/2.
more
This other answer show a practical way to implement an expression calculator with operator resolution, and lazy evaluation.