github.com/orteth01/up@v0.2.0/internal/logs/parser/parser.go (about) 1 //go:generate peg -inline -switch grammar.peg 2 3 // Package parser provides a parser for Up's 4 // log query language, abstracting away provider 5 // specifics. 6 package parser 7 8 import ( 9 "github.com/apex/up/internal/logs/parser/ast" 10 ) 11 12 // Parse query string. 13 func Parse(s string) (ast.Node, error) { 14 p := &parser{Buffer: s} 15 p.Init() 16 17 if err := p.Parse(); err != nil { 18 return nil, err 19 } 20 21 p.Execute() 22 n := ast.Root{Node: p.stack[0]} 23 return n, nil 24 } 25 26 // push node. 27 func (p *parser) push(n ast.Node) { 28 p.stack = append(p.stack, n) 29 } 30 31 // pop node. 32 func (p *parser) pop() ast.Node { 33 if len(p.stack) == 0 { 34 panic("pop: no nodes") 35 } 36 37 n := p.stack[len(p.stack)-1] 38 p.stack = p.stack[:len(p.stack)-1] 39 return n 40 } 41 42 // AddLevel node. 43 func (p *parser) AddLevel(s string) { 44 p.AddField("level") 45 p.AddString(s) 46 p.AddBinary(ast.EQ) 47 p.AddExpr() 48 } 49 50 // AddExpr node. 51 func (p *parser) AddExpr() { 52 p.push(ast.Expr{ 53 Node: p.pop(), 54 }) 55 } 56 57 // AddField node. 58 func (p *parser) AddField(s string) { 59 switch s { 60 case "level", "message", "timestamp": 61 p.push(ast.Property(s)) 62 default: 63 p.push(ast.Field(s)) 64 } 65 } 66 67 // AddString node. 68 func (p *parser) AddString(s string) { 69 p.push(ast.String(s)) 70 } 71 72 // AddSubscript node. 73 func (p *parser) AddSubscript(s string) { 74 p.push(ast.Subscript{ 75 Left: p.pop(), 76 Right: ast.Literal(s), 77 }) 78 } 79 80 // AddMember node. 81 func (p *parser) AddMember(s string) { 82 p.push(ast.Member{ 83 Left: p.pop(), 84 Right: ast.Literal(s), 85 }) 86 } 87 88 // AddNumber node. 89 func (p *parser) AddNumber(s string) { 90 p.push(ast.Number(s)) 91 } 92 93 // AddTuple node. 94 func (p *parser) AddTuple() { 95 p.push(ast.Tuple{}) 96 } 97 98 // AddTupleValue node. 99 func (p *parser) AddTupleValue() { 100 v := p.pop() 101 t := p.pop().(ast.Tuple) 102 t = append(t, v) 103 p.push(t) 104 } 105 106 // AddBinary node. 107 func (p *parser) AddBinary(op ast.Op) { 108 p.push(ast.Binary{ 109 Op: op, 110 Right: p.pop(), 111 Left: p.pop(), 112 }) 113 } 114 115 // AddBinaryContains node. 116 func (p *parser) AddBinaryContains() { 117 p.push(ast.Binary{ 118 Op: ast.EQ, 119 Right: ast.Contains{Node: p.pop()}, 120 Left: p.pop(), 121 }) 122 } 123 124 // AddUnary node. 125 func (p *parser) AddUnary(op ast.Op) { 126 p.push(ast.Unary{ 127 Op: op, 128 Right: p.pop(), 129 }) 130 }