Skip to content

Commit

Permalink
reading XBGF in Rascal works for all existing XBGF files
Browse files Browse the repository at this point in the history
  • Loading branch information
grammarware committed Jun 1, 2012
1 parent 921d8c4 commit 98cdd59
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 51 deletions.
163 changes: 123 additions & 40 deletions shared/rascal/src/XBGF.rsc
@@ -1,3 +1,4 @@
@contributor{Vadim Zaytsev - vadim@grammarware.net - CWI}
module XBGF

import IO;
Expand All @@ -6,31 +7,128 @@ import lang::xml::DOM;

public void main()
{
Node N = parseXMLDOMTrim(readFile(|project://xbgf/tests/long.xbgf|));
println(readXBGF(|project://xbgf/tests/undefine1.xbgf|));
}

public bool tryAll()
{
loc base = |project://xbgf/tests|;
for (f <- listEntries(base))
{
if (f == ".gitignore") continue;
println(f);
println(readXBGF(base+f));
}
return true;
}


public XBGFSequence readXBGF(loc f)
{
Node N = parseXMLDOMTrim(readFile(f));
XBGFSequence xbgfs = [];
//XBGFCommand x;
if (document(element(namespace(_,"http://planet-sl.org/xbgf"),"sequence",L)) := N)
for (el <- L)
if (element(namespace(_,"http://planet-sl.org/xbgf"),_,_) := el)
return [mapxbgf(element(namespace("xbgf","http://planet-sl.org/xbgf"),name,kids)) | element(namespace(_,"http://planet-sl.org/xbgf"),name,kids) <- L];
}

XBGFCommand mapxbgf(Node el)
{
if (element(namespace(_,"http://planet-sl.org/xbgf"),_,_) := el)
{
switch(el)
{
switch(el)
{
case element(_,"abridge",[prod]): xbgfs += abridge(mapprod(prod));
case element(_,"add",[element(none(),"vertical",[prod])]): xbgfs += addV(mapprod(prod));
case element(_,"narrow",[e1,e2]): xbgfs += narrow(mapexpr(e1),mapexpr(e2),globally());
case element(_,"narrow",[e1,e2,w]): xbgfs += narrow(mapexpr(e1),mapexpr(e2),mapcontext(w));
case element(_,"replace",[e1,e2]): xbgfs += replace(mapexpr(e1),mapexpr(e2),globally());
case element(_,"replace",[e1,e2,w]): xbgfs += replace(mapexpr(e1),mapexpr(e2),mapcontext(w));
case element(_,"yaccify",[p1,p2]): xbgfs += yaccify(mapprod(p1),mapprod(p2));
// default
case element(_,elname,elkids):
{
println(elname);
println(elkids);
}
}
case element(_,"abridge",[prod]): return abridge(mapprod(prod));
case element(_,"abstractize",[prod]): return abstractize(mapprod(prod));
case element(_,"add",[element(none(),"horizontal",[prod])]): return addH(mapprod(prod));
case element(_,"add",[element(none(),"vertical",[prod])]): return addV(mapprod(prod));
case element(_,"anonymize",[prod]): return anonymize(mapprod(prod));
case element(_,"appear",[prod]): return appear(mapprod(prod));
case element(_,"chain",[prod]): return chain(mapprod(prod));
// clone(str x, str y, BGFContext w)
// concatT(list[str] xs, str y, BGFContext w)
case element(_,"concretize",[prod]): return concretize(mapprod(prod));
case element(_,"deanonymize",[prod]): return deanonymize(mapprod(prod));
case element(_,"define",ps): return define([mapprod(p) | p <- ps]);
case element(_,"designate",[prod]): return designate(mapprod(prod));
case element(_,"detour",[prod]): return detour(mapprod(prod));
case element(_,"deyaccify",[element(none(),"nonterminal",[charData(str s)])]): return deyaccify(s);
case element(_,"disappear",[prod]): return disappear(mapprod(prod));
case element(_,"distribute",[w]): return distribute(mapcontext(w));
case element(_,"downgrade",[p1,p2]): return downgrade(mapprod(p1),mapprod(p2));
case element(_,"eliminate",[element(none(),"nonterminal",[charData(str s)])]): return eliminate(s);
case element(_,"equate",[element(none(),"align",[charData(str s1)]),element(none(),"with",[charData(str s2)])]): return equate(s1,s2);
case element(_,"extract",[prod]): return extract(mapprod(prod),globally());
case element(_,"extract",[prod,w]): return extract(mapprod(prod),mapcontext(w));
case element(_,"factor",[e1,e2]): return factor(mapexpr(e1),mapexpr(e2),globally());
case element(_,"factor",[e1,e2,w]): return factor(mapexpr(e1),mapexpr(e2),mapcontext(w));
case element(_,"fold",[element(none(),"nonterminal",[charData(str s)])]): return fold(s,globally());
case element(_,"fold",[element(none(),"nonterminal",[charData(str s)]),w]): return fold(s,mapcontext(w));
case element(_,"horizontal",[w]): return horizontal(mapcontext(w));
case element(_,"import",ps): return \import([mapprod(p) | p <- ps]);
case element(_,"inject",[prod]): return inject(mapprod(prod));
case element(_,"inline",[charData(str s)]): return inline(s);
case element(_,"introduce",ps): return introduce([mapprod(p) | p <- ps]);
case element(_,"iterate",[prod]): return iterate(mapprod(prod));
case element(_,"lassoc",[prod]): return lassoc(mapprod(prod));
case element(_,"massage",[e1,e2]): return massage(mapexpr(e1),mapexpr(e2),globally());
case element(_,"massage",[e1,e2,w]): return massage(mapexpr(e1),mapexpr(e2),mapcontext(w));
case element(_,"narrow",[e1,e2]): return narrow(mapexpr(e1),mapexpr(e2),globally());
case element(_,"narrow",[e1,e2,w]): return narrow(mapexpr(e1),mapexpr(e2),mapcontext(w));
case element(_,"permute",[prod]): return permute(mapprod(prod));
case element(_,"project",[prod]): return project(mapprod(prod));
case element(_,"rassoc",[prod]): return rassoc(mapprod(prod));
case element(_,"redefine",ps): return redefine([mapprod(p) | p <- ps]);
case element(_,"remove",[element(none(),"horizontal",[prod])]): return removeH(mapprod(prod));
case element(_,"remove",[element(none(),"vertical",[prod])]): return removeV(mapprod(prod));
case element(_,"rename",[element(none(),"label",[element(none(),"from",[charData(str s1)]),element(none(),"to",[charData(str s2)])])]): return renameL(s1, s2, globally());
case element(_,"rename",[element(none(),"label",[element(none(),"from",[charData(str s1)]),element(none(),"to",[charData(str s2)]),w])]): return renameL(s1, s2, mapcontext(w));
case element(_,"rename",[element(none(),"nonterminal",[element(none(),"from",[charData(str s1)]),element(none(),"to",[charData(str s2)])])]): return renameN(s1, s2, globally());
case element(_,"rename",[element(none(),"nonterminal",[element(none(),"from",[charData(str s1)]),element(none(),"to",[charData(str s2)]),w])]): return renameN(s1, s2, mapcontext(w));
case element(_,"rename",[element(none(),"selector",[element(none(),"from",[charData(str s1)]),element(none(),"to",[charData(str s2)])])]): return renameS(s1, s2, globally());
case element(_,"rename",[element(none(),"selector",[element(none(),"from",[charData(str s1)]),element(none(),"to",[charData(str s2)]),w])]): return renameS(s1, s2, mapcontext(w));
case element(_,"rename",[element(none(),"terminal",[element(none(),"from",[charData(str s1)]),element(none(),"to",[charData(str s2)])])]): return renameT(s1, s2, globally());
case element(_,"rename",[element(none(),"terminal",[element(none(),"from",[charData(str s1)]),element(none(),"to",[charData(str s2)]),w])]): return renameT(s1, s2, mapcontext(w));
case element(_,"replace",[e1,e2]): return replace(mapexpr(e1),mapexpr(e2),globally());
case element(_,"replace",[e1,e2,w]): return replace(mapexpr(e1),mapexpr(e2),mapcontext(w));
case element(_,"reroot",roots): return reroot([r | element(none(),"root",[charData(r)]) <- roots]);
// TODO: what is the best wat to parametrise splitN?
// also, the current structure is too hard to match in a one-liner in Rascal
//case element(_,"split",[element(none(),"nonterminal",[charData(str s)]),ps*,element(none(),"label",[charData(str s)])]): return splitN(s,[mapprod(p) | p <- ps],mapcontext(element(none(),"label",[charData(s)])));
//case element(_,"split",[element(none(),"nonterminal",[charData(str s)]),ps*]): return splitN(s,[mapprod(p) | p <- ps],globally());
// splitN(str x, list[BGFProduction] ps, BGFContext w)
case element(_,"split",[element(none(),"nonterminal",[charData(str s)]),p]): return splitN(s,[mapprod(p)],globally());
case element(_,"split",[element(none(),"nonterminal",[charData(str s)]),p,w]): return splitN(s,[mapprod(p)],mapcontext(w));
// TODO: not implemented anywhere
// splitT(str x, list[str] ys, BGFContext w)
case element(_,"unchain",[prod]): return unchain(mapprod(prod));
case element(_,"undefine",xs): return undefine([s | element(none(),"nonterminal",[charData(s)]) <- xs]);
case element(_,"unfold",[element(none(),"nonterminal",[charData(str s)])]): return unfold(s,globally());
case element(_,"unfold",[element(none(),"nonterminal",[charData(str s)]),w]): return unfold(s,mapcontext(w));
case element(_,"unite",[element(none(),"add",[charData(str s1)]),element(none(),"to",[charData(str s2)])]): return unite(s1, s2);
case element(_,"unlabel",[element(none(),"label",[charData(str s)])]): return unlabel(s);
case element(_,"upgrade",[p1,p2]): return upgrade(mapprod(p1),mapprod(p2));
case element(_,"vertical",[w]): return vertical(mapcontext(w));
case element(_,"widen",[e1,e2]): return widen(mapexpr(e1),mapexpr(e2),globally());
case element(_,"widen",[e1,e2,w]): return widen(mapexpr(e1),mapexpr(e2),mapcontext(w));
case element(_,"yaccify",ps): return yaccify([mapprod(p) | p <- ps]);
// legacy
case element(_,"atomic",L): return atomic([mapxbgf(element(namespace("xbgf","http://planet-sl.org/xbgf"),name,kids)) | element(namespace(_,"http://planet-sl.org/xbgf"),name,kids) <- L]);
case element(_,"strip",[element(none(),str s,[])]): return strip(s);
// default
case element(_,elname,elkids):
{
println("ERROR mapping "+elname);
println(elkids);
return;
}
}
println(xbgfs);
}
else
{
println("ERROR with:");
println(el);
}
}

BGFContext mapcontext(Node n)
Expand All @@ -41,26 +139,26 @@ BGFProduction mapprod(Node n)
str label = "";
str lhs = "";
BGFExpression rhs;
if (element(namespace("bgf","http://planet-sl.org/bgf"),"production",kids) := n)
if (element(namespace(_,"http://planet-sl.org/bgf"),"production",kids) := n)
{
for (k <- kids)
switch (k)
{
case element(none(),"label",[charData(str s)]) : label = s;
case element(none(),"nonterminal",[charData(str s)]) : lhs = s;
case element(namespace("bgf","http://planet-sl.org/bgf"),"expression",[expr]): rhs = mapexpr(expr);
case element(namespace(_,"http://planet-sl.org/bgf"),"expression",[expr]): rhs = mapexpr(expr);
}
return production (label, lhs, rhs);
}
else
return;
{println("ERROR in mapprod");println(n);return;}
}

BGFExpression mapexpr(Node n)
{
switch(n)
{
case element(namespace("bgf","http://planet-sl.org/bgf"),"expression",[e]): return mapexpr(e);
case element(namespace(_,"http://planet-sl.org/bgf"),"expression",[e]): return mapexpr(e);
case element(none(),"epsilon",[]): return epsilon();
case element(none(),"empty",[]): return empty();
case element(none(),"value",[charData("string")]): return val(string());
Expand All @@ -77,21 +175,6 @@ BGFExpression mapexpr(Node n)
case element(none(),"star",[expr]): return star(mapexpr(expr));
case element(none(),"starsepplus",[e1,e2]): return starsepplus(mapexpr(e1),mapexpr(e2));
case element(none(),"starsepstar",[e1,e2]): return starsepstar(mapexpr(e1),mapexpr(e2));
default: {println("ERROR in mapexpr");return epsilon();}
default: {println("ERROR in mapexpr");println(n);return;}
}
}

//
//<xbgf:sequence
// xmlns:bgf="http://planet-sl.org/bgf"
// xmlns:xbgf="http://planet-sl.org/xbgf">
// <xbgf:abridge>
// <bgf:production>
// <label>bracket</label>
// <nonterminal>expr</nonterminal>
// <bgf:expression>
// <nonterminal>expr</nonterminal>
// </bgf:expression>
// </bgf:production>
// </xbgf:abridge>
//</xbgf:sequence>
56 changes: 55 additions & 1 deletion shared/rascal/src/XBGFSyntax.rsc
@@ -1,14 +1,68 @@
@contributor{Vadim Zaytsev - vadim@grammarware.net - CWI}
module XBGFSyntax

alias XBGFSequence = list[XBGFCommand];

data XBGFCommand =
abridge(BGFProduction p)
| abstractize(BGFProduction p) // marked
| addH(BGFProduction p) // marked
| addV(BGFProduction p)
| anonymize(BGFProduction p)
| appear(BGFProduction p) // marked
| chain(BGFProduction p)
| clone(str x, str y, BGFContext w)
| concatT(list[str] xs, str y, BGFContext w)
| concretize(BGFProduction p) // marked
| deanonymize(BGFProduction p)
| define(list[BGFProduction] ps)
| designate(BGFProduction p)
| detour(BGFProduction p)
| deyaccify(str x)
| disappear(BGFProduction p) // marked
| distribute(BGFContext w)
| downgrade(BGFProduction p1,BGFProduction p2) // p1 is marked
| eliminate(str x)
| equate(str x, str y)
| extract(BGFProduction p, BGFContext w)
| factor(BGFExpression e1, BGFExpression e2, BGFContext w)
| fold(str x, BGFContext w)
| horizontal(BGFContext w)
| \import(list[BGFProduction] ps)
| inject(BGFProduction p) // marked
| inline(str x)
| introduce(list[BGFProduction] ps)
| iterate(BGFProduction p)
| lassoc(BGFProduction p)
| massage(BGFExpression e1, BGFExpression e2, BGFContext w)
| narrow(BGFExpression e1, BGFExpression e2, BGFContext w)
| permute(BGFProduction p)
| project(BGFProduction p) // marked
| rassoc(BGFProduction p)
| redefine(list[BGFProduction] ps)
| removeH(BGFProduction p) // marked
| removeV(BGFProduction p)
| renameL(str x, str y, BGFContext w)
| renameN(str x, str y, BGFContext w)
| renameS(str x, str y, BGFContext w)
| renameT(str x, str y, BGFContext w)
| replace(BGFExpression e1, BGFExpression e2, BGFContext w)
| yaccify(BGFProduction p1, BGFProduction p2)
| reroot(list[str] xs)
//| splitN(list[BGFProduction] ps, list[BGFProduction] qs, BGFContext w)
| splitN(str x, list[BGFProduction] ps, BGFContext w)
| splitT(str x, list[str] ys, BGFContext w)
| unchain(BGFProduction p)
| undefine(list[str] xs)
| unfold(str x, BGFContext w)
| unite(str x, str y)
| unlabel(str x) // ???
| upgrade(BGFProduction p1, BGFProduction p2) // p1 is marked
| vertical(BGFContext w)
| widen(BGFExpression e1, BGFExpression e2, BGFContext w)
| yaccify(list[BGFProduction] ps)
// legacy
| atomic(list[XBGFCommand] exprs)
| strip(str a)
;

data BGFContext =
Expand Down
19 changes: 9 additions & 10 deletions topics/transformation/xbgf/tests/rename4.xbgf
@@ -1,11 +1,10 @@
<xbgf:sequence
xmlns:bgf="http://planet-sl.org/bgf"
xmlns:xbgf="http://planet-sl.org/xbgf">
<xbgf:rename>
<selector>
<in>binary</in>
<from>op</from>
<to>operator</to>
</selector>
</xbgf:rename>
<?xml version="1.0" encoding="UTF-8"?>
<xbgf:sequence xmlns:bgf="http://planet-sl.org/bgf" xmlns:xbgf="http://planet-sl.org/xbgf">
<xbgf:rename>
<selector>
<from>op</from>
<to>operator</to>
<in>binary</in>
</selector>
</xbgf:rename>
</xbgf:sequence>

0 comments on commit 98cdd59

Please sign in to comment.