diff --git a/rascal/src/Rascalware.rsc b/rascal/src/Rascalware.rsc new file mode 100644 index 0000000..1a50576 --- /dev/null +++ b/rascal/src/Rascalware.rsc @@ -0,0 +1,7 @@ +@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI} +module Rascalware + +public str folds(str(&T) f, list[&T] ss) = ("" | it + f(s) | &T s <- ss); +public list[&T] mapl(&T(&D) f, list[&D] xs) = [f(x) | &D x <- xs]; +//public list[&T] mapc2a(&T(&D) f, {&D &L}+ xs) = [f(x) | &D x <- xs]; +//public list[&T] mapc2a(&T(&D) f, &D+ xs) = [f(x) | &D x <- xs]; diff --git a/rascal/src/io/bibtex/Normal.rsc b/rascal/src/io/bibtex/Normal.rsc new file mode 100644 index 0000000..07452cc --- /dev/null +++ b/rascal/src/io/bibtex/Normal.rsc @@ -0,0 +1,21 @@ +@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI} +module io::bibtex::Normal + +import io::bibtex::Unparser; +import io::bibtex::Parser; +import IO; + +public void main() +{ + println(bib2str([normalise(e) | e <- loc2bib(|home:///workspace/bibtex/list.bib|)])); +} + +BibEntry normalise(BibEntry e) +{ + return e; +} + +//BibEntry normalise(BibEntry e) +//{ +// +//} diff --git a/rascal/src/io/bibtex/Parser.rsc b/rascal/src/io/bibtex/Parser.rsc index 537c60d..5885031 100644 --- a/rascal/src/io/bibtex/Parser.rsc +++ b/rascal/src/io/bibtex/Parser.rsc @@ -1,24 +1,73 @@ @contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI} module io::bibtex::Parser +//import Rascalware; import io::bibtex::Syntax; import ParseTree; import String; +import List; // size import IO; alias BibLib = list[BibEntry]; -alias BibEntry = tuple[str kind, str name, map[str,str] attrs]; +alias BibAttrs = map[str,BibString]; +alias BibEntry = tuple[str kind, str name, BibAttrs attrs]; +data BibString + = raw(str s) + | quoted(BibString bs) + | bracketed(BibString bs) + | bibseq(list[BibString]) + ; public BibLib loc2bib(loc l) = str2bib(readFile(l)); BibLib str2bib(str s) = library2list(parse(#BibLibrary,trim(s))); +//BibLib library2list(BibLibrary b) = mapc2a(mapEntry,b.es); BibLib library2list(BibLibrary b) = [mapEntry(e) | OneBibEntry e <- b.es]; BibEntry mapEntry(OneBibEntry e) = <"","",mapKVs(e.pairs)>; -map[str,str] mapKVs({BibPair ","}+ ps) = ("":"" | BibPair p <- ps); +BibAttrs mapKVs({BibPair ","}+ ps) = ("":mapStr(p.val) | BibPair p <- ps); + +BibString mapStr((BibValue)``) = quoted(mapStrQ(v)); +BibString mapStr((BibValue)``) = bracketed(mapStrC(v)); +default BibString mapStr(BibValue v) = raw(""); + +BibString mapStrQ(BibValueQ v) = normalise([mapQEl(e) | BQElement e <- v.es]); + +BibString mapQEl((BQElement)``) = bracketed(mapStrC(c)); +default BibString mapQEl(BQElement e) = raw(""); + +BibString mapStrC(BibValueC v) = normalise([mapCEl(e) | BCElement e <- v.es]); + +BibString mapCEl((BCElement)``) = bracketed(mapStrC(c)); +default BibString mapCEl(BCElement e) = raw(""); + +BibString normalise(list[BibString] bs) +{ + bs2 = innermost visit(bs) + { + case [*L1,raw(str s1),raw(str s2),*L2] => [*L1,raw(s1+s2),*L2] + }; + if (size(bs2)==1) + return bs2[0]; + else + return bibseq(bs2); +} + public void main() { - loc2bib(|home:///workspace/zaytsev.bib|); -} \ No newline at end of file + iprintln(loc2bib(|home:///workspace/bibtex/icse2010.bib|)[0]); + //loc2bib(|home:///workspace/zaytsev.bib|); +} + +// TODO will be useful later for checking unparser completeness +public void do() +{ + list[str] allkeys = []; + for(BibEntry b <-loc2bib(|home:///workspace/bibtex/icse2010.bib|), str x <- b.attrs) + if (x notin allkeys) + allkeys += x; + iprintln(allkeys); +} + diff --git a/rascal/src/io/bibtex/Syntax.rsc b/rascal/src/io/bibtex/Syntax.rsc index 4ff4a75..797f4c3 100644 --- a/rascal/src/io/bibtex/Syntax.rsc +++ b/rascal/src/io/bibtex/Syntax.rsc @@ -16,10 +16,10 @@ lexical BibValue | [a-zA-Z0-9]+ !>> [a-zA-Z0-9] ; -lexical BibValueQ = [\"] BQElement* [\"] ; +lexical BibValueQ = [\"] BQElement* es [\"] ; lexical BQElement = ![\"\\{}] | [\\] [\"\'`&$%a-zA-Z] | BibValueC; -lexical BibValueC = [{] BCElement* [}]; +lexical BibValueC = [{] BCElement* es [}]; lexical BCElement = BibValueC | ![{}]; start syntax BibLibrary = OneBibEntry+ es; diff --git a/rascal/src/io/bibtex/Unparser.rsc b/rascal/src/io/bibtex/Unparser.rsc new file mode 100644 index 0000000..d3faace --- /dev/null +++ b/rascal/src/io/bibtex/Unparser.rsc @@ -0,0 +1,25 @@ +@contributor{Vadim Zaytsev - vadim@grammarware.net - SWAT, CWI} +module io::bibtex::Unparser + +import io::bibtex::Parser; +import Rascalware; + +// TODO: check completeness, sort appropriately +list[str] good = + ["author","title","booktitle","year", + "url","doi","numpages","publisher","series","acmid", + "isbn","location","address","pages","keywords"]; + +public str bib2str(BibLib bl) = folds(bib2str,bl); + +str bib2str(BibEntry be) = + "@{, + '\t = , + '<}>} + '"; + +str pp(quoted(BibString s)) = "\"\""; +str pp(bracketed(BibString s)) = "{}"; +str pp(raw(str s)) = s; +str pp(bibseq(list[BibString] ss)) = folds(pp,ss); +default str pp(BibString s) = ""; \ No newline at end of file