core.logic - DCG

119 views
Skip to first unread message

Alexsandro Soares

unread,
Sep 16, 2012, 11:52:38 PM9/16/12
to clo...@googlegroups.com
Hi,

  I'm trying to write a small parser using DCG, but when I use the code below

-------------- parser.clj -----------------------
(ns compiler.parser
  (:refer-clojure :exclude [==])
  (:use [clojure.core.logic]
        [clojure.core.logic.dcg] )
)
  
(def-->e token [tg x]
  ([_ ?tk] [?tk]
     (!dcg
       (project [?tk]
          (== (= (?tk :tag) tg) true)))))

(declare expr1 term term term1 factor)

(def-->e expr [e]
   ([?e1] (fresh [t] (term t) (expr1 t ?e1))))

(def-->e expr1 [t e]
   ([t1 ?e1] (fresh [tk t2]
      (token '+ tk) (term t2) (expr1 {:binop '+ t1 t2} ?e1)))
   ([_ t] []))

(def-->e term [t]
  ([?t1] (fresh [f] (factor f) (term1 f ?t1))))

(def-->e term1 [f t]
   ([f1 ?t1] (fresh [tk f2]
      (token '* tk) (factor f2) (term1 {:binop '* f1 f2} ?t1)))
   ([_ f] []))

(def-->e factor [tree]
   ([?tk] (token 'id ?tk))
   ([?tk] (token 'int ?tk))
   ([?tk] (token 'real ?tk)))

(def tokens1 [{:tag 'int, :value 1, :start {:line 1, :col 1}}
                     {:tag '+, :start {:line 1, :col 2}}
                     {:tag 'int, :value 2, :start {:line 1, :col 3}} ])

(def tokens2 [{:tag 'int, :value 1, :start {:line 1, :col 1}}
                     {:tag '*, :start {:line 1, :col 2}}
                     {:tag 'int, :value 2, :start {:line 1, :col 3}} ])

(defn tests [num]
   (let [tokens (case num
                  1 tokens1
                  2 tokens2)]
     (run 1 [tree] (expr tree tokens []))))

--------------------------------------------------

I get these answers in Clojure:

compiler.parser=> (tests 1)
({:binop +, <lvar:t1_5036> {:start {:col 3, :line 1}, :value 2, :tag int}})

compiler.parser=> (tests 2)
({:binop *, <lvar:f1_5079> {:start {:col 3, :line 1}, :value 2, :tag int}})

The first argument is a  logical variable not instanced and what I'm expecting is:

compiler.parser=> (tests 1)
({:binop +  {:tag 'int, :value 1, :start {:line 1, :col 1}}
                 {:start {:col 3, :line 1}, :value 2, :tag int}})

compiler.parser=> (tests 2)
({:binop *  {:tag 'int, :value 1, :start {:line 1, :col 1}}
                {:start {:col 3, :line 1}, :value 2, :tag int}})


What am I doing wrong?

Thanks in advance for any answer.

Regards,
Alex

David Nolen

unread,
Sep 17, 2012, 11:56:18 AM9/17/12
to clo...@googlegroups.com
On Sun, Sep 16, 2012 at 11:52 PM, Alexsandro Soares
<prof.a...@gmail.com> wrote:
> (def-->e expr1 [t e]
> ([t1 ?e1] (fresh [tk t2]
> (token '+ tk) (term t2) (expr1 {:binop '+ t1 t2} ?e1)))
> ([_ t] []))

> (def-->e term1 [f t]
> ([f1 ?t1] (fresh [tk f2]
> (token '* tk) (factor f2) (term1 {:binop '* f1 f2} ?t1)))
> ([_ f] []))

You can't use logic variables as keys in maps.

A side note ... the DCG namespace is *very* experimental :)

David
Reply all
Reply to author
Forward
0 new messages