|
|
@ -23,9 +23,17 @@ func (p *Parser) lexStart() (lexer.StateFn, error) { |
|
|
|
case IsSpace(r): |
|
|
|
case IsSpace(r): |
|
|
|
// whitespace
|
|
|
|
// whitespace
|
|
|
|
p.stepRune() |
|
|
|
p.stepRune() |
|
|
|
|
|
|
|
case IsCommentStart(r): |
|
|
|
|
|
|
|
// switch to comment lexer
|
|
|
|
|
|
|
|
p.src.UnreadRune() |
|
|
|
|
|
|
|
return p.lexComment, nil |
|
|
|
|
|
|
|
case IsSectionStart(r): |
|
|
|
|
|
|
|
// section
|
|
|
|
|
|
|
|
return p.lexSectionStart, nil |
|
|
|
default: |
|
|
|
default: |
|
|
|
|
|
|
|
// entry
|
|
|
|
p.src.UnreadRune() |
|
|
|
p.src.UnreadRune() |
|
|
|
return p.lexToken, nil |
|
|
|
return p.lexEntryStart, nil |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -59,9 +67,78 @@ func (p *Parser) lexMoreNewLine(r1 rune) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (p *Parser) lexToken() (lexer.StateFn, error) { |
|
|
|
func (p *Parser) lexComment() (lexer.StateFn, error) { |
|
|
|
p.src.AcceptAll(IsNotSpace) |
|
|
|
// until the end of the line
|
|
|
|
|
|
|
|
p.src.AcceptAll(IsNotNewLine) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err := p.emitString(TokenComment) |
|
|
|
|
|
|
|
return p.lexStart, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (p *Parser) lexSectionStart() (lexer.StateFn, error) { |
|
|
|
|
|
|
|
if err := p.emitString(TokenSectionStart); err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// remove whitespace between `[` and the name
|
|
|
|
|
|
|
|
if p.src.AcceptAll(IsSpaceNotNewLine) { |
|
|
|
|
|
|
|
p.stepString() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if !p.src.AcceptAll(IsName) { |
|
|
|
|
|
|
|
// no name
|
|
|
|
|
|
|
|
return p.emitError("section name missing", lexer.ErrUnacceptableRune) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if err := p.emitString(TokenSectionName); err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// remove whitespace between the name andthe closing `]`
|
|
|
|
|
|
|
|
if p.src.AcceptAll(IsSpaceNotNewLine) { |
|
|
|
|
|
|
|
p.stepString() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r, _, err := p.src.ReadRune() |
|
|
|
|
|
|
|
switch { |
|
|
|
|
|
|
|
case err != nil: |
|
|
|
|
|
|
|
return p.emitError("", err) |
|
|
|
|
|
|
|
case IsSectionEnd(r): |
|
|
|
|
|
|
|
err := p.emitString(TokenSectionEnd) |
|
|
|
|
|
|
|
return p.lexStart, err |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
return p.emitInvalidRune(r) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (p *Parser) lexEntryStart() (lexer.StateFn, error) { |
|
|
|
|
|
|
|
p.src.AcceptAll(IsName) |
|
|
|
|
|
|
|
if err := p.emitString(TokenFieldKey); err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ignore whitespace between key and the '=' sign
|
|
|
|
|
|
|
|
if p.src.AcceptAll(IsSpaceNotNewLine) { |
|
|
|
|
|
|
|
p.stepString() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r, _, err := p.src.ReadRune() |
|
|
|
|
|
|
|
switch { |
|
|
|
|
|
|
|
case err != nil: |
|
|
|
|
|
|
|
return p.emitError("", err) |
|
|
|
|
|
|
|
case r != RuneFieldEqual: |
|
|
|
|
|
|
|
return p.emitInvalidRune(r) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ignore whitespace between the '=' and the value
|
|
|
|
|
|
|
|
if p.src.AcceptAll(IsSpaceNotNewLine) { |
|
|
|
|
|
|
|
p.stepString() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p.src.AcceptAll(IsNotNewLine) |
|
|
|
|
|
|
|
if err := p.emitString(TokenFieldValue); err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
err := p.emitString(TokenUnknown) |
|
|
|
|
|
|
|
return p.lexStart, err |
|
|
|
return p.lexStart, err |
|
|
|
} |
|
|
|
} |
|
|
|