163 |
165 |
164 func (p *tomlParser) parseAssign() tomlParserStateFn { |
166 func (p *tomlParser) parseAssign() tomlParserStateFn { |
165 key := p.getToken() |
167 key := p.getToken() |
166 p.assume(tokenEqual) |
168 p.assume(tokenEqual) |
167 |
169 |
|
170 parsedKey, err := parseKey(key.val) |
|
171 if err != nil { |
|
172 p.raiseError(key, "invalid key: %s", err.Error()) |
|
173 } |
|
174 |
168 value := p.parseRvalue() |
175 value := p.parseRvalue() |
169 var tableKey []string |
176 var tableKey []string |
170 if len(p.currentTable) > 0 { |
177 if len(p.currentTable) > 0 { |
171 tableKey = p.currentTable |
178 tableKey = p.currentTable |
172 } else { |
179 } else { |
173 tableKey = []string{} |
180 tableKey = []string{} |
174 } |
181 } |
|
182 |
|
183 prefixKey := parsedKey[0 : len(parsedKey)-1] |
|
184 tableKey = append(tableKey, prefixKey...) |
175 |
185 |
176 // find the table to assign, looking out for arrays of tables |
186 // find the table to assign, looking out for arrays of tables |
177 var targetNode *Tree |
187 var targetNode *Tree |
178 switch node := p.tree.GetPath(tableKey).(type) { |
188 switch node := p.tree.GetPath(tableKey).(type) { |
179 case []*Tree: |
189 case []*Tree: |
180 targetNode = node[len(node)-1] |
190 targetNode = node[len(node)-1] |
181 case *Tree: |
191 case *Tree: |
182 targetNode = node |
192 targetNode = node |
|
193 case nil: |
|
194 // create intermediate |
|
195 if err := p.tree.createSubTree(tableKey, key.Position); err != nil { |
|
196 p.raiseError(key, "could not create intermediate group: %s", err) |
|
197 } |
|
198 targetNode = p.tree.GetPath(tableKey).(*Tree) |
183 default: |
199 default: |
184 p.raiseError(key, "Unknown table type for path: %s", |
200 p.raiseError(key, "Unknown table type for path: %s", |
185 strings.Join(tableKey, ".")) |
201 strings.Join(tableKey, ".")) |
186 } |
202 } |
187 |
203 |
188 // assign value to the found table |
204 // assign value to the found table |
189 keyVals := []string{key.val} |
205 keyVal := parsedKey[len(parsedKey)-1] |
190 if len(keyVals) != 1 { |
|
191 p.raiseError(key, "Invalid key") |
|
192 } |
|
193 keyVal := keyVals[0] |
|
194 localKey := []string{keyVal} |
206 localKey := []string{keyVal} |
195 finalKey := append(tableKey, keyVal) |
207 finalKey := append(tableKey, keyVal) |
196 if targetNode.GetPath(localKey) != nil { |
208 if targetNode.GetPath(localKey) != nil { |
197 p.raiseError(key, "The following key was defined twice: %s", |
209 p.raiseError(key, "The following key was defined twice: %s", |
198 strings.Join(finalKey, ".")) |
210 strings.Join(finalKey, ".")) |
299 if err != nil { |
311 if err != nil { |
300 p.raiseError(tok, "%s", err) |
312 p.raiseError(tok, "%s", err) |
301 } |
313 } |
302 return val |
314 return val |
303 case tokenDate: |
315 case tokenDate: |
304 val, err := time.ParseInLocation(time.RFC3339Nano, tok.val, time.UTC) |
316 layout := time.RFC3339Nano |
|
317 if !strings.Contains(tok.val, "T") { |
|
318 layout = strings.Replace(layout, "T", " ", 1) |
|
319 } |
|
320 val, err := time.ParseInLocation(layout, tok.val, time.UTC) |
|
321 if err != nil { |
|
322 p.raiseError(tok, "%s", err) |
|
323 } |
|
324 return val |
|
325 case tokenLocalDate: |
|
326 v := strings.Replace(tok.val, " ", "T", -1) |
|
327 isDateTime := false |
|
328 isTime := false |
|
329 for _, c := range v { |
|
330 if c == 'T' || c == 't' { |
|
331 isDateTime = true |
|
332 break |
|
333 } |
|
334 if c == ':' { |
|
335 isTime = true |
|
336 break |
|
337 } |
|
338 } |
|
339 |
|
340 var val interface{} |
|
341 var err error |
|
342 |
|
343 if isDateTime { |
|
344 val, err = ParseLocalDateTime(v) |
|
345 } else if isTime { |
|
346 val, err = ParseLocalTime(v) |
|
347 } else { |
|
348 val, err = ParseLocalDate(v) |
|
349 } |
|
350 |
305 if err != nil { |
351 if err != nil { |
306 p.raiseError(tok, "%s", err) |
352 p.raiseError(tok, "%s", err) |
307 } |
353 } |
308 return val |
354 return val |
309 case tokenLeftBracket: |
355 case tokenLeftBracket: |
336 } |
382 } |
337 switch follow.typ { |
383 switch follow.typ { |
338 case tokenRightCurlyBrace: |
384 case tokenRightCurlyBrace: |
339 p.getToken() |
385 p.getToken() |
340 break Loop |
386 break Loop |
341 case tokenKey: |
387 case tokenKey, tokenInteger, tokenString: |
342 if !tokenIsComma(previous) && previous != nil { |
388 if !tokenIsComma(previous) && previous != nil { |
343 p.raiseError(follow, "comma expected between fields in inline table") |
389 p.raiseError(follow, "comma expected between fields in inline table") |
344 } |
390 } |
345 key := p.getToken() |
391 key := p.getToken() |
346 p.assume(tokenEqual) |
392 p.assume(tokenEqual) |
|
393 |
|
394 parsedKey, err := parseKey(key.val) |
|
395 if err != nil { |
|
396 p.raiseError(key, "invalid key: %s", err) |
|
397 } |
|
398 |
347 value := p.parseRvalue() |
399 value := p.parseRvalue() |
348 tree.Set(key.val, value) |
400 tree.SetPath(parsedKey, value) |
349 case tokenComma: |
401 case tokenComma: |
350 if previous == nil { |
|
351 p.raiseError(follow, "inline table cannot start with a comma") |
|
352 } |
|
353 if tokenIsComma(previous) { |
402 if tokenIsComma(previous) { |
354 p.raiseError(follow, "need field between two commas in inline table") |
403 p.raiseError(follow, "need field between two commas in inline table") |
355 } |
404 } |
356 p.getToken() |
405 p.getToken() |
357 default: |
406 default: |