Skip to content

Commit

Permalink
Framework for writing XBGF and BGF files (tested)
Browse files Browse the repository at this point in the history
  • Loading branch information
grammarware committed Jun 1, 2012
1 parent ad31398 commit 8953e20
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 45 deletions.
1 change: 1 addition & 0 deletions shared/rascal/res/.gitignore
@@ -0,0 +1 @@
*.xbgf
9 changes: 7 additions & 2 deletions shared/rascal/src/Main.rsc
Expand Up @@ -5,21 +5,26 @@ import IO;
import syntax::BGF;
import syntax::XBGF;
import io::ReadXBGF;
import io::WriteXBGF;
//import lang::xml::DOM;

public void main()
{
println(readXBGF(|project://slps/tests/undefine1.xbgf|));
XBGFSequence x;
x = readXBGF(|project://slps/tests/long.xbgf|);
iprintln(x);
writeXBGF(x,|project://slps/res/long.xbgf|);
}

public bool tryAll()
{
loc base = |project://slps/tests|;
loc outp = |project://slps/res|;
for (f <- listEntries(base))
{
if (f == ".gitignore") continue;
println(f);
println(readXBGF(base+f));
writeXBGF(readXBGF(base+f),outp+f);
}
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion shared/rascal/src/io/ReadBGF.rsc
Expand Up @@ -10,7 +10,7 @@ public BGFGrammar readBGF(loc f)
if (document(element(namespace(_,"http://planet-sl.org/bgf"),"grammar",L)) := parseXMLDOMTrim(readFile(f)))
return grammar([s | element(none(),"root",[charData(s)]) <- L],[mapprod(p) | p <- L, element(namespace(_,"http://planet-sl.org/bgf"),name,kids) := p]);
else
throw "<f> is not an BGF file";
throw "<f> is not a proper BGF file";
}

public BGFProduction mapprod(Node n)
Expand Down
26 changes: 16 additions & 10 deletions shared/rascal/src/io/ReadXBGF.rsc
Expand Up @@ -13,7 +13,7 @@ public XBGFSequence readXBGF(loc f)
if (document(element(namespace(_,"http://planet-sl.org/xbgf"),"sequence",L)) := N)
return [mapxbgf(step) | step <- L, element(namespace(_,"http://planet-sl.org/xbgf"),name,kids) := step];
else
throw "<f> is not an XBGF file";
throw "<f> is not a proper XBGF file";
}

XBGFCommand mapxbgf(Node el)
Expand All @@ -29,8 +29,8 @@ XBGFCommand mapxbgf(Node el)
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)
// clone(str x, str y, XBGFContext w)
// concatT(list[str] xs, str y, XBGFContext 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]);
Expand Down Expand Up @@ -70,7 +70,7 @@ XBGFCommand mapxbgf(Node el)
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(),"selector",[element(none(),"in",[charData(str w)]),element(none(),"from",[charData(str s1)]),element(none(),"to",[charData(str s2)])])]): return renameS(s1, s2, inlabel(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());
Expand All @@ -80,11 +80,11 @@ XBGFCommand mapxbgf(Node el)
// 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)
// splitN(str x, list[BGFProduction] ps, XBGFContext 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)
// splitT(str x, list[str] ys, XBGFContext 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());
Expand All @@ -97,7 +97,7 @@ XBGFCommand mapxbgf(Node el)
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(_,"atomic",L): return atomic([mapxbgf(x) | x <- L, element(namespace(_,"http://planet-sl.org/xbgf"),_,_) := x]);
case element(_,"strip",[element(none(),str s,[])]): return strip(s);
// default
default:
Expand All @@ -111,8 +111,14 @@ XBGFCommand mapxbgf(Node el)
throw "ERROR with:\n<el>";
}

BGFContext mapcontext(Node n)
XBGFContext mapcontext(Node n)
{
// TODO: not implemented
return globally();
switch(n)
{
case element(none(),"label",[charData(str s)]): return inlabel(s);
case element(none(),"nonterminal",[charData(str s)]): return innt(s);
case element(none(),"in",[charData(str s)]): return inlabel(s); // conceptually wrong yet happens in renameS
case element(none(),"in",[w]): return mapcontext(w);
default: throw "ERROR in context: <n>";
}
}
63 changes: 63 additions & 0 deletions shared/rascal/src/io/WriteBGF.rsc
@@ -0,0 +1,63 @@
@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI}
module io::WriteBGF

import IO;
import syntax::BGF;
import lang::xml::DOM;

public void writeBGF(BGFGrammar bgf, loc f)
{
//grammar (list[str] roots, list[BGFProduction] prods)
if (grammar(list[str] roots, list[BGFProduction] prods) := bgf)
{
list[Node] xml1 = [element(none(),"root",[charData(s)]) | s <- roots];
list[Node] xml2 = [prod2xml(p) | p <- prods];
//println(xml);
writeFile(f,xmlRaw(document(element(namespace("bgf","http://planet-sl.org/bgf"),"grammar",xml1+xml2))));
}
else throw "ERROR: grammar expected in place of <bgf>";
//Node N = parseXMLDOMTrim(readFile(f));
//if (document(element(namespace(_,"http://planet-sl.org/xbgf"),"sequence",L)) := N)
// return [mapxbgf(step) | step <- L, element(namespace(_,"http://planet-sl.org/xbgf"),name,kids) := step];
//else
// throw "<f> is not a proper XBGF file";
}

public Node prod2xml(BGFProduction p)
{
if (production (str label, str lhs, BGFExpression rhs) := p)
{
list[Node] kids = [];
if (label!="") kids += element(none(),"label",[charData(label)]);
kids += element(none(),"nonterminal",[charData(lhs)]);
kids += expr2xml(rhs);
return element(namespace("bgf","http://planet-sl.org/bgf"),"production",kids);
}
else throw "ERROR: production rule expected in place of <p>";
}

public Node expr2xml(BGFExpression ex)
{
Node e;
switch(ex)
{
case epsilon(): e = element(none(),"epsilon",[]);
case empty(): e = element(none(),"empty",[]);
case val(string()): e = element(none(),"value",[charData("string")]);
case val(integer()): e = element(none(),"value",[charData("int")]);
case anything(): e = element(none(),"any",[]);
case terminal(str s): e = element(none(),"terminal",[charData(s)]);
case nonterminal(str s): e = element(none(),"nonterminal",[charData(s)]);
case selectable(s,expr): e = element(none(),"selectable",[element(none(),"selector",[charData(s)]),expr2xml(expr)]);
case sequence(L): e = element(none(),"sequence",[expr2xml(expr) | expr <- L]);
case choice(L): e = element(none(),"choice",[expr2xml(expr) | expr <- L]);
case marked(expr): e = element(none(),"marked",[expr2xml(expr)]);
case optional(expr): e = element(none(),"optional",[expr2xml(expr)]);
case plus(expr): e = element(none(),"plus",[expr2xml(expr)]);
case star(expr): e = element(none(),"star",[expr2xml(expr)]);
case starsepplus(e1,e2): e = element(none(),"starsepplus",[expr2xml(e1),expr2xml(e2)]);
case starsepstar(e1,e2): e = element(none(),"starsepstar",[expr2xml(e1),expr2xml(e2)]);
default: throw "ERROR: expression expected in place of <ex>";
}
return element(namespace("bgf","http://planet-sl.org/bgf"),"expression",[e]);
}

0 comments on commit 8953e20

Please sign in to comment.