i am a newbie in prolog, i want to read a file which actually contains CLASS Definition - using Prolog DCG Rule. But i am stuck in between now..
My input text (linessample.txt)
class component {
attributes
Real V, I, R;
constraints
V = I * R;
constructors component(V1, I1, R1) {
V = V1; I = I1; R = R1;
}
}
I want to read the above sample text using DCG Rule in prolog... I have written one sample code.. but i am not getting the first word "class" in the output
Code
:- use_module(library(pio)).
%classrule(Z) -->class,letter(X),letters(L),{name(Z,[X|L])}.
classrule(Z) -->"class ",classname(X),"{",{name(Z,X)}.
classname([X|L])-->letter(X),letters(L).
letters([X|L])-->letter(X),!,letters(L).
class-->"class".
letters([])-->[].
letter(X)-->[X], {alpha(X)}.
alpha(X) :- X > 64, X < 91.
alpha(X) :- X > 96, X < 123.
how to run this
phrase_from_file(classrule(Z),'linesample.txt').
There are two main problems with your program:
1. You do not allow for a space to occur between classname/1 and "{". Since in practice multiple spaces (and horizontal tabs) may occur here, I have used whites//0
from library dcg/basics
.
2. phrase_from_file/2
tries to parse the entire input document, whereas your grammar only covers the first line (i.e., the class name). This is solved by skipping the rest of the file. I use '...'//0
and then eos//0
for this.
Then there are some minor things:
1. Clauses of letters//1
are not placed consecutively in the code file. I have relocated one clause but you can also add the declarations :- discontiguous(letters//1).
at the top of your program.
2. I have used code_type/2
to check for alphabetic characters.
The resultant code, updated after useful comments from mat:
:- use_module(library(dcg/basics)).
:- use_module(library(pio)).
classrule(Z) -->
"class",
whites,
classname(X),
whites,
"{",
{name(Z,X)},
... .
classname([H|T])-->
letter(H),
letters(T).
letters([H|T])-->
letter(H), !,
letters(T).
letters([])--> [].
letter(X)-->
[X],
{code_type(X, alpha)}.
... --> [].
... -->
[_],
... .
Example of use:
?- phrase_from_file(classrule(X), 'linesample.txt').
X = component