diff --git a/shared/rascal/src/Main.rsc b/shared/rascal/src/Main.rsc
index 767d835f..53261bed 100644
--- a/shared/rascal/src/Main.rsc
+++ b/shared/rascal/src/Main.rsc
@@ -5,34 +5,22 @@ import String;
import IO;
import syntax::BGF;
import syntax::XBGF;
-import io::ReadBGF;
-import io::ReadXBGF;
-import io::WriteXBGF;
-import transform::XBGF;
-//import lang::xml::DOM;
+import diff::GDT;
+import transform::library::Test;
+import transform::NegotiatedXBGF;
public void main()
{
- XBGFSequence x;
- x = readXBGF(|project://slps/tests/all/abridge.xbgf|);
- println(x);
- g1 = readBGF(|project://slps/tests/all/abridge.bgf|);
- g2 = readBGF(|project://slps/tests/all/abridge.baseline|);
- //writeXBGF(x,|project://slps/tests/all/abridge.bgf|);
- g3 = transform(x,g1);
+ <_,g1,g2> = transform::library::Test::test_data["renameN"];
+ XBGFSequence x = [renameN("expression","exp")];
+ //XBGFSequence x = [renameN("expr","int")];
+
+
= transform::NegotiatedXBGF::attemptTransform(x,g1);
+ iprintln(x);
+ println(g1);
println(g3);
println(g2);
-}
-
-public bool tryAll()
-{
- loc base = |project://slps/tests/xbgf|;
- loc outp = |project://slps/tests/xbgf-res|;
- for (f <- listEntries(base))
- {
- if (f == ".gitignore") continue;
- println(f);
- writeXBGF(readXBGF(base+f),outp+f);
- }
- return true;
+ println(diff::GDT::gdtv(g3,g2));
+ println(p);
+ println(a);
}
diff --git a/shared/rascal/src/Sync.rsc b/shared/rascal/src/Sync.rsc
index 8ca7072e..b3658675 100644
--- a/shared/rascal/src/Sync.rsc
+++ b/shared/rascal/src/Sync.rsc
@@ -15,7 +15,7 @@ public void main()
loc base = |home:///projects/slps/topics/transformation/xbgf/tests|;
str buffer = "@contributor{Super Awesome Automated XBGF Test Suite Synchroniser}
'@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
- 'module transform::XBGFTest
+ 'module transform::library::Test
'
'import IO;
'import syntax::BGF;
@@ -37,6 +37,6 @@ public void main()
buffer2 += "test bool test_() { \ = test_data[\"\"]; return gdts(transform(xbgf,bgf1),bgf2); }\n";
buffer3 += "void show_() { \ = test_data[\"\"]; println(\"Input \\");println(\"Transformations: \\");println(\"Expected output \\");bgf3=transform(xbgf,bgf1);println(\"Actual output \\"); gdtv(bgf3,bgf2); }\n";
}
- writeFile(|project://slps/src/transform/XBGFTest.rsc|, replaceLast(buffer,",","")+");\n\n"+buffer3+"\n\n"+buffer2);
+ writeFile(|project://slps/src/transform/library/Test.rsc|, replaceLast(buffer,",","")+");\n\n"+buffer3+"\n\n"+buffer2);
}
diff --git a/shared/rascal/src/transform/NegotiatedXBGF.rsc b/shared/rascal/src/transform/NegotiatedXBGF.rsc
new file mode 100644
index 00000000..f8c01d21
--- /dev/null
+++ b/shared/rascal/src/transform/NegotiatedXBGF.rsc
@@ -0,0 +1,156 @@
+@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
+module transform::NegotiatedXBGF
+
+import IO;
+import syntax::BGF;
+import syntax::XBGF;
+//import diff::GDT;
+import List;
+import String;
+import Integer;
+import normal::BGF;
+import transform::library::Core;
+import transform::library::Util;
+import transform::XBGF;
+
+data Problem
+ = noproblem()
+ | error(str m);
+
+data Advice
+ = noadvice()
+ | setadvice(str s, set[str] a);
+
+public tuple[Problem,Advice,BGFGrammar] attemptTransform(XBGFSequence xbgf, BGFGrammar g)
+{
+ BGFGrammar g1 = normalise(g);
+ Problem p = noproblem();
+ Advice a = noadvice();
+ for (XBGFCommand step <- xbgf)
+ {
+ switch(step)
+ {
+ case abridge(BGFProduction p): g1 = transform::XBGF::runAbridge(p,g1);
+ case abstractize(BGFProduction p): g1 = transform::XBGF::runAbstractize(p,g1);
+ case addH(BGFProduction p): g1 = transform::XBGF::runAddH(p,g1);
+ case addV(BGFProduction p): g1 = transform::XBGF::runAddV(p,g1);
+ case anonymize(BGFProduction p): g1 = transform::XBGF::runAnonymize(p,g1);
+ case appear(BGFProduction p): g1 = transform::XBGF::runAppear(p,g1);
+ case chain(BGFProduction p): g1 = transform::XBGF::runChain(p,g1);
+ case clone(str x, str y, XBGFScope w): g1 = transform::XBGF::runClone(x,y,w,g1);
+ case concatT(list[str] xs, str y, XBGFScope w): g1 = transform::XBGF::runConcatT(xs,y,w,g1);
+ case concretize(BGFProduction p): g1 = transform::XBGF::runConcretize(p,g1);
+ case deanonymize(BGFProduction p): g1 = transform::XBGF::runDeanonymize(p,g1);
+ case define(list[BGFProduction] ps): g1 = transform::XBGF::runDefine(ps,g1);
+ case designate(BGFProduction p): g1 = transform::XBGF::runDesignate(p,g1);
+ case detour(BGFProduction p): g1 = transform::XBGF::runDetour(p,g1);
+ case deyaccify(str x): g1 = transform::XBGF::runDeyaccify(x,g1);
+ case disappear(BGFProduction p): g1 = transform::XBGF::runDisappear(p,g1);
+ case distribute(XBGFScope w): g1 = transform::XBGF::runDistribute(w,g1);
+ case downgrade(BGFProduction p1,BGFProduction p2): g1 = transform::XBGF::runDowngrade(p1,p2,g1);
+ case eliminate(str x): g1 = transform::XBGF::runEliminate(x,g1);
+ case equate(str x, str y): g1 = transform::XBGF::runEquate(x,y,g1);
+ case extract(BGFProduction p, XBGFScope w): g1 = transform::XBGF::runExtract(p,w,g1);
+ case factor(BGFExpression e1, BGFExpression e2, XBGFScope w): g1 = transform::XBGF::runFactor(e1,e2,w,g1);
+ case fold(str x, XBGFScope w): g1 = transform::XBGF::runFold(x,w,g1);
+ case horizontal(XBGFScope w): g1 = transform::XBGF::runHorizontal(w,g1);
+ case importG(list[BGFProduction] ps): g1 = transform::XBGF::runImportG(ps,g1);
+ case inject(BGFProduction p): g1 = transform::XBGF::runInject(p,g1);
+ case inline(str x): g1 = transform::XBGF::runInline(x,g1);
+ case introduce(list[BGFProduction] ps): g1 = transform::XBGF::runIntroduce(ps,g1);
+ case iterate(BGFProduction p): g1 = transform::XBGF::runIterate(p,g1);
+ case lassoc(BGFProduction p): g1 = transform::XBGF::runAssoc(p,g1);
+ case massage(BGFExpression e1, BGFExpression e2, XBGFScope w): g1 = transform::XBGF::runMassage(e1,e2,w,g1);
+ case narrow(BGFExpression e1, BGFExpression e2, XBGFScope w): g1 = transform::XBGF::runNarrow(e1,e2,w,g1);
+ case permute(BGFProduction p): g1 = transform::XBGF::runPermute(p,g1);
+ case project(BGFProduction p): g1 = transform::XBGF::runProject(p,g1);
+ case rassoc(BGFProduction p): g1 = transform::XBGF::runAssoc(p,g1);
+ case redefine(list[BGFProduction] ps): g1 = transform::XBGF::runRedefine(ps,g1);
+ case removeH(BGFProduction p): g1 = transform::XBGF::runRemoveH(p,g1);
+ case removeV(BGFProduction p): g1 = transform::XBGF::runRemoveV(p,g1);
+ case renameL(str x, str y): g1 = transform::XBGF::runRenameL(x,y,g1);
+
+ case renameN(str x, str y): = runRenameN(x,y,g1);
+
+ case renameS(str x, str y, XBGFScope w): g1 = transform::XBGF::runRenameS(x,y,w,g1);
+ case renameT(str x, str y): g1 = transform::XBGF::runRenameT(x,y,g1);
+ case replace(BGFExpression e1, BGFExpression e2, XBGFScope w): g1 = transform::XBGF::runReplace(e1,e2,w,g1);
+ case reroot(list[str] xs): g1 = transform::XBGF::runReroot(xs,g1);
+ case splitN(str x, list[BGFProduction] ps, XBGFScope w): g1 = transform::XBGF::runSplitN(x,ps,w,g1);
+ case splitT(str x, list[str] ys, XBGFScope w): g1 = transform::XBGF::runSplitT(x,ys,w,g1);
+ case unchain(BGFProduction p): g1 = transform::XBGF::runUnchain(p,g1);
+ case undefine(list[str] xs): g1 = transform::XBGF::runUndefine(xs,g1);
+ case unfold(str x, XBGFScope w): g1 = transform::XBGF::runUnfold(x,w,g1);
+ case unite(str x, str y): g1 = transform::XBGF::runUnite(x,y,g1);
+ case unlabel(str x): g1 = transform::XBGF::runUnlabel(x,g1);
+ case upgrade(BGFProduction p1, BGFProduction p2): g1 = transform::XBGF::runUpgrade(p1,p2,g1);
+ case vertical(XBGFScope w): g1 = transform::XBGF::runVertical(w,g1);
+ case widen(BGFExpression e1, BGFExpression e2, XBGFScope w): g1 = transform::XBGF::runWiden(e1,e2,w,g1);
+ case yaccify(list[BGFProduction] ps): g1 = transform::XBGF::runYaccify(ps,g1);
+ case atomic(list[XBGFCommand] steps): g1 = transform::XBGF::runAtomic(steps,g1);
+ case strip(str a): g1 = transform::XBGF::runStrip(a,g1);
+ default: throw "Unknown XBGF command ";
+ }
+ if (noproblem() !:= p)
+ return ;
+ }
+ return ;
+}
+
+tuple[Problem,Advice,BGFGrammar] runRenameN(str x, str y, grammar(rs, ps))
+{
+ ns = allNs(ps);
+ if (x notin ns)
+ return
+ <
+ error("Source name for renaming must not be fresh."),
+ adviseUsedNonterminal(x,allNs(ps)),
+ grammar(rs, ps)
+ >;
+ if (y in ns)
+ return
+ <
+ error("Target name for renaming must be fresh."),
+ adviseFreshNonterminal(y,allNs(ps)),
+ grammar(rs, ps)
+ >;
+ return ;
+}
+
+Advice adviseUsedNonterminal(str x, set[str] nts)
+{
+ int minl = 9000;
+ str mins = "";
+ good = {z | z <- nts, levenshtein(z,x) == min([levenshtein(s,x) | s <- nts])};
+ if (good == {})
+ return noadvice();
+ else
+ return setadvice("Did you mean",good);
+}
+
+Advice adviseFreshNonterminal(str x, set[str] nts)
+{
+ list[str] low = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y"];
+ list[str] upp = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y"];
+ set[str] adv = {};
+ int cx = 1;
+ str s = x;
+ // expr -> expr1
+ while ("" in nts) cx+=1;
+ adv += "";
+ cx = 0;
+ // expr -> expr_
+ while (s in nts) s += "_";
+ adv += s;
+ // expr -> shjk
+ s = "";
+ for (c <- [stringChar(charAt(x,i)) | i <- [0..size(x)-1]])
+ if (c in low)
+ s += low[arbInt(size(low))];
+ elseif (c in upp)
+ s += upp[arbInt(size(upp))];
+ else
+ s += stringChar(c);
+ adv += s;
+ return setadvice("Did you mean",adv);
+}
\ No newline at end of file
diff --git a/shared/rascal/src/transform/XBGF.rsc b/shared/rascal/src/transform/XBGF.rsc
index 8c1a8b27..225bcf10 100644
--- a/shared/rascal/src/transform/XBGF.rsc
+++ b/shared/rascal/src/transform/XBGF.rsc
@@ -8,12 +8,13 @@ import syntax::BGF;
import syntax::XBGF;
import normal::BGF;
import diff::GDT;
-import transform::Associativity;
-import transform::Factoring;
-import transform::Massage;
-import transform::Util;
-import transform::Width;
-import transform::Yacc;
+import transform::library::Associativity;
+import transform::library::Factoring;
+import transform::library::Massage;
+import transform::library::Util;
+import transform::library::Core;
+import transform::library::Width;
+import transform::library::Yacc;
public BGFGrammar transform(XBGFSequence xbgf, BGFGrammar g)
{
@@ -161,7 +162,7 @@ BGFGrammar runAssoc(production(str l, str x, BGFExpression e1), grammar(rs, ps))
{
= splitPbyW(ps,comboscope(inlabel(l),innt(x)));
if ([production(l, x, BGFExpression e2)] := ps2)
- if (transform::Associativity::admit(e1,e2))
+ if (transform::library::Associativity::admit(e1,e2))
return grammar(rs,ps1 + production(l, x, e1) + ps3);
else throw " must admit associativity transformation.";
else throw "Cannot find the right production rule to match in .";
@@ -250,7 +251,7 @@ BGFGrammar runDeyaccify(str n, grammar(rs,ps))
= splitPbyW(ps,innt(n));
if (size(ps2) == 1) throw "Nonterminal must be defined vertically for deyaccification to work.";
if (size(ps2) > 2) throw "No deyaccification patterns for production rules known.";
- return grammar(rs, ps1 + transform::Yacc::deyaccify(toSet(ps2)) + ps3);
+ return grammar(rs, ps1 + transform::library::Yacc::deyaccify(toSet(ps2)) + ps3);
}
BGFGrammar runDisappear(BGFProduction p1, grammar(rs, ps))
@@ -268,7 +269,7 @@ BGFGrammar runDistribute(XBGFScope w, grammar(rs, ps))
{
= splitPbyW(ps,w);
if (/choice(_) !:= ps2) throw "No choices found in the context , nothing to distribute";
- return grammar(rs,ps1 + normalise([transform::Factoring::makeDistributed(p) | p <- ps2]) + ps3);
+ return grammar(rs,ps1 + normalise([transform::library::Factoring::makeDistributed(p) | p <- ps2]) + ps3);
}
BGFGrammar runDowngrade(BGFProduction p1, BGFProduction p2, grammar(rs, ps))
@@ -317,8 +318,8 @@ BGFGrammar runExtract(production(str l, str x, BGFExpression rhs), XBGFScope w,
BGFGrammar runFactor(BGFExpression e1, BGFExpression e2, XBGFScope w, g)
{
- e3 = normalise(transform::Factoring::makeDistributed(e1));
- e4 = normalise(transform::Factoring::makeDistributed(e2));
+ e3 = normalise(transform::library::Factoring::makeDistributed(e1));
+ e4 = normalise(transform::library::Factoring::makeDistributed(e2));
if (!eqE(e3, e4))
throw "Expressions and must be related by distribution.";
return runReplace(e1,e2,w,g);
@@ -388,7 +389,7 @@ BGFGrammar runIterate(production(str l, str x, BGFExpression e1), grammar(rs, ps
{
= splitPbyW(ps,comboscope(inlabel(l),innt(x)));
if ([production(l, x, BGFExpression e2)] := ps2)
- if (transform::Associativity::admit(e2,e1))
+ if (transform::library::Associativity::admit(e2,e1))
return grammar(rs,ps1 + production(l, x, e1) + ps3);
else throw " must admit associativity transformation.";
else throw "Cannot find the right production rule to match in .";
@@ -396,7 +397,7 @@ BGFGrammar runIterate(production(str l, str x, BGFExpression e1), grammar(rs, ps
BGFGrammar runMassage(BGFExpression e1, BGFExpression e2, XBGFScope w, BGFGrammar g)
{
- if (transform::Massage::massage_eq({e1,e2}))
+ if (transform::library::Massage::massage_eq({e1,e2}))
return runReplace(e1,e2,w,g);
else
throw " and are not massage-equivalent.";
@@ -404,7 +405,7 @@ BGFGrammar runMassage(BGFExpression e1, BGFExpression e2, XBGFScope w, BGFGramma
BGFGrammar runNarrow(BGFExpression e1, BGFExpression e2, XBGFScope w, g)
{
- if (!transform::Width::narrowing(e1,e2))
+ if (!transform::library::Width::narrowing(e1,e2))
throw " and are not in narrowing relation.";
return runReplace(e1,e2,w,g);
}
@@ -491,13 +492,8 @@ BGFGrammar runRenameN(str x, str y, grammar(rs, ps))
{
ns = allNs(ps);
if (x notin ns) throw "Source name for renaming must not be fresh.";
- if (y in ns) throw "Target name for renaming must be fresh.";
- = splitPbyW(ps,innt(x));
- list[BGFProduction] ps4 = ps1 + [production(l,y,e) | p <- ps2, production(str l,x,BGFExpression e) := p] + ps3;
- if (x in usedNs(ps4))
- return runReplace(nonterminal(x),nonterminal(y),globally(),grammar(rs,ps4));
- else
- return grammar(rs,ps4);
+ if (y in ns) throw "Target name for renaming must be fresh.";
+ return transform::library::Core::performRenameN(x,y,grammar(rs,ps));
}
BGFGrammar runRenameS(str x, str y, XBGFScope w, grammar(rs, ps))
@@ -517,58 +513,14 @@ BGFGrammar runRenameT(str x, str y, grammar(rs, ps))
return runReplace(terminal(x),terminal(y),globally(),grammar(rs,ps));
}
-list[BGFExpression] replaceSubsequence(list[BGFExpression] where, list[BGFExpression] what, list[BGFExpression] with)
-{
- if (eqE(sequence(where),sequence(what))) return with;
- int i = 0, len = size(what);
- while (i+len<=size(where))
- {
- if (eqE(sequence(slice(where,i,len)),sequence(what)))
- return slice(where,0,i) + with + slice(where,i+len,size(where)-i-len);
- i+=1;
- }
- return where;
-}
-
-list[BGFExpression] replaceChoice(list[BGFExpression] where, list[BGFExpression] what, list[BGFExpression] with)
-{
- if (eqE(choice(where),choice(what))) return with;
- unmatched = where;
- = diff::GDT::tryMatchChoices(what,where);
- if (res)
- return es1 + with + es2;
- else
- return where;
-}
-
-list[BGFProduction] justReplace(BGFExpression e1, BGFExpression e2, list[BGFProduction] ps)
-{
- list[BGFExpression] L5;
- switch(e1)
- {
- case sequence(L1):
- {
- if (sequence(L4) := e2) L5 = L4; else L5 = [e2];
- return visit(ps){case sequence(L2) => sequence(replaceSubsequence(L2,L1,L5))};
- }
- case choice(L1):
- {
- if (choice(L4) := e2) L5 = L4; else L5 = [e2];
- return visit(ps){case choice(L2) => choice(replaceChoice(L2,L1,L5))};
- }
- default:
- return visit(ps){case e1 => e2}
- }
-}
-
BGFGrammar runReplace(BGFExpression e1, BGFExpression e2, XBGFScope w, grammar(rs, ps))
{
list[BGFProduction] ps1,ps2,ps3,ps4;
= splitPbyW(ps,w);
- ps4 = justReplace(e1,e2,ps2);
+ ps4 = transform::library::Core::performReplace(e1,e2,ps2);
if (ps2 == ps4)
{
- ps4 = justReplace(normalise(e1),normalise(e2),ps2); // TODO check if needed
+ ps4 = transform::library::Core::performReplace(normalise(e1),normalise(e2),ps2); // TODO check if needed
if (ps2 == ps4)
throw "Vacuous replace of by in context .";
}
@@ -709,7 +661,7 @@ BGFGrammar runVertical(XBGFScope w, grammar(rs,ps))
BGFGrammar runWiden(BGFExpression e1, BGFExpression e2, XBGFScope w, BGFGrammar g)
{
- if (!transform::Width::narrowing(e2,e1))
+ if (!transform::library::Width::narrowing(e2,e1))
throw " and are not in widening relation.";
return runReplace(e1,e2,w,g);
}
@@ -719,7 +671,7 @@ BGFGrammar runYaccify(list[BGFProduction] ps1, grammar(rs,ps2))
if ({str x} := definedNs(ps1))
{
= splitPbyW(ps2,innt(x));
- if ([dyp1] := ps4 && [yp1,yp2] := ps1 && transform::Yacc::yaccification(dyp1,{yp1,yp2}))
+ if ([dyp1] := ps4 && [yp1,yp2] := ps1 && transform::library::Yacc::yaccification(dyp1,{yp1,yp2}))
return grammar(rs,ps3 + ps1 + ps5);
else
throw " are not suitable as yaccification of .";
diff --git a/shared/rascal/src/transform/Associativity.rsc b/shared/rascal/src/transform/library/Associativity.rsc
similarity index 93%
rename from shared/rascal/src/transform/Associativity.rsc
rename to shared/rascal/src/transform/library/Associativity.rsc
index a062d7a6..30900b41 100644
--- a/shared/rascal/src/transform/Associativity.rsc
+++ b/shared/rascal/src/transform/library/Associativity.rsc
@@ -1,5 +1,5 @@
@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
-module transform::Associativity
+module transform::library::Associativity
import syntax::BGF;
diff --git a/shared/rascal/src/transform/library/Core.rsc b/shared/rascal/src/transform/library/Core.rsc
new file mode 100644
index 00000000..caada1b8
--- /dev/null
+++ b/shared/rascal/src/transform/library/Core.rsc
@@ -0,0 +1,63 @@
+@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
+module transform::library::Core
+
+import syntax::BGF;
+import syntax::XBGF;
+import transform::library::Util;
+import diff::GDT;
+import List; // size
+
+BGFGrammar performRenameN(str x, str y, grammar(rs, ps))
+{
+ list[BGFProduction] ps1,ps2,ps3,ps4;
+ = splitPbyW(ps,innt(x));
+ ps4 = ps1 + [production(l,y,e) | p <- ps2, production(str l,x,BGFExpression e) := p] + ps3;
+ if (x in usedNs(ps4))
+ return grammar(rs,performReplace(nonterminal(x),nonterminal(y),ps4));
+ else
+ return grammar(rs,ps4);
+}
+
+list[BGFProduction] performReplace(BGFExpression e1, BGFExpression e2, list[BGFProduction] ps)
+{
+ list[BGFExpression] L5;
+ switch(e1)
+ {
+ case sequence(L1):
+ {
+ if (sequence(L4) := e2) L5 = L4; else L5 = [e2];
+ return visit(ps){case sequence(L2) => sequence(replaceSubsequence(L2,L1,L5))};
+ }
+ case choice(L1):
+ {
+ if (choice(L4) := e2) L5 = L4; else L5 = [e2];
+ return visit(ps){case choice(L2) => choice(replaceChoice(L2,L1,L5))};
+ }
+ default:
+ return visit(ps){case e1 => e2}
+ }
+}
+
+list[BGFExpression] replaceSubsequence(list[BGFExpression] where, list[BGFExpression] what, list[BGFExpression] with)
+{
+ if (eqE(sequence(where),sequence(what))) return with;
+ int i = 0, len = size(what);
+ while (i+len<=size(where))
+ {
+ if (eqE(sequence(slice(where,i,len)),sequence(what)))
+ return slice(where,0,i) + with + slice(where,i+len,size(where)-i-len);
+ i+=1;
+ }
+ return where;
+}
+
+list[BGFExpression] replaceChoice(list[BGFExpression] where, list[BGFExpression] what, list[BGFExpression] with)
+{
+ if (eqE(choice(where),choice(what))) return with;
+ unmatched = where;
+ = diff::GDT::tryMatchChoices(what,where);
+ if (res)
+ return es1 + with + es2;
+ else
+ return where;
+}
diff --git a/shared/rascal/src/transform/Factoring.rsc b/shared/rascal/src/transform/library/Factoring.rsc
similarity index 95%
rename from shared/rascal/src/transform/Factoring.rsc
rename to shared/rascal/src/transform/library/Factoring.rsc
index c88f68cd..5f19ec66 100644
--- a/shared/rascal/src/transform/Factoring.rsc
+++ b/shared/rascal/src/transform/library/Factoring.rsc
@@ -1,5 +1,5 @@
@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
-module transform::Factoring
+module transform::library::Factoring
import syntax::BGF;
diff --git a/shared/rascal/src/transform/Massage.rsc b/shared/rascal/src/transform/library/Massage.rsc
similarity index 98%
rename from shared/rascal/src/transform/Massage.rsc
rename to shared/rascal/src/transform/library/Massage.rsc
index aa307088..90faca49 100644
--- a/shared/rascal/src/transform/Massage.rsc
+++ b/shared/rascal/src/transform/library/Massage.rsc
@@ -1,5 +1,5 @@
@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
-module transform::Massage
+module transform::library::Massage
import syntax::BGF;
import normal::BGF;
diff --git a/shared/rascal/src/transform/XBGFTest.rsc b/shared/rascal/src/transform/library/Test.rsc
similarity index 99%
rename from shared/rascal/src/transform/XBGFTest.rsc
rename to shared/rascal/src/transform/library/Test.rsc
index 50cedbb1..99562757 100644
--- a/shared/rascal/src/transform/XBGFTest.rsc
+++ b/shared/rascal/src/transform/library/Test.rsc
@@ -1,6 +1,6 @@
@contributor{Super Awesome Automated XBGF Test Suite Synchroniser}
@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
-module transform::XBGFTest
+module transform::library::Test
import IO;
import syntax::BGF;
diff --git a/shared/rascal/src/transform/Util.rsc b/shared/rascal/src/transform/library/Util.rsc
similarity index 85%
rename from shared/rascal/src/transform/Util.rsc
rename to shared/rascal/src/transform/library/Util.rsc
index ca3c68b3..9444e400 100644
--- a/shared/rascal/src/transform/Util.rsc
+++ b/shared/rascal/src/transform/library/Util.rsc
@@ -1,5 +1,5 @@
@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
-module transform::Util
+module transform::library::Util
import syntax::BGF;
import syntax::XBGF;
@@ -7,6 +7,7 @@ import normal::BGF;
import diff::GDT;
import List;
import Set; // toList
+import String; //size
public BGFProduction unmark (BGFProduction p1)
{
@@ -111,3 +112,22 @@ public list[BGFProduction] replaceP(list[BGFProduction] ps, p1, p2)
ps2 += p;
return ps2;
}
+
+public int levenshtein(str x, str y)
+{
+ if (size(x) < size(y)) return levenshtein(y,x);
+ if (x=="") return size(y);
+
+ prow = [0..size(y)];
+ for (i <- [0..size(x)-1])
+ {
+ crow = [i+1];
+ for (j <- [0..size(y)-1])
+ if (charAt(x,i) == charAt(y,j))
+ crow += min([ prow[j+1]+1, crow[j]+1, prow[j] ]);
+ else
+ crow += min([ prow[j+1]+1, crow[j]+1, prow[j]+1 ]);
+ prow = crow;
+ }
+ return prow[size(prow)-1];
+}
diff --git a/shared/rascal/src/transform/Width.rsc b/shared/rascal/src/transform/library/Width.rsc
similarity index 93%
rename from shared/rascal/src/transform/Width.rsc
rename to shared/rascal/src/transform/library/Width.rsc
index 3c797169..08b61ee4 100644
--- a/shared/rascal/src/transform/Width.rsc
+++ b/shared/rascal/src/transform/library/Width.rsc
@@ -1,5 +1,5 @@
@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
-module transform::Width
+module transform::library::Width
import syntax::BGF;
diff --git a/shared/rascal/src/transform/Yacc.rsc b/shared/rascal/src/transform/library/Yacc.rsc
similarity index 98%
rename from shared/rascal/src/transform/Yacc.rsc
rename to shared/rascal/src/transform/library/Yacc.rsc
index 64719665..d39b216a 100644
--- a/shared/rascal/src/transform/Yacc.rsc
+++ b/shared/rascal/src/transform/library/Yacc.rsc
@@ -1,5 +1,5 @@
@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
-module transform::Yacc
+module transform::library::Yacc
import syntax::BGF;