diff --git a/shared/rascal/src/export/BNF.rsc b/shared/rascal/src/export/BNF.rsc
index 57101784..e3016aef 100644
--- a/shared/rascal/src/export/BNF.rsc
+++ b/shared/rascal/src/export/BNF.rsc
@@ -21,7 +21,7 @@ public str pp(BGFProdList ps)
public str pp(BGFProduction p)
= (p.label!="" ? "[
] " : "")
- + " ::= ";
+ + " ::= ;";
public str pp(BGFExprList es)
{
diff --git a/shared/rascal/src/lib/Rascalware.rsc b/shared/rascal/src/lib/Rascalware.rsc
index 77fad351..95ab8f32 100644
--- a/shared/rascal/src/lib/Rascalware.rsc
+++ b/shared/rascal/src/lib/Rascalware.rsc
@@ -8,14 +8,14 @@ import List;
import IO;
// one length to rule them all
-public int len(list[&T] l) = List::size(l);
-public int len(set[&T] l) = Set::size(l);
-public int len(rel[&T,&T] l) = Relation::size(l);
+public int len(list[&T] x) = List::size(x);
+public int len(set[&T] x) = Set::size(x);
+public int len(rel[&T,&T] x) = Relation::size(x);
// one isempty to rule them all
-public bool isEmpty(list[&T] l) = List::isEmpty(l);
-public bool isEmpty(set[&T] l) = Set::isEmpty(l);
-public bool isEmpty(rel[&T,&T] l) = Relation::isEmpty(l);
+public bool isEmpty(list[&T] x) = List::isEmpty(x);
+public bool isEmpty(set[&T] x) = Set::isEmpty(x);
+public bool isEmpty(rel[&T,&T] x) = Relation::isEmpty(x);
public void print(str s) = IO::print(s);
public void println(str s) = IO::println(s);
@@ -26,3 +26,6 @@ public str joinStrings(list[str] ss, str w) = (ss[0] | it + w + s | s <- tail(ss
//public bool multiseteq(list[&T] xs, list[&T] ys) = sort(xs) == sort(ys);
public bool multiseteq(list[&T] xs, list[&T] ys) = sort(xs) == sort(ys);
//}
+
+public set[&T] toSet(list[&T] x) = List::toSet(x);
+public list[&T] toList(set[&T] x) = Set::toList(x);
diff --git a/shared/rascal/src/normal/ANF.rsc b/shared/rascal/src/normal/ANF.rsc
index 088c17e3..fb90df2d 100644
--- a/shared/rascal/src/normal/ANF.rsc
+++ b/shared/rascal/src/normal/ANF.rsc
@@ -8,12 +8,12 @@ import syntax::CBGF;
import transform::CBGF;
import transform::XBGF;
import analyse::Metrics;
-import Set;
-import List;
-import IO; //debug
+import lib::Rascalware;
import io::WriteBGF; // batch
import io::WriteCBGF; // batch
import io::ReadBGF; // batch
+import export::BNF;
+import IO;
CBGFSequence normalise(BGFGrammar g)
= (topNs(g) - leafNs(g) == toSet(g.roots)
@@ -32,7 +32,7 @@ CBGFSequence normAllStages(BGFGrammar gr)
dropAllLabels,
dropAllSelectors,
dropAllTerminals,
- dropAllHorizontals,
+ //dropAllHorizontals,
dropAllUnknowns,
dropAllChains
])
@@ -45,7 +45,58 @@ CBGFSequence normAllStages(BGFGrammar gr)
}
c += c1;
} while (!isEmpty(c1));
- return c;
+ // TODO check for horizontal/vertical issue
+ // now g is normalised, but with possibly multiple productions per nonterminal
+ for (n <- definedNs(g))
+ {
+ ps = prodsOfN(n,g.prods);
+ //println("");
+ if (len(ps)>1)
+ {
+ // go over all vertical production rules
+ for (p <- ps)
+ if (nonterminal(_) !:= p.rhs)
+ {
+ c2 = [extract_inline(production("",uniqueName(n,allNs(g)),p.rhs),innt(n))];
+ // global extract can introduce conflicts with subsequent extracts,
+ // that's why we need to transform immediately
+ g = transform(forward(c2),g);
+ c1 += c2;
+ }
+ c1 += horizontal_vertical(innt(n));
+ }
+ elseif (production(_,n,choice(L)) := ps[0])
+ {
+ //println("Horizontal!");
+ // go over all horizontal production rules
+ for (e <- L)
+ if (nonterminal(_) !:= e)
+ {
+ c2 = [extract_inline(production("",uniqueName(n,allNs(g)),e),innt(n))];
+ // global extract can introduce conflicts with subsequent extracts,
+ // that's why we need to transform immediately
+ g = transform(forward(c2),g);
+ c1 += c2;
+ }
+ }
+ //else
+ // iprintln(ps);
+ }
+ //iprintln(c1);
+ // now we can have constuctions like this:
+ // expression ::= (expression1 | expression2 | expression3 | expression | id | number) ;
+ // with cleverly hidden reflexive chain rules
+ for (p <- g.prods, production(str l,str n,choice(L)) := p, [*L1,nonterminal(n),*L2] := L)
+ // the last expression is a traceable variant of "nonterminal(n) in L"
+ c1 += removeH_addH(production(l,n,choice([*L1, marked(nonterminal(n)), *L2])));
+ return c+c1;
+}
+
+str uniqueName(str n, set[str] nts)
+{
+ int cx = 1;
+ while ("" in nts) cx += 1;
+ return "";
}
CBGFSequence dropAllLabels(BGFGrammar g) = [unlabel_designate(p) | p <- g.prods, p.label != ""];
@@ -59,7 +110,7 @@ CBGFSequence dropAllUnknowns(BGFGrammar g)
{
CBGFSequence cbgf = [];
set[str] used = usedNs(g.prods);
- for (p <- {q | q <- g.prods, epsilon() := q.rhs})
+ for (p <- {q | q <- g.prods, (epsilon() := q.rhs || empty() := q.rhs)})
if (p.lhs in used)
cbgf += undefine_define([p]);
else
@@ -85,7 +136,7 @@ BGFProduction markAllTerminals(BGFProduction p) = visit(p) {case terminal(t) =>
public void main()
{
for (src <- ["antlr","dcg","ecore","emf","jaxb","om","python","rascal-a","rascal-c","sdf","txl","xsd"])
- //for (src <- ["python"])
+ //for (src <- ["txl"])
{
println("Reading ...");
BGFGrammar g = readBGF(|home:///projects/slps/topics/convergence/guided/bgf/.bgf|);
@@ -96,5 +147,7 @@ public void main()
g = transform(forward(c),g);
println("Writing output to ...");
writeBGF(g,|home:///projects/slps/topics/convergence/guided/bgf/.normal.bgf|);
+ writeFile(|home:///projects/slps/topics/convergence/guided/bgf/.normal.bnf|,pp(g));
+ //println(pp(g));
}
}