Stream parser
This commit is contained in:
parent
7f547ce194
commit
4ef3bb8fd6
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue