OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / magiconair / properties / parser.go
1 // Copyright 2017 Frank Schroeder. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package properties
6
7 import (
8         "fmt"
9         "runtime"
10 )
11
12 type parser struct {
13         lex *lexer
14 }
15
16 func parse(input string) (properties *Properties, err error) {
17         p := &parser{lex: lex(input)}
18         defer p.recover(&err)
19
20         properties = NewProperties()
21         key := ""
22         comments := []string{}
23
24         for {
25                 token := p.expectOneOf(itemComment, itemKey, itemEOF)
26                 switch token.typ {
27                 case itemEOF:
28                         goto done
29                 case itemComment:
30                         comments = append(comments, token.val)
31                         continue
32                 case itemKey:
33                         key = token.val
34                         if _, ok := properties.m[key]; !ok {
35                                 properties.k = append(properties.k, key)
36                         }
37                 }
38
39                 token = p.expectOneOf(itemValue, itemEOF)
40                 if len(comments) > 0 {
41                         properties.c[key] = comments
42                         comments = []string{}
43                 }
44                 switch token.typ {
45                 case itemEOF:
46                         properties.m[key] = ""
47                         goto done
48                 case itemValue:
49                         properties.m[key] = token.val
50                 }
51         }
52
53 done:
54         return properties, nil
55 }
56
57 func (p *parser) errorf(format string, args ...interface{}) {
58         format = fmt.Sprintf("properties: Line %d: %s", p.lex.lineNumber(), format)
59         panic(fmt.Errorf(format, args...))
60 }
61
62 func (p *parser) expect(expected itemType) (token item) {
63         token = p.lex.nextItem()
64         if token.typ != expected {
65                 p.unexpected(token)
66         }
67         return token
68 }
69
70 func (p *parser) expectOneOf(expected ...itemType) (token item) {
71         token = p.lex.nextItem()
72         for _, v := range expected {
73                 if token.typ == v {
74                         return token
75                 }
76         }
77         p.unexpected(token)
78         panic("unexpected token")
79 }
80
81 func (p *parser) unexpected(token item) {
82         p.errorf(token.String())
83 }
84
85 // recover is the handler that turns panics into returns from the top level of Parse.
86 func (p *parser) recover(errp *error) {
87         e := recover()
88         if e != nil {
89                 if _, ok := e.(runtime.Error); ok {
90                         panic(e)
91                 }
92                 *errp = e.(error)
93         }
94         return
95 }