1/**********
2 Starting rule, our entry point to the parser.
3 The first part of the PEG extracts the entity name as a string,
4 and makes the "entity" accessible in the JS below, allowing us to the AST and return it.
5 It matches certain expected keywords, eg. "has", but does nothing with them.
6 Finally it extracts the values, which have already been turned into a Values AST.
7 You'll see the "_" rule used here, this means "accept/skip whitespace", it's defined below.
8**********/
9Command = entity:Var "." command:Var _ "has" _ "nothing"* _ values:Values* _
10 {
11 // Handle case that there are no values
12 values = values.length === 0 ? [] : values[0];
13
14 // Return the matched results with this object structure
15 return {
16 entity: entity,
17 command: command,
18 values: values
19 }
20 }
21
22/**********
23 Matches a collection of inputs, 0 to many, that are wrapped in parentheses
24**********/
25Values = "{" _ values:(CompositeValue/Value)* _ "}"
26 {
27 return values;
28 }
29
30/**********
31 Value and CompositeValues always have the same initial shape, so I extracted
32 this into a partial result that is extended by both Value and Composite
33**********/
34ValuePartial = _ "a" [n]? _ cls:Var _ name:Var _
35 {
36 return {
37 class: cls,
38 param: name
39 }
40 }
41
42Value = value:ValuePartial alias:(Alias)? _
43 {
44 value.requestParam = (alias) ? alias: value.param;
45 value.type = 'value';
46 return value;
47 }
48
49/**********
50 Extract the alias value, ignore the "from" string
51**********/
52Alias = _ "from" _ alias:Var
53 {
54 return alias;
55 }
56
57CompositeValue = value:ValuePartial "from" _ values:Values
58 {
59 value.type = 'composite';
60 value.values = values;
61 return value;
62 }
63
64Var = name:[A-Za-z0-9_]*
65 {
66 return name.join("");
67 }
68
69/**********
70 Match any sequence of "whitespace" characters
71**********/
72_ = [ \t\n\r]*
73