-
Notifications
You must be signed in to change notification settings - Fork 2
/
geekspec_dsl_parser.pegjs
91 lines (75 loc) · 2.28 KB
/
geekspec_dsl_parser.pegjs
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
{
let filterIsNotArray = (xs => xs.filter(x => !Array.isArray(x)));
let isNotUndef = (s => s != 'undefined');
let head = xs => xs[0]
}
GeekSpec = specs:(__ ApiSpec __)* { return specs.map(x => head(filterIsNotArray(x))); }
SingleLineComment
= "#" !lineTerminator .*
entityName = letter+
interfaceName = letter+
urlPath "url letters" = (letter / [:/.{}?&=%])+
argName = letter+
possibleValue = letter+
fieldName = simpleletter+
httpMethod
= "GET" / "POST"
/ "PUT" / "DELETE"
/ "PATCH" / "OPTIONS"
/ "HEAD"
ApiSpec =
name:interfaceName _ '(' _ a:Arg? as:(_ "," _ Arg)* _ ')'
_ rtxd:('->' _ (ReturnType / Dict))? _ '=' _ url:urlPath {
return {
method: "GET",
name: name.join(''),
args: a == null ? [] : [a].concat(as.map(ra => ra[3])),
return : isNotUndef(typeof rtxd) ? (rtxd == null ? null : rtxd[2]) : null,
url: url.join('')
};
}
/
method:httpMethod '@' name:interfaceName _ '(' _ a:Arg? as:(_ "," _ Arg)* _ ')'
_ rtxd:('->' _ (ReturnType / Dict))? _ '=' _ url:urlPath {
return {
method: method,
name: name.join(''),
args: a == null ? [] : [a].concat(as.map(ra => ra[3])),
return : isNotUndef(typeof rtxd) ? (rtxd == null ? null : rtxd[2]) : null,
url: url.join('')
};
}
Arg = name:argName _ q:('?' / "!"?) _ ov:OptionVals? {
return {
name: name.join(''),
required: q != "?",
options: ov
};
}
OptionVals = '{' _ pv:possibleValue? pvs:(_ ',' _ possibleValue)* _ '}' {
return pv == null ? [] : [pv.join('')].concat(pvs.map(rpv => rpv[3].join('')));
}
ReturnType
= axo:("array" / "object") ':' a:Atom { return { type: axo, of: ((typeof a != 'string') ? a.join('') : a) }; }
/ a:Atom { return ((typeof a != 'string') ? a.join('') : a); }
Atom = "boolean" / "number"
/ "string" / "datetime"
/ "plain" / entityName
Dict = '[' _ di:DictItem? dis:(_ ',' _ DictItem)* _ ']' {
return di == null ? [] : [di].concat(dis.map(rd => rd[3]))
}
DictItem
= !'$' rt:ReturnType { return { type: rt }; }
/ '$' name:fieldName ':' rt:ReturnType {
return { name: name.join(''), type: rt };
}
_ "whitespace"
= [ \t\n\r]*
__ "comment or whitespace"
= SingleLineComment / _
letter "letter"
= [A-Za-z0-9_\-:]
simpleletter "simple letter"
= [A-Za-z0-9_\-]
lineTerminator
= [\n\r\u2028\u2029]