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;