Skip to content

Commit

Permalink
cleanup & modularisation
Browse files Browse the repository at this point in the history
  • Loading branch information
grammarware committed Jun 4, 2012
1 parent adb3f81 commit e2e6bf1
Show file tree
Hide file tree
Showing 8 changed files with 324 additions and 374 deletions.
6 changes: 0 additions & 6 deletions shared/rascal/src/diff/GDT.rsc
Expand Up @@ -13,15 +13,11 @@ tuple[bool,list[BGFExpression],list[BGFExpression]] tryMatchChoices(list[BGFExpr
tuple[bool,list[BGFExpression],list[BGFExpression]] tryMatchChoices(list[BGFExpression] es1, list[BGFExpression] L1, list[BGFExpression] es2, [], bool hit) = <false,[],[]>;
tuple[bool,list[BGFExpression],list[BGFExpression]] tryMatchChoices(list[BGFExpression] es1, list[BGFExpression] L1, list[BGFExpression] es2, list[BGFExpression] L2, bool hit)
{
println("tryMatchChoices(<es1>,<L1>,<es2>,<L2>,<hit>");
for (y <- L2)
{
for (x <- L1)
if (eqE(x,y))
{
println("-\> tryMatchChoices(<es1>,<L1-x>,<es2>,<L2-y>,true");
return tryMatchChoices(es1,L1-x,es2,L2-y,true);
}
if (hit)
es2 += y;
else
Expand All @@ -36,11 +32,9 @@ tuple[bool,list[BGFExpression],list[BGFExpression]] tryMatchChoices(list[BGFExpr
public bool eqE(choice([BGFExpression e1]), choice([BGFExpression e2])) = eqE(e1,e2);
public bool eqE(choice(L1), choice(L2))
{
//println("We\'re at eqE with:\n <L1>\nvs\n <L2>...");
for (x <- L1, y <- L2)
if (eqE(x,y))
return eqE(choice(L1 - x), choice(L2 - y));
//println("Unmatched <L1> with <L2> :(");
return false;
}
public bool eqE(sequence(L1), sequence(L2))
Expand Down
12 changes: 12 additions & 0 deletions shared/rascal/src/transform/Associativity.rsc
@@ -0,0 +1,12 @@
@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
module transform::Associativity

import syntax::BGF;

bool admit(sequence([nonterminal(n),nonterminal(x),nonterminal(n)]),
sequence([nonterminal(n),star(sequence([nonterminal(x),nonterminal(n)]))])) = true;
bool admit(sequence([nonterminal(n),nonterminal(x),nonterminal(n)]),
sequence([star(sequence([nonterminal(n),nonterminal(x)])),nonterminal(n)])) = true;
bool admit(sequence([nonterminal(n),nonterminal(n)]),
plus(nonterminal(n))) = true;
default bool admit(BGFExpression e1, BGFExpression e2) = false;
43 changes: 43 additions & 0 deletions shared/rascal/src/transform/Factoring.rsc
@@ -0,0 +1,43 @@
@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
module transform::Factoring

import syntax::BGF;

BGFProduction makeDistributed(production(str l, str x, BGFExpression e)) = production(l, x, makeDistributed(e));

BGFExpression makeDistributed(BGFExpression e1)
{
if (choice(L1) := e1) // excessive normalisation
{
list[BGFExpression] Ln = [];
for (e2 <- L1)
{
e3 = makeDistributed(e2);
if (choice(L2) := e3)
Ln += L2;
else
Ln += e2; // TODO or e3?
}
return choice(Ln);
}
elseif (sequence(L1) := e1)
{
list[list[BGFExpression]] Ln = [[]];
for (e2 <- L1)
{
e3 = makeDistributed(e2);
if (choice(L2) := e3)
{
Lm = [];
for (e4 <- L2)
Lm += [Li + e4 | Li <- Ln];
Ln = Lm;
}
else
Ln = [Li + e3 | Li <- Ln]; // TODO or e2?
}
return choice([sequence(Li) | Li <- Ln]);
}
else
return e1;
}
68 changes: 68 additions & 0 deletions shared/rascal/src/transform/Massage.rsc
@@ -0,0 +1,68 @@
@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
module transform::Massage

import syntax::BGF;
import normal::BGF;
import diff::GDT;
import List;

bool massage_eq({selectable(_,x),x}) = true; // deprecated, please use anonymize/deanonymize instead!
bool massage_eq({optional(selectable(s,x)),selectable(s,optional(x))}) = true;
bool massage_eq({star(selectable(s,x)),selectable(s,star(x))}) = true;
bool massage_eq({plus(selectable(s,x)),selectable(s,plus(x))}) = true;

bool massage_eq({optional(optional(x)),optional(x)}) = true;
bool massage_eq({optional(star(x)),star(x)}) = true;
bool massage_eq({optional(plus(x)),star(x)}) = true;
bool massage_eq({star(optional(x)),star(x)}) = true;
bool massage_eq({star(star(x)),star(x)}) = true;
bool massage_eq({star(plus(x)),star(x)}) = true;
bool massage_eq({plus(optional(x)),star(x)}) = true;
bool massage_eq({plus(star(x)),star(x)}) = true;
bool massage_eq({plus(plus(x)),plus(x)}) = true;

bool massage_eq({sequence([star(x),star(x)]),star(x)}) = true;
bool massage_eq({sequence([optional(x),star(x)]),star(x)}) = true;
bool massage_eq({sequence([star(x),optional(x)]),star(x)}) = true;
bool massage_eq({sequence([optional(x),plus(x)]),plus(x)}) = true;
bool massage_eq({sequence([plus(x),optional(x)]),plus(x)}) = true;
bool massage_eq({sequence([plus(x),star(x)]),plus(x)}) = true;
bool massage_eq({sequence([star(x),plus(x)]),plus(x)}) = true;
bool massage_eq({sequence([x,star(x)]),plus(x)}) = true;
bool massage_eq({sequence([star(x),x]),plus(x)}) = true;
// separator lists
bool massage_eq({sequence([x,optional(sequence([y,x]))]),sequence([optional(sequence([x,y])),x])}) = true;
bool massage_eq({sequence([x,plus(sequence([y,x]))]),sequence([plus(sequence([x,y])),x])}) = true;
bool massage_eq({sequence([x,star(sequence([y,x]))]),sequence([star(sequence([x,y])),x])}) = true;
bool massage_eq({sequence([x,star(sequence([y,x]))]),seplistplus(x,y)}) = true;
bool massage_eq({sequence([star(sequence([x,y])),x]),seplistplus(x,y)}) = true;
bool massage_eq({optional(sequence([x,star(sequence([y,x]))])),sepliststar(x,y)}) = true;
bool massage_eq({optional(sequence([star(sequence([x,y])),x])),sepliststar(x,y)}) = true;
bool massage_eq({optional(seplistplus(x,y)),sepliststar(x,y)}) = true;

default bool massage_eq(set[BGFExpression] s)
{
// some of the following are not general enough

if ({choice(L),z} := s)
{
if (optional(x) := z)
{
if ((x in L || optional(x) in L) && epsilon() in L) return true;
if ({optional(x),x} := toSet(L)) return true;
}
if (star(x) := z)
{
if ((star(x) in L || plus(x) in L) && epsilon() in L) return true;
if ({star(x),x} := toSet(L)) return true;
if ({star(x),optional(x)} := toSet(L)) return true;
if ({star(x),plus(x)} := toSet(L)) return true;
if ({plus(x),optional(x)} := toSet(L)) return true;
}
if (plus(x) := z, {plus(x),x} := toSet(L)) return true;

L1 = visit(L){case selectable(_,BGFExpression e) => e};
if (eqE(normalise(choice(L1)),z)) return true;
}
return false;
}
113 changes: 113 additions & 0 deletions shared/rascal/src/transform/Util.rsc
@@ -0,0 +1,113 @@
@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
module transform::Util

import syntax::BGF;
import syntax::XBGF;
import normal::BGF;
import diff::GDT;
import List;
import Set; // toList

public BGFProduction unmark (BGFProduction p1)
{
if (/marked(_) !:= p1)
throw "<p1> must contain markers.";
p2 = innermost visit(p1)
{
case marked(BGFExpression e) => e
};
//return normalise(p2);
return p2;
}
public BGFProduction demark (BGFProduction p1)
{
if (/marked(_) !:= p1)
throw "<p1> must contain markers.";
p2 = innermost visit(p1)
{
case sequence([L1*,marked(BGFExpression e),L2*]) => sequence(L1 + L2)
case choice([L1*,marked(BGFExpression e),L2*]) => choice(L1 + L2)
}
//return normalise(p2);
return p2;
}

public BGFProduction replaceMarker (BGFProduction p1, BGFExpression e)
{
p2 = visit(p1)
{
case marked(_) => e
}
return normalise(p2);
}

// remove selectors from marked subexpressions
public BGFProduction demarkS (BGFProduction p1)
{
if (/marked(_) !:= p1)
throw "<p1> must contain markers.";
p2 = innermost visit(p1)
{
case marked(selectable(str selector, BGFExpression expr)) => expr
}
return normalise(p2);
}
public bool checkScope(BGFProduction p, XBGFScope w)
{
switch(w)
{
case globally(): return true;
case nowhere(): return false;
case innt(x): return production(_,x,_) := p;
case notinnt(x): return production(_,x,_) !:= p;
case inlabel(x): return production(x,_,_) := p;
case notinlabel(x): return production(x,_,_) !:= p;
case comboscope(w1,w2): return checkScope(p,w1) && checkScope(p,w2);
default: throw "Unknown context <w>.";
}
}
// order-preserving splitting of production rules
// returns <prods before context; prods in context; prods after context>
public tuple[list[BGFProduction],list[BGFProduction],list[BGFProduction]] splitPbyW(list[BGFProduction] ps, XBGFScope w)
{
if (globally() := w)
return <[],ps,[]>;
if (nowhere() := w)
throw "Splitting by empty scope!";
if (inlabel(str x) := w && x == "")
throw "Empty label is not a proper scope.";
bool hit = false;
list[BGFProduction] ps1 = [], ps2 = [], ps3 = [];
for (p <- ps)
if (checkScope(p,w))
{
hit = true;
ps2 += p;
}
elseif (hit)
ps3 += p;
else
ps1 += p;
if (isEmpty(ps2))
throw "Scope <w> not found.";
return <ps1,ps2,ps3>;
}
public set[str] allNs(list[BGFProduction] ps) = definedNs(ps) + usedNs(ps);
public set[str] allTs(list[BGFProduction] ps) = {s | /terminal(str s) := ps};
public set[str] usedNs(list[BGFProduction] ps) = {s | /nonterminal(str s) := ps};
public set[str] definedNs(list[BGFProduction] ps) = {s | production(_,str s,_) <- ps};
public list[BGFProduction] replaceP(list[BGFProduction] ps, p1, p2)
{
list[BGFProduction] ps2 = [];
for (p <- ps)
if (eqP(normalise(p),normalise(p1)))
ps2 += p2;
else
ps2 += p;
return ps2;
}
13 changes: 13 additions & 0 deletions shared/rascal/src/transform/Width.rsc
@@ -0,0 +1,13 @@
@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
module transform::Width

import syntax::BGF;

// narrow-equivalence (the reverse, widen-equivalence, is hereby also implicitly defined)
bool narrowing(anything(),_) = true;
bool narrowing(star(e),plus(e)) = true;
bool narrowing(star(e),optional(e)) = true;
bool narrowing(star(e),e) = true;
bool narrowing(plus(e),e) = true;
bool narrowing(optional(e),e) = true;
default bool narrowing(_,_) = false;

0 comments on commit e2e6bf1

Please sign in to comment.