Skip to content
Browse files

Updated parsing rules to support precedence rules.

In gluer.resources the parsing rules have been updated to support precedence rules. Since the this changed the toplevel part of the resulting parse tree, some cleaning up has been done to make such changes easier in the future.

This means that 'build-assocation-library' function is now gone, and two new functions have been added: 'parsed-associations' and 'parsed-precedences'. Both functions use a general function 'toplevel-items', that extracts these toplevel items easily. The two new functions do not return mere sets of those items anymore, but now returns a set filename-item pairs, like it was already used in gluer.logic/parse-valid-files.

Furthermore, some test adapters has been added for testing the precedence rules. At the moment of this commit, precedende rules are simply ignored.
  • Loading branch information...
1 parent b045151 commit 439fed7e2711e4ca2cd512ffce4952a34cc705a4 @aroemers committed Nov 7, 2012
View
1 src-java/test/Main.java
@@ -13,6 +13,7 @@
private SuperSuperA superSuperA;
private SuperA superA;
private A a;
+ private A twice;
private SubA subA;
public Main(final String[] args) throws Exception {
View
2 src-java/test/adapter/SubBtoA.java
@@ -6,7 +6,7 @@
import test.modelb.SubSubB;
@Adapter
-public abstract class SubBtoA implements A {
+public class SubBtoA implements A {
private SubB adaptee;
View
29 src-java/test/adapter/TwiceBtoA1.java
@@ -0,0 +1,29 @@
+package test.adapter;
+
+import gluer.Adapter;
+import test.modela.A;
+import test.modelb.B;
+
+@Adapter
+public class TwiceBtoA1 implements A {
+
+ private B adaptee;
+
+ public TwiceBtoA1(B adaptee) {
+ this.adaptee = adaptee;
+ }
+
+ public void superSuperAMethod() {
+ System.out.println("{test.adapter.TwiceBtoA1} How to implement this?");
+ }
+
+ public void superAMethod() {
+ System.out.println("{test.adapter.TwiceBtoA1} Forwarding call to superBMethod.");
+ adaptee.superBMethod();
+ }
+
+ public void aMethod() {
+ System.out.println("{test.adapter.TwiceBtoA1} Forwarding call to bMethod.");
+ adaptee.bMethod();
+ }
+}
View
29 src-java/test/adapter/TwiceBtoA2.java
@@ -0,0 +1,29 @@
+package test.adapter;
+
+import gluer.Adapter;
+import test.modela.A;
+import test.modelb.B;
+
+@Adapter
+public class TwiceBtoA2 implements A {
+
+ private B adaptee;
+
+ public TwiceBtoA2(B adaptee) {
+ this.adaptee = adaptee;
+ }
+
+ public void superSuperAMethod() {
+ System.out.println("{test.adapter.TwiceBtoA2} How to implement this?");
+ }
+
+ public void superAMethod() {
+ System.out.println("{test.adapter.TwiceBtoA2} Forwarding call to superBMethod.");
+ adaptee.superBMethod();
+ }
+
+ public void aMethod() {
+ System.out.println("{test.adapter.TwiceBtoA2} Forwarding call to bMethod.");
+ adaptee.bMethod();
+ }
+}
View
2 src-java/test/bind.gluer
@@ -3,3 +3,5 @@ associate field test.Main.a with new test.modela.ConcreteA
associate field test.Main.superA with call test.modelb.ModelFactory.get()
associate field test.Main.superSuperA with single test.modelb.SubSubB using test.adapter.BtoA$BtoA_Inner
+
+associate field test.Main.twice with new test.modelb.TwiceB
View
16 src/gluer/agent.clj
@@ -22,12 +22,14 @@
;;; Helper functions.
(defn- build-transformation-library
- "Based on an association library, builds a map with a fully qualified class
- name as key and a set of associations that transform that class as a value.
- For example: {\"test.NativeClient\" #{{:where ... :what ...} ...}}"
- [association-library]
+ "Based on a set of filename-assocation pairs, builds a map with a fully
+ qualified class name as key and a set of associations that transform that
+ class as a value. For example:
+
+ {\"test.NativeClient\" #{{:where ... :what ...} ...}}"
+ [file-associations]
(apply merge-with (comp set concat)
- (for [association association-library]
+ (for [[file-name association] file-associations]
(let [transforms (transforms-classes association)]
(zipmap transforms (repeat (hash-set association)))))))
@@ -106,8 +108,8 @@
(:error (:parsed error)))))
(System/exit 1))
;; No parse errors, so build the libraries and initialise the agent.
- (let [association-library (r/build-association-library (map :parsed parsed))
- transformation-library (build-transformation-library association-library)
+ (let [file-associations (r/parsed-associations parsed)
+ transformation-library (build-transformation-library file-associations)
adapter-library (r/build-adapter-library)
transformer (transformer transformation-library)]
(log-verbose "Transformation library:" transformation-library)
View
4 src/gluer/logic.clj
@@ -228,9 +228,7 @@
all the results given by the 'check-association' function."
[valid-files adapter-library]
;; The symbol file-associations will refer to a single sequence of filename-association pairs.
- (let [file-associations (for [file valid-files
- association (get-in file [:parsed :succes :associations :association])]
- [(:file-name file) association])
+ (let [file-associations (r/parsed-associations valid-files)
individual-check-results (map #(check-association % adapter-library) file-associations)
overlap-check-results (check-overlaps file-associations)]
;; Merge all the {:errors [..] :warnings [..]} maps, and add the overlap errors to it.
View
83 src/gluer/resources.clj
@@ -163,19 +163,27 @@
(def rules
"The parse rules for .gluer files."
- {; Basic rules
- :associations [:association*]
+ {;; Root rule
+ :root [:toplevel*]
+ :toplevel #{ :precedence :association }
+
+ ;; Precedence rules
+ :precedence ["declare" "precedence" :higher "over" :lower]
+ :higher [:class]
+ :lower [:class]
+
+ ;; Association rules
:association ["associate" :where "with" :what :using?]
:where #{ :where-clause-field }
:what #{ :what-clause-new :what-clause-call :what-clause-single}
:using ["using" :class]
:class (re-pattern (str package-pattern "?" class-pattern))
- ; Where clauses
+ ;; Where clauses
:where-clause-field ["field" :field]
:field (re-pattern (str package-pattern "?" class-pattern "\\." member-pattern))
- ; What clauses
+ ;; What clauses
:what-clause-new ["new" :class]
:what-clause-call ["call" :method]
@@ -197,12 +205,65 @@
(for [file-name gluer-file-names]
{:file-name file-name
:parsed (try
- (p/parse rules :associations (slurp file-name))
+ (p/parse rules :root (slurp file-name))
(catch Exception ex {:error (str "Error parsing file: " ex)}))}))
-(defn build-association-library
- "Given a collection of parse-trees of .gluer files according to the `rules'
- above (including the :succes key), returns a set of associations found in all
- of the parse trees."
- [parsed-gluer-files]
- (set (mapcat #(get-in % [:succes :associations :association]) parsed-gluer-files)))
+(defn- toplevel-items
+ "Given the parse result as given by the `parse-gluer-files' function, returns
+ a set containing the toplevel items as identified by key `k'. Each item in the
+ set is a filename-item pair. So, the return value has the following form:
+
+ #{ [\"filename\" value-of-k]
+ [\"filename\" value-of-k]
+ [\"otherfile\" value-of-k]
+ ... }
+
+ Unsuccesfully parsed files are ignored."
+ [parse-result k]
+ (for [{:keys [file-name parsed]} parse-result
+ :let [toplevel (get-in parsed [:succes :root :toplevel])
+ filtered (remove nil? (map k toplevel))]
+ item filtered]
+ [file-name item]))
+
+(defn parsed-associations
+ "Given the parse result as given by the `parse-gluer-files' function, returns
+ a set containing filename-association pairs. The return value has the
+ following form:
+
+ #{ [\"filename\" {:where {...} :what {...} ... }]
+ [\"filename\" {:where {...} :what {...} ... }]
+ [\"otherfile\" {:where {...} :what {...} ... }]
+ ... }
+
+ Unsuccesfully parsed files are ignored."
+ [parse-result]
+ (toplevel-items parse-result :association))
+
+(defn parsed-precedences
+ "Given the parse result as given by the `parse-gluer-files' function, returns
+ a set containing filename-precedence pairs. The return value has the
+ following form:
+
+ #{ [\"filename\" {:higher {...} :lower {...} }]
+ [\"filename\" {:higher {...} :lower {...} }]
+ [\"otherfile\" {:higher {...} :lower {...} }]
+ ... }
+
+ Unsuccesfully parsed files are ignored."
+ [parse-result]
+ (toplevel-items parse-result :precedence))
+
+; (defn build-association-library
+; "Given a collection of parse-trees of .gluer files according to the `rules'
+; above (including the :succes key), returns a set of associations found in all
+; of the parse trees."
+; [parsed-gluer-files]
+; (toplevel-items parsed-gluer-files :association))
+
+; (defn build-precedence-library
+; "Given a collection of parse-trees of .gluer files according to the `rules'
+; above (including the :succes key), returns a set of precedende declarations
+; found in all of the parse trees."
+; [parsed-gluer-files]
+; (toplevel-items parsed-gluer-files :precedence))

0 comments on commit 439fed7

Please sign in to comment.
Something went wrong with that request. Please try again.