/
Parser.rsc
73 lines (57 loc) · 2.01 KB
/
Parser.rsc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
@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 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) = <"<e.kind.name>","<e.name>",mapKVs(e.pairs)>;
BibAttrs mapKVs({BibPair ","}+ ps) = ("<p.key>":mapStr(p.val) | BibPair p <- ps);
BibString mapStr((BibValue)`<BibValueQ v>`) = quoted(mapStrQ(v));
BibString mapStr((BibValue)`<BibValueC v>`) = bracketed(mapStrC(v));
default BibString mapStr(BibValue v) = raw("<v>");
BibString mapStrQ(BibValueQ v) = normalise([mapQEl(e) | BQElement e <- v.es]);
BibString mapQEl((BQElement)`<BibValueC c>`) = bracketed(mapStrC(c));
default BibString mapQEl(BQElement e) = raw("<e>");
BibString mapStrC(BibValueC v) = normalise([mapCEl(e) | BCElement e <- v.es]);
BibString mapCEl((BCElement)`<BibValueC c>`) = bracketed(mapStrC(c));
default BibString mapCEl(BCElement e) = raw("<e>");
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()
{
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);
}