1: Great renaming in pursuit of a CLJC-viable parser. There is still a bug here,

or between here and microworld.engine, because compiled rules which pass all the
unit tests nevertheless fail in integration testing.
This commit is contained in:
simon 2016-09-24 14:20:43 +01:00
parent 88d707a32e
commit 2788cac40f
12 changed files with 64 additions and 52 deletions

View file

@ -1,4 +1,4 @@
(defproject mw-parser "0.1.5-SNAPSHOT" (defproject mw-parser "3.0.0-SNAPSHOT"
:description "Parser for production rules for MicroWorld engine" :description "Parser for production rules for MicroWorld engine"
:url "http://www.journeyman.cc/microworld" :url "http://www.journeyman.cc/microworld"
:manifest { :manifest {
@ -8,11 +8,12 @@
"build-signature-timestamp" "unset" "build-signature-timestamp" "unset"
"Implementation-Version" "unset" "Implementation-Version" "unset"
} }
:source-paths ["src/clj" "src/cljc"]
:license {:name "GNU General Public License v2" :license {:name "GNU General Public License v2"
:url "http://www.gnu.org/licenses/gpl-2.0.html"} :url "http://www.gnu.org/licenses/gpl-2.0.html"}
:plugins [[lein-marginalia "0.7.1"]] :plugins [[lein-marginalia "0.7.1"]]
:dependencies [[org.clojure/clojure "1.6.0"] :dependencies [[org.clojure/clojure "1.8.0"]
[org.clojure/tools.trace "0.7.9"] [org.clojure/tools.trace "0.7.9"]
[instaparse "1.4.1"] [com.lucasbradstreet/instaparse-cljs "1.4.1.2"]
[mw-engine "0.1.5-SNAPSHOT"] [mw-engine "3.0.0-SNAPSHOT"]
]) ])

View file

@ -1,15 +1,15 @@
(ns ^{:doc "parse multiple rules from a stream, possibly a file." (ns ^{:doc "parse multiple rules from a stream, possibly a file."
:author "Simon Brooke"} :author "Simon Brooke"}
mw-parser.bulk microworld.parser.bulk
(:use mw-parser.declarative (:use microworld.parser.declarative
mw-engine.utils microworld.engine.utils
clojure.java.io clojure.java.io
[clojure.string :only [split trim]]) [clojure.string :only [split trim]])
(:import (java.io BufferedReader StringReader))) (:import (java.io BufferedReader StringReader)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; ;;;;
;;;; mw-parser: a rule parser for MicroWorld. ;;;; microworld.parser: a rule parser for MicroWorld.
;;;; ;;;;
;;;; This program is free software; you can redistribute it and/or ;;;; This program is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU General Public License ;;;; modify it under the terms of the GNU General Public License

View file

@ -1,14 +1,14 @@
(ns ^{:doc "A very simple parser which parses production rules." (ns ^{:doc "A very simple parser which parses production rules."
:author "Simon Brooke"} :author "Simon Brooke"}
mw-parser.core microworld.parser.core
(:use mw-engine.utils (:use microworld.engine.utils
[clojure.string :only [split trim triml]]) [clojure.string :only [split trim triml]])
(:gen-class) (:gen-class)
) )
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; ;;;;
;;;; mw-parser: a rule parser for MicroWorld. ;;;; microworld.parser: a rule parser for MicroWorld.
;;;; ;;;;
;;;; This program is free software; you can redistribute it and/or ;;;; This program is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU General Public License ;;;; modify it under the terms of the GNU General Public License
@ -44,7 +44,7 @@
;;;; * "if state is pasture and more than 3 neighbours have state equal to scrub then state should be scrub" ;;;; * "if state is pasture and more than 3 neighbours have state equal to scrub then state should be scrub"
;;;; * ;;;; *
;;;; ;;;;
;;;; it generates rules in the form expected by `mw-engine.core`, q.v. ;;;; it generates rules in the form expected by `microworld.engine.core`, q.v.
;;;; ;;;;
;;;; It is, as I say, very simple; it generates a complete rule, or it fails completely, returning nil. ;;;; It is, as I say, very simple; it generates a complete rule, or it fails completely, returning nil.
;;;; Very occasionally it generates a wrong rule - one which is not a correct translation of the rule ;;;; Very occasionally it generates a wrong rule - one which is not a correct translation of the rule
@ -434,7 +434,7 @@
(defn compile-rule (defn compile-rule
"Parse this `rule-text`, a string conforming to the grammar of MicroWorld rules, "Parse this `rule-text`, a string conforming to the grammar of MicroWorld rules,
into Clojure source, and then compile it into an anonymous into Clojure source, and then compile it into an anonymous
function object, getting round the problem of binding mw-engine.utils in function object, getting round the problem of binding microworld.engine.utils in
the compiling environment. If `return-tuple?` is present and true, return the compiling environment. If `return-tuple?` is present and true, return
a list comprising the anonymous function compiled, and the function from a list comprising the anonymous function compiled, and the function from
which it was compiled. which it was compiled.
@ -442,7 +442,7 @@
Throws an exception if parsing fails." Throws an exception if parsing fails."
([rule-text return-tuple?] ([rule-text return-tuple?]
(do (do
(use 'mw-engine.utils) (use 'microworld.engine.utils)
(let [afn (eval (parse-rule rule-text))] (let [afn (eval (parse-rule rule-text))]
(cond (cond
(and afn return-tuple?)(list afn (trim rule-text)) (and afn return-tuple?)(list afn (trim rule-text))

View file

@ -1,16 +1,16 @@
(ns ^{:doc "A very simple parser which parses production rules." (ns ^{:doc "A very simple parser which parses production rules."
:author "Simon Brooke"} :author "Simon Brooke"}
mw-parser.declarative microworld.parser.declarative
(:require [instaparse.core :as insta] (:require [instaparse.core :as insta]
[clojure.string :refer [split trim triml]] [clojure.string :refer [split trim triml]]
[mw-parser.errors :as pe] [microworld.parser.errors :as pe]
[mw-parser.generate :as pg] [microworld.parser.generate :as pg]
[mw-parser.simplify :as ps] [microworld.parser.simplify :as ps]
[mw-parser.utils :refer [rule?]])) [microworld.parser.utils :refer [rule?]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; ;;;;
;;;; mw-parser: a rule parser for MicroWorld. ;;;; microworld.parser: a rule parser for MicroWorld.
;;;; ;;;;
;;;; This program is free software; you can redistribute it and/or ;;;; This program is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU General Public License ;;;; modify it under the terms of the GNU General Public License
@ -96,7 +96,7 @@
(defn compile-rule (defn compile-rule
"Parse this `rule-text`, a string conforming to the grammar of MicroWorld rules, "Parse this `rule-text`, a string conforming to the grammar of MicroWorld rules,
into Clojure source, and then compile it into an anonymous into Clojure source, and then compile it into an anonymous
function object, getting round the problem of binding mw-engine.utils in function object, getting round the problem of binding microworld.engine.utils in
the compiling environment. If `return-tuple?` is present and true, return the compiling environment. If `return-tuple?` is present and true, return
a list comprising the anonymous function compiled, and the function from a list comprising the anonymous function compiled, and the function from
which it was compiled. which it was compiled.
@ -106,11 +106,12 @@
(assert (string? rule-text)) (assert (string? rule-text))
(let [rule (trim rule-text) (let [rule (trim rule-text)
tree (ps/simplify (parse-rule rule)) tree (ps/simplify (parse-rule rule))
afn (if (rule? tree) (eval (pg/generate tree)) clj (pg/generate tree)
afn (if (rule? tree) (eval clj)
;; else ;; else
(pe/throw-parse-exception tree))] (pe/throw-parse-exception tree))]
(if return-tuple? (if return-tuple?
(list afn rule) (list afn {:rule rule :clojure (print-str clj)})
;; else ;; else
afn))) afn)))
([rule-text] ([rule-text]

View file

@ -1,7 +1,7 @@
(ns ^{:doc "Display parse errors in a format which makes it easy for the user (ns ^{:doc "Display parse errors in a format which makes it easy for the user
to see where the error occurred." to see where the error occurred."
:author "Simon Brooke"} :author "Simon Brooke"}
mw-parser.errors) microworld.parser.errors)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;

View file

@ -1,9 +1,9 @@
(ns ^{:doc "Generate Clojure source from simplified parse trees." (ns ^{:doc "Generate Clojure source from simplified parse trees."
:author "Simon Brooke"} :author "Simon Brooke"}
mw-parser.generate microworld.parser.generate
(:require [mw-engine.utils :refer []] (:require [microworld.engine.utils :refer []]
[mw-parser.utils :refer [assert-type TODO]] [microworld.parser.utils :refer [assert-type TODO]]
[mw-parser.errors :as pe])) [microworld.parser.errors :as pe]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
@ -246,7 +246,7 @@
(list 'count (list 'count
(list 'remove 'false? (list 'remove 'false?
(list 'map (list 'fn ['cell] property-condition) (list 'map (list 'fn ['cell] property-condition)
(list 'mw-engine.utils/get-neighbours 'world 'cell distance)))) quantity)) (list 'microworld.engine.utils/get-neighbours 'world 'cell distance)))) quantity))
([comp1 quantity property-condition] ([comp1 quantity property-condition]
(generate-neighbours-condition comp1 quantity property-condition 1))) (generate-neighbours-condition comp1 quantity property-condition 1)))

View file

@ -1,11 +1,11 @@
(ns ^{:doc "Simplify a parse tree." (ns ^{:doc "Simplify a parse tree."
:author "Simon Brooke"} :author "Simon Brooke"}
mw-parser.simplify microworld.parser.simplify
(:require [mw-engine.utils :refer [member?]])) (:require [microworld.engine.utils :refer [member?]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; ;;;;
;;;; mw-parser: a rule parser for MicroWorld. ;;;; microworld.parser: a rule parser for MicroWorld.
;;;; ;;;;
;;;; This program is free software; you can redistribute it and/or ;;;; This program is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU General Public License ;;;; modify it under the terms of the GNU General Public License

View file

@ -1,10 +1,10 @@
(ns ^{:doc "Utilities used in more than one namespace within the parser." (ns ^{:doc "Utilities used in more than one namespace within the parser."
:author "Simon Brooke"} :author "Simon Brooke"}
mw-parser.utils) microworld.parser.utils)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; ;;;;
;;;; mw-parser: a rule parser for MicroWorld. ;;;; microworld.parser: a rule parser for MicroWorld.
;;;; ;;;;
;;;; This program is free software; you can redistribute it and/or ;;;; This program is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU General Public License ;;;; modify it under the terms of the GNU General Public License

View file

@ -1,7 +1,7 @@
(ns mw-parser.bulk-test (ns microworld.parser.bulk-test
(:use clojure.java.io) (:use clojure.java.io)
(:require [clojure.test :refer :all] (:require [clojure.test :refer :all]
[mw-parser.bulk :refer :all])) [microworld.parser.bulk :refer :all]))
(deftest bulk-parsing-test (deftest bulk-parsing-test
(testing "Bulk (file) parsing and compilation" (testing "Bulk (file) parsing and compilation"

View file

@ -1,9 +1,9 @@
(ns mw-parser.core-test (ns microworld.parser.core-test
(:use clojure.pprint (:use clojure.pprint
mw-engine.core microworld.engine.core
mw-engine.world) microworld.engine.world)
(:require [clojure.test :refer :all] (:require [clojure.test :refer :all]
[mw-parser.core :refer :all])) [microworld.parser.core :refer :all]))
(deftest primitives-tests (deftest primitives-tests
(testing "Simple functions supporting the parser" (testing "Simple functions supporting the parser"

View file

@ -1,11 +1,11 @@
(ns mw-parser.declarative-test (ns microworld.parser.declarative-test
(:use clojure.pprint (:use clojure.pprint
mw-engine.core microworld.engine.core
mw-engine.world microworld.engine.world
mw-engine.utils microworld.engine.utils
mw-parser.utils) microworld.parser.utils)
(:require [clojure.test :refer :all] (:require [clojure.test :refer :all]
[mw-parser.declarative :refer :all])) [microworld.parser.declarative :refer :all]))
(deftest rules-tests (deftest rules-tests
(testing "Rule parser - does not test whether generated functions actually work, just that something is generated!" (testing "Rule parser - does not test whether generated functions actually work, just that something is generated!"
@ -485,3 +485,13 @@
(is (= (apply afn (list (get-cell world 2 1) world)) nil) (is (= (apply afn (list (get-cell world 2 1) world)) nil)
"Middle cell of the strip is not scrub, so rule should not fire.")))) "Middle cell of the strip is not scrub, so rule should not fire."))))
(deftest regression-2-tests
(testing "Still getting fails althought tests for these fails fail."
(is
(=
(:state
(apply
(compile-rule "if state is scrub then 1 chance in 1 state should be forest")
(list {:state :scrub} {})))
:forest))))

View file

@ -1,11 +1,11 @@
(ns mw-parser.generate-test (ns microworld.parser.generate-test
(:use clojure.pprint (:use clojure.pprint
mw-engine.core microworld.engine.core
mw-engine.world microworld.engine.world
mw-engine.utils microworld.engine.utils
mw-parser.utils) microworld.parser.utils)
(:require [clojure.test :refer :all] (:require [clojure.test :refer :all]
[mw-parser.generate :refer :all])) [microworld.parser.generate :refer :all]))
(deftest expressions-tests (deftest expressions-tests