github.com/franciscocpg/up@v0.1.10/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  }