vendor/github.com/magiconair/properties/parser.go
changeset 242 2a9ec03fe5a1
child 260 445e01aede7e
equal deleted inserted replaced
241:e77dad242f4c 242:2a9ec03fe5a1
       
     1 // Copyright 2018 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 }