1
0
Fork 0

Stream parser

This commit is contained in:
Gregory Eremin 2015-02-18 22:04:26 +07:00
parent 7f547ce194
commit 4ef3bb8fd6
1 changed files with 44 additions and 14 deletions

View File

@ -15,7 +15,11 @@ type (
lex *lexer.Lexer lex *lexer.Lexer
ctx *context ctx *context
sels map[string]*context sels map[string]*context
res map[string][]lexer.Item res chan Match
}
Match struct {
Sel string
Val interface{}
} }
) )
@ -27,29 +31,45 @@ func New(buf buffer.Bufferer, sels []string) *Parser {
exps: []expectation{}, exps: []expectation{},
}, },
sels: parseSelectors(sels), sels: parseSelectors(sels),
res: map[string][]lexer.Item{}, res: make(chan Match),
} }
} }
// Starts parsing // Starts parsing
func (p *Parser) Parse() map[string][]interface{} { func (p *Parser) Parse() map[string][]interface{} {
go p.lex.Run() p.ParseStream()
p.parseValue(p.next())
out := map[string][]interface{}{} out := map[string][]interface{}{}
for sel, res := range p.res { for {
for _, item := range res { if m, ok := <-p.res; ok {
if val, err := castValue(item); err == nil { out[m.Sel] = append(out[m.Sel], m.Val)
out[sel] = append(out[sel], val)
} else { } else {
out[sel] = append(out[sel], err) break
} }
} }
}
return out return out
} }
func (p *Parser) ParseStream() <-chan Match {
go p.lex.Run()
go func() {
defer func() {
if err := recover(); err != nil {
fmt.Println("\nParse error! Yay!")
fmt.Println(err)
}
close(p.res)
}()
for {
if item := p.next(); item.Token != lexer.EOF {
p.parseValue(item)
} else {
break
}
}
}()
return p.res
}
func (p *Parser) parseValue(item lexer.Item) { func (p *Parser) parseValue(item lexer.Item) {
switch item.Token { switch item.Token {
case lexer.Null, lexer.Bool, lexer.Number, lexer.String: case lexer.Null, lexer.Bool, lexer.Number, lexer.String:
@ -123,7 +143,17 @@ func (p *Parser) parseObject() {
func (p *Parser) pushValue(item lexer.Item) { func (p *Parser) pushValue(item lexer.Item) {
for sel, exp := range p.sels { for sel, exp := range p.sels {
if ok := exp.compare(p.ctx); ok { if ok := exp.compare(p.ctx); ok {
p.res[sel] = append(p.res[sel], item) if val, err := castValue(item); err == nil {
p.res <- Match{
Sel: sel,
Val: val,
}
} else {
p.res <- Match{
Sel: sel,
Val: err,
}
}
return return
} }
} }