I have this dcg code:
program([Node|Rest]) --> item(Node), (program(Rest) | {Rest = []}).
item(Node) --> lit(Node) | quote(Node) | pat_obj(Node) | word(Node). %| word_def(Node).
lit(num(N, L)) --> [lit(N, L)], {number(N)}.
lit(str(S, L)) --> [lit(S, L)], {string(S)}.
lit(true(L)) --> [word_s("t", L)].
lit(false(L)) --> [word_s("f", L)].
lit(atom(A, L)) --> [lit(A, L)], {atom(A)}.
word(word(right, Name, L)) --> [word(">", Name, L)].
word(word(left, Name, L)) --> [word("<", Name, L)].
word(word_s(Name, L)) --> [word_s(Name, L)].
quote(quote(Body, L)) --> [word_s("[", L)], program(Body), [word_s("]", _)].
% maybe allow nested objects?
pat_obj(pattern_obj(Pats, L)) --> [word_s("(", L)], pats(Pats), [word_s(")", _)].
pats([Pat|Rest]) --> pat(Pat), (pats(Rest) | {Rest = []}).
pat(quo_spl(left, Pats, R)) --> [word_s("[", _)], pats(Pats), [word_s("|<",_)], pat(R), [word_s("]", _)]. % too complicated?, also maybe change symbol for it
pat(quo_spl(right, Pats, R)) --> [word_s("[", _)], pat(R), [word_s("|>",_)], pats(Pats), [word_s("]", _)]. % too complicated?
pat(quote(Quote)) --> [word_s("[", _)], pats(Quote), [word_s("]", _)].
pat(lit(Lit)) --> [lit(Lit, _)].
pat(var(Name)) --> [word_s(Name, _)], {\+ (Name = "|>"), \+ (Name = "|<")}.
I want to prevent prolog from backtracking if it fails to find a match for quote
, lit
, par_obj
, etc.
For example:
This is the current behavior for an invalid pat_obj
?- pparse("( |> )").
[word_s("(",1),word_s("|>",1),word_s(")",1)]
true .
|>
is not a valid word for a pattern variable, so prolog goes all the way back and see that this cant be parsed as three words. How can I prevent this, because I want it to fail if it can’t match a pat_obj, not backtrack. I tried using cuts, and they didn’t seem to work (or I put them in the wrong place).
Any ideas? Thanks in advance