Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site ucla-cs.ARPA Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxt!houxm!vax135!cornell!uw-beaver!tektronix!hplabs!sdcrdcf!ucla-cs!dimare From: dimare@ucla-cs.UUCP Newsgroups: net.lang.prolog Subject: DCGs + Left Recursion = (:-[) ! Message-ID: <6884@ucla-cs.ARPA> Date: Thu, 19-Sep-85 19:38:57 EDT Article-I.D.: ucla-cs.6884 Posted: Thu Sep 19 19:38:57 1985 Date-Received: Mon, 23-Sep-85 00:43:44 EDT Organization: UCLA Computer Science Department Lines: 93 I'm writing a little parser for a Pascal like language. I was going to copy Wirth's grammar into a DCG Prolog program, but I noticed that left recursion can't be used. If you have a rule like: a --> a, [+], b. a --> b. b --> [b]. it translates into: a(A, B) :- a(A, C), 'C'(C, +, D), b(D, B). 'C'([H|T],H,T). Any goal of the form a(Sentence,[]) would make the above rule recurse until end_of_stack. (Yes, a([b,+,b],[]) doesn't work either: try it!). My problem is that the grammars I know for parsing expressions are left recursive. The example in most Prolog manuals uses left recursion. I ran it, and I got the following result (I include the code at the end of the message): | ?- expr(Z,"2-3-4",[]). Z = 3 ; no | ?- Z is 2-3-4. Z = -5 ; no | ?- halt. Obviously, the 'standard' example is wrong. My question is: Does any body know a way to do expressions using DCGs that doesn't make the grammar look like a plate of spaghetti? I know I could translate my grammar into Griebach Normal Form (or $%#!"%#$" Normal Form, for that mater), but I could also as well write the whole parser in 8080 assembly language. Here's the grammar: Script started on Thu Sep 19 15:16:07 1985 h[2:101] c dcg0 % File : /usr/lib/prolog/teach/dcg0 % Author : lost in the mists of time % Updated: 23 Nov 1983 % Purpose: the standard example of using Prolog grammar rules % This is a simple grammar which parses an arithmetic expression (of digits and % operators) and computes its value. expr(Z) --> term(X), "+", expr(Y), {Z is X+Y}. expr(Z) --> term(X), "-", expr(Y), {Z is X-Y}. expr(Z) --> term(Z). term(Z) --> number(X), "*", term(Y), {Z is X*Y}. term(Z) --> number(X), "/", term(Y), {Z is X/Y}. term(Z) --> number(Z). number(C) --> "+", number(C). number(C) --> "-", number(X), {C is -X}. number(X) --> [C], {48=