Skip to content

Commit

Permalink
code reengineered but not yet tested
Browse files Browse the repository at this point in the history
  • Loading branch information
grammarware committed Jan 10, 2013
1 parent 55f7c7d commit 5480aa7
Show file tree
Hide file tree
Showing 16 changed files with 150 additions and 207 deletions.
3 changes: 1 addition & 2 deletions shared/rascal/src/transform/XBGF.rsc
Expand Up @@ -160,7 +160,6 @@ public XBGFResult vtransform(XBGFCommand x, BGFGrammar g)
// legacy code
XBGFResult runStrip(str a, BGFGrammar g)
{
XBGFOutcome r = ok();
// TODO: semi-deprecated
list[BGFProduction] ps2;
if (a=="allLabels")
Expand All @@ -174,5 +173,5 @@ XBGFResult runStrip(str a, BGFGrammar g)
}
else
return <problemStr("Unknown strip parameter",a),g>;
return <r,grammar(g.roots,ps2)>;
return <ok(),grammar(g.roots,ps2)>;
}
6 changes: 2 additions & 4 deletions shared/rascal/src/transform/library/Associativity.rsc
Expand Up @@ -21,11 +21,10 @@ XBGFResult runLAssoc(BGFProduction p, BGFGrammar g) = runAssoc(p,g);

XBGFResult runAssoc(production(str l, str x, BGFExpression e1), BGFGrammar g)
{
XBGFOutcome r = ok();
<ps1,ps2,ps3> = splitPbyW(g.prods,comboscope(inlabel(l),innt(x)));
if ([production(l, x, BGFExpression e2)] := ps2)
if (admit(e1,e2))
return <r,grammar(g.roots,ps1 + production(l, x, e1) + ps3)>;
return <ok(),grammar(g.roots,ps1 + production(l, x, e1) + ps3)>;
else
return <problemProd("Production rule must admit associativity transformation",production(l,x,e1)),g>;
else
Expand All @@ -34,11 +33,10 @@ XBGFResult runAssoc(production(str l, str x, BGFExpression e1), BGFGrammar g)

XBGFResult runIterate(production(str l, str x, BGFExpression e1), BGFGrammar g)
{
XBGFOutcome r = ok();
<ps1,ps2,ps3> = splitPbyW(g.prods,comboscope(inlabel(l),innt(x)));
if ([production(l, x, BGFExpression e2)] := ps2)
if (admit(e2,e1))
return <r,grammar(g.roots,ps1 + production(l, x, e1) + ps3)>;
return <ok(),grammar(g.roots,ps1 + production(l, x, e1) + ps3)>;
else
return <problemProd("Production rule must admit associativity transformation",production(l,x,e1)),g>;
else
Expand Down
5 changes: 2 additions & 3 deletions shared/rascal/src/transform/library/Brutal.rsc
Expand Up @@ -11,17 +11,16 @@ import diff::GDT;

XBGFResult runReplace(BGFExpression e1, BGFExpression e2, XBGFScope w, BGFGrammar g)
{
XBGFOutcome r = ok();
list[BGFProduction] ps1,ps2,ps3,ps4;
<ps1,ps2,ps3> = splitPbyW(g.prods, w);
ps4 = performReplace(e1,e2,ps2);
if (ps2 == ps4)
{
ps4 = performReplace(normalise(e1),normalise(e2),ps2); // TODO check if needed
if (ps2 == ps4)
r = add(r,problemExpr2("Vacuous replace",e1,e2));
return <problemExpr2("Vacuous replace",e1,e2),g>;
}
return <r,grammar(g.roots, ps1 + normalise(ps4) + ps3)>;
return <ok(),grammar(g.roots, ps1 + normalise(ps4) + ps3)>;
}

list[BGFProduction] performReplace(BGFExpression e1, BGFExpression e2, list[BGFProduction] ps)
Expand Down
36 changes: 16 additions & 20 deletions shared/rascal/src/transform/library/Chaining.rsc
Expand Up @@ -11,74 +11,70 @@ import diff::GDT;

XBGFResult runAbridge(BGFProduction p, BGFGrammar g)
{
XBGFOutcome r = ok();
if (production(_,x,nonterminal(x)) !:= p)
r = add(r,problemProd("Production cannot be abridged.",p));
return <problemProd("Production cannot be abridged.",p),g>;
if (!inProds(p,g.prods))
r = notFoundP(r,p);
return <r,grammar(g.roots, g.prods - p)>;
return <notFoundP(p),g>;
return <ok(),grammar(g.roots, g.prods - p)>;
}

XBGFResult runChain(BGFProduction p, BGFGrammar g)
{
XBGFOutcome r = ok();
if (production(str l,str n1,nonterminal(str n2)) := p)
{
if (n1 == n2)
r = add(r,problem("Do not introduce reflexive chain productions with chain, use detour instead"));
return <problem("Do not introduce reflexive chain productions with chain, use detour instead"),g>;
if (n2 in allNs(g.prods))
r = add(r,problemStr("Nonterminal must be fresh",n2));
return <notFreshName(n2),g>;
list[BGFProduction] ps1,ps2,ps3;
if (l != "") <ps1,ps2,ps3> = splitPbyW(g.prods,inlabel(l));
else <ps1,ps2,ps3> = splitPbyW(g.prods,innt(n1));
if ([production(l,n1,e)] := ps2)
return <r,grammar(g.roots, ps1 + p + production("",n2,e) + ps3)>;
return <ok(),grammar(g.roots, ps1 + p + production("",n2,e) + ps3)>;
else
return <add(r,problemProds("Production rule has unexpected form",ps2)),g>;
return <problemProds("Production rule has unexpected form",ps2),g>;
}
else
return <problemProd("Not a chain production rule.",p),g>;
}

XBGFResult runDetour(BGFProduction p, BGFGrammar g)
{
XBGFOutcome r = ok();
if (production(_,x,nonterminal(x)) := p)
{
// xbgf1.pro only aksed for x to be used, not necessarily defined; we're more strict here
if (x notin definedNs(g.prods))
r = freshN(r,x);
return <freshN(r,x),g>;
<ps1,ps2,ps3> = splitPbyW(g.prods,innt(x));
return <r,grammar(g.roots, ps1 + ps2 + p + ps3)>;
return <ok(),grammar(g.roots, ps1 + ps2 + p + ps3)>;
}
else
return <problemProd("Not a reflexive chain production rule",p),g>;
}

XBGFResult runUnchain(BGFProduction p, BGFGrammar g)
{
XBGFOutcome r = ok();
if (production(str l,str n1,nonterminal(str n2)) := p)
{
if (n1 == n2)
r = add(r,problem("Do not remove reflexive chain productions with chain, use abridge instead"));
return <problem("Do not remove reflexive chain productions with chain, use abridge instead"),g>;
if (n2 in g.roots)
r = add(r,problemStr("Nonterminal must not be root",n2));
return <problemStr("Nonterminal must not be root",n2),g>;
if (!inProds(p,g.prods))
r = notFoundP(r,p);
return <notFoundP(r,p),g>;
//if (n2 in allNs(ps)) r = notFreshN(r,n2);
list[BGFProduction] ps1,ps2,ps3;
<ps1,ps2,ps3> = splitPbyW(g.prods - p,innt(n2));
if (len(ps2) != 1)
r = add(r,problemStr("Nonterminal must occur exactly once",n2));
return <problemStr("Nonterminal must occur exactly once",n2),g>;
if (l == "")
l = n2;
if ([production(_,n2,e)] := ps2)
return <r,grammar(g.roots, ps1 + production(l,n1,e) + ps3)>;
return <ok(),grammar(g.roots, ps1 + production(l,n1,e) + ps3)>;
else
return <add(r,problemProds("Production rules have unexpected form",ps2)),g>;
return <problemProds("Production rules have unexpected form",ps2),g>;
}
else
return <add(r,problemProd("Not a chain production rule",p)),g>;
return <problemProd("Not a chain production rule",p),g>;
}

10 changes: 4 additions & 6 deletions shared/rascal/src/transform/library/Factoring.rsc
Expand Up @@ -11,21 +11,19 @@ import transform::library::Brutal;

XBGFResult runFactor(BGFExpression e1, BGFExpression e2, XBGFScope w, g)
{
XBGFOutcome r = ok();
e3 = normalise(transform::library::Factoring::makeDistributed(e1));
e4 = normalise(transform::library::Factoring::makeDistributed(e2));
if (!eqE(e3, e4))
r = problemExpr2("Expressions must be related by distribution.",e1,e2);
return add(r,transform::library::Brutal::runReplace(e1,e2,w,g));
return <problemExpr2("Expressions must be related by distribution.",e1,e2),g>;
return transform::library::Brutal::runReplace(e1,e2,w,g);
}

XBGFResult runDistribute(XBGFScope w, BGFGrammar g)
{
XBGFOutcome r = ok();
<ps1,ps2,ps3> = splitPbyW(g.prods,w);
if (/choice(_) !:= ps2)
r = add(r,problemScope("No choices found, nothing to distribute",w));
return <r,grammar(g.roots, ps1 + normalise([makeDistributed(p) | p <- ps2]) + ps3)>;
return <problemScope("No choices found, nothing to distribute",w),g>;
return <ok(),grammar(g.roots, ps1 + normalise([makeDistributed(p) | p <- ps2]) + ps3)>;
}
BGFProduction makeDistributed(production(str l, str x, BGFExpression e)) = production(l, x, makeDistributed(e));
Expand Down
21 changes: 8 additions & 13 deletions shared/rascal/src/transform/library/Folding.rsc
Expand Up @@ -11,50 +11,46 @@ import transform::library::Brutal;

XBGFResult runExtract(production(str l, str x, BGFExpression rhs), XBGFScope w, grammar(rs,ps))
{
XBGFOutcome r = ok();
if (x in definedNs(ps))
r = notFreshN(r,x);
return <notFreshN(x),g>;
// TODO hard to check if rhs occurs in the grammar; it was somehow done in xbgf1.pro
XBGFResult rep = transform::library::Brutal::runReplace(rhs,nonterminal(x),w,grammar(rs,ps));
return <add(r,rep.r),grammar(rep.g.roots,rep.g.prods + production(l,x,rhs))>;
if (ok() !:= rep.r) return rep;
else return <ok(),grammar(rep.g.roots,rep.g.prods + production(l,x,rhs))>;
}

XBGFResult runFold(str x, XBGFScope w, BGFGrammar g)
{
XBGFOutcome r = ok();
if (<_,[production(_, x, BGFExpression rhs)],_> := splitPbyW(g.prods,innt(x)))
return add(r,transform::library::Brutal::runReplace(rhs,nonterminal(x),comboscope(notinnt(x),w),g));
return transform::library::Brutal::runReplace(rhs,nonterminal(x),comboscope(notinnt(x),w),g);
else
return <problemStr("Nonterminal must be defined horizontally prior to folding.",x),g>;
}

XBGFResult runInline(str x, BGFGrammar g)
{
XBGFOutcome r = ok();
if (<ps1,[production(_, x, BGFExpression rhs)],ps2> := splitPbyW(g.prods,innt(x)))
return add(r,transform::library::Brutal::runReplace(nonterminal(x),rhs,globally(),grammar(g.roots,ps1+ps2)));
return transform::library::Brutal::runReplace(nonterminal(x),rhs,globally(),grammar(g.roots,ps1+ps2));
else
return <problemStr("Nonterminal must be defined horizontally prior to inlining.",x),g>;
}

XBGFResult runUnfold(str x, XBGFScope w, BGFGrammar g)
{
XBGFOutcome r = ok();
if (<_,[production(_, x, BGFExpression rhs)],_> := splitPbyW(g.prods,innt(x)))
return add(r,transform::library::Brutal::runReplace(nonterminal(x),rhs,comboscope(notinnt(x),w),g));
return transform::library::Brutal::runReplace(nonterminal(x),rhs,comboscope(notinnt(x),w),g);
else
return <problemStr("Nonterminal must be defined horizontally prior to unfolding.",x),g>;
}

// Liberal forms of folding
XBGFResult runDowngrade(BGFProduction p1, BGFProduction p2, grammar(rs, ps))
{
XBGFOutcome r = ok();
if (/marked(nonterminal(str x)) := p1)
if (production(str l,x,BGFExpression e) := p2)
{
p3 = visit(p1){case marked(_) => e};
return <r,grammar(rs,replaceP(ps,unmark(p1),normalise(p3)))>;
return <ok(),grammar(rs,replaceP(ps,unmark(p1),normalise(p3)))>;
}
else
return <problemProd2("Production rules do not agree on nonterminal",p1,p2),g>;
Expand All @@ -64,13 +60,12 @@ XBGFResult runDowngrade(BGFProduction p1, BGFProduction p2, grammar(rs, ps))
XBGFResult runUpgrade(BGFProduction p1, BGFProduction p2, BGFGrammar g)
{
XBGFOutcome r = ok();
if (/marked(nonterminal(str x)) := p1)
if (production(str l,x,BGFExpression e) := p2)
{
p3 = visit(p1){case marked(_) => e};
p3 = normalise(p3);
return <r,grammar(g.roots,replaceP(g.prods,p3,unmark(p1)))>;
return <ok(),grammar(g.roots,replaceP(g.prods,p3,unmark(p1)))>;
}
else
return <problemProd2("Production rules do not agree on nonterminal",p1,p2),g>;
Expand Down
20 changes: 8 additions & 12 deletions shared/rascal/src/transform/library/Intermittent.rsc
Expand Up @@ -9,17 +9,15 @@ import transform::library::Util;

XBGFResult runAddH(BGFProduction p1, BGFGrammar g)
{
XBGFOutcome r = ok();
p2 = unmark(p1);
p3 = demarkH(p1);
if (!inProds(p3,g.prods))
r = notFoundP(r,p3);
return <r,grammar(g.roots, replaceP(g.prods,p3,p2))>;
return <notFoundP(p3),g>;
return <ok(),grammar(g.roots, replaceP(g.prods,p3,p2))>;
}

XBGFResult runHorizontal(XBGFScope w, BGFGrammar g)
{
XBGFOutcome r = ok();
// For xbgf1.pro, the context must be strictly vertical. Here we are more relaxed.
<ps1,ps2,ps3> = splitPbyW(g.prods,w);
list[BGFExpression] es4 = [];
Expand All @@ -31,37 +29,35 @@ XBGFResult runHorizontal(XBGFScope w, BGFGrammar g)
else
es4 += selectable(l,e);
if (innt(str x) := w)
return <r,grammar(g.roots,ps1 + production("",x,choice(es4)) + ps3)>;
return <ok(),grammar(g.roots,ps1 + production("",x,choice(es4)) + ps3)>;
else
return <problemScope("Scope for horizontal must be a nonterminal",w),g>;
}

XBGFResult runRemoveH(BGFProduction p1, BGFGrammar g)
{
XBGFOutcome r = ok();
p2 = unmark(p1);
if (!inProds(p2, g.prods))
r = notFoundP(r,p2);
return <r,grammar(g.roots, replaceP(g.prods,p2,demarkH(p1)))>;
return <notFoundP(p2),g>;
return <ok(),grammar(g.roots, replaceP(g.prods,p2,demarkH(p1)))>;
}

XBGFResult runVertical(XBGFScope w, BGFGrammar g)
{
XBGFOutcome r = ok();
<ps1,ps2,ps3> = splitPbyW(g.prods, w);
ps4 = [];
for (production(str l, str x, BGFExpression e) <- ps2)
if (choice(L) := e)
for (se <- L)
if (selectable(str s, BGFExpression e2) := se)
if (/production(s,_,_) := g.prods)
r = add(r,problemStr("Outermost selector clashes with an existing label",s));
return <problemStr("Outermost selector clashes with an existing label",s),g>;
elseif (/production(s,_,_) := ps4)
r = add(r,problemStr("Outermost selectors ambiguous",s));
return <problemStr("Outermost selectors ambiguous",s),g>;
else
ps4 += production(s,x,e2);
else
ps4 += production("",x,se);
else ps4 += production(l,x,e);
return <r,grammar(g.roots, ps1 + ps4 + ps3)>;
return <ok(),grammar(g.roots, ps1 + ps4 + ps3)>;
}

0 comments on commit 5480aa7

Please sign in to comment.