Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Side by Side Diff: appengine/cmd/dm/distributor/impl/jobsim/parser/grammar.peg

Issue 1537883002: Initial distributor implementation (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-go@master
Patch Set: work in progress Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // vim: syntax=go
2 {
3 // Copyright 2015 The Chromium Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6
7 package parser
8
9 type retriesHolder uint64
10 type identityHolder uint64
11
12 var whitespaceRE = regexp.MustCompile("#[^\n]*\n|\\s+")
13
14 // CleanPhrase removes all whitespace and comments from a phrase in preparation
15 // for parsing it. The parsers defined in this package only operate on cleaned
16 // phrases, and will fail to parse if you provide a phrase with whitespace.
17 func CleanPhrase(p string) string {
18 return whitespaceRE.ReplaceAllLiteralString(p, "")
19 }
20
21 // ParsePhrase is a convenience function for the parser functions in this
22 // package to return a typed Phrase object as the result of a string.
23 func ParsePhrase(p string) (Phrase, error) {
24 ret, err := Parse("<string>", []byte(p))
25 if err != nil {
26 return nil, err
27 }
28 return ret.(Phrase), nil
29 }
30 }
31
32 Overall = p:Phrase !. {
33 return p, nil
34 } / p:Phrase ext:Extra {
35 return nil, fmt.Errorf("found extra: %q", ext.(string))
36 } / !. {
37 return nil, fmt.Errorf("empty phrase")
38 } / ext:Extra {
39 return nil, fmt.Errorf("expected phrase: %q", ext.(string))
40 }
41
42 Extra = .* {
43 return string(c.text), nil
44 }
45
46 Phrase = ret:ReturnStage {
47 return Phrase{ret.(Stage)}, nil
48 } / first:Stage middleI:(',' Stage)* retI:(',' ReturnStage)? {
49 middle, _ := middleI.([]interface{})
50 retStage, _ := retI.([]interface{})
51
52 amt := 1
53 if middle != nil {
54 amt += len(middle)
55 }
56 if retStage != nil {
57 amt++
58 }
59
60 ret := make(Phrase, 0, amt)
61 ret = append(ret, first.(Stage))
62 for _, itm := range middle {
63 ret = append(ret, itm.([]interface{})[1].(Stage))
64 }
65 if retStage != nil {
66 ret = append(ret, retStage[1].(Stage))
67 }
68
69 return ret, nil
70 } / ',' .* {
71 return nil, fmt.Errorf("expected stage in %q", string(c.text))
72 }
73
74 Stage = s:(FailureStage / StallStage / DepsStage) {
75 return s, nil
76 }
77
78 FailureStage = '%' num:Num {
79 return FailureStage(num.(uint64)), nil
80 }
81
82 StallStage = '@' amt:Duration {
83 return StallStage(amt.(time.Duration)), nil
84 }
85
86 ReturnStage = '=' val:Num exp:('<' Duration)? {
87 ret := &ReturnStage{Value: val.(uint64)}
88 if exp != nil {
89 ret.Expiration = exp.([]interface{})[1].(time.Duration)
90 }
91 return ret, nil
92 }
93
94 DepsStage = first:Dependency restI:('&' Dependency)* {
95 rest, _ := restI.([]interface{})
96
97 if rest == nil {
98 return DepsStage{first.(*Dependency)}, nil
99 }
100 ret := make(DepsStage, 0, 1+len(rest))
101 ret = append(ret, first.(*Dependency))
102 for _, itm := range rest{
103 ret = append(ret, itm.([]interface{})[1].(*Dependency))
104 }
105 return ret, nil
106 } / '&' .* {
107 return nil, fmt.Errorf("expected dependency in %q", string(c.text))
108 }
109
110 Dependency = shards:Shards? attempts:Attempts? id:ID options:Option? subI:( '(' Phrase ')' )? {
111 ret := &Dependency{Name: id.(string)}
112
113 if shards != nil {
114 ret.ShardCount = shards.(uint64)
115 }
116
117 if attempts != nil {
118 ret.AttemptNums = attempts.(RangeSlice)
119 }
120
121 if options != nil {
122 switch x := options.(type) {
123 case retriesHolder:
124 if attempts != nil {
125 return nil, fmt.Errorf(
126 "in %q: retries are incompatible with specified Attempts",
127 string(c.text))
128 }
129 ret.Retries = uint64(x)
130
131 case identityHolder:
132 ret.Uniq = uint64(x)
133 }
134 }
135
136 sub, _ := subI.([]interface{})
137 if sub != nil {
138 ret.Substages = sub[1].(Phrase)
139 }
140
141 return ret, nil
142 }
143
144 Option = '+' num:Num {
145 return retriesHolder(num.(uint64)), nil
146 } / '^' num:Num {
147 return identityHolder(num.(uint64)), nil
148 }
149
150 Shards = '{' num:Num '}' {
151 return num, nil
152 }
153
154 Attempts = '[' rs:RangeSlice ']' {
155 return rs, nil
156 }
157
158 RangeSlice = firstI:Range restI:(',' Range)* {
159 rest, _ := restI.([]interface{})
160
161 ret := make(RangeSlice, 0, 1+len(rest))
162 ret = append(ret, firstI.(Range))
163 for _, itm := range rest {
164 ret = append(ret, itm.([]interface{})[1].(Range))
165 }
166
167 return ret, nil
168 }
169
170 Range = loI:Num '-' hiI:Num {
171 lo := loI.(uint64)
172 hi := hiI.(uint64)
173
174 if lo >= hi {
175 return nil, fmt.Errorf("invalid range %q: lo >= hi", string(c.text))
176 }
177
178 return Range{lo, hi}, nil
179 } / num:Num {
180 return Range{num.(uint64), 0}, nil
181 }
182
183 Duration = num:Num {
184 return time.Second * time.Duration(num.(uint64)), nil
185 }
186
187 Num = '0' {
188 return nil, fmt.Errorf("zero value not acceptable")
189 } / [1-9][0-9]* {
190 return strconv.ParseUint(string(c.text), 10, 64)
191 } / .* {
192 return nil, fmt.Errorf("expected number, got %q", string(c.text))
193 }
194
195 ID = [a-zA-Z'_]+ {
196 return string(c.text), nil
197 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698