promql字符串解析
lexer 用来将promql字符串解析成item
volume_manager_total_volumes{instance="lfgphicprd07591",job="kubernetes-nodes",kubernetes_io_arch="amd64"}[5m]
// item represents a token or text string returned from the scanner. type item struct { typ ItemType // The type of this item. pos Pos // The starting position, in bytes, of this item in the input string. val string // The value of this item. }
StateFunc
// stateFn represents the state of the scanner as a function that returns the next state. type stateFn func(*lexer) stateFn
lexStatements
识别所有表达式中可分类的部分,并将一般可解析的转化为itemlexInsideBraces
识别{}中可能出现的字符解析:eof space 字母或者下划线 ," '
=~ != !~ ` lexValueSequence
lexLineComment
识别注释行lexNumberOrDuration
识别数组或者区间 lexString
识别引号中的文本包括单双引号lexRawString
识别原始的文本lexKeywordOrIdentifier
识别字母数字标记符号(labelname)或关键字lexDuration
识别时间区间 smhdwy lexSpace
识别空白字符 lexIdentifier
识别字母数字标记符号lexNumber
识别数字lexEscape
识别转义字符
操作pos
next
// next returns the next rune in the input. func (l *lexer) next() rune { if int(l.pos) >= len(l.input) { l.width = 0 return eof } r, w := utf8.DecodeRuneInString(l.input[l.pos:]) l.width = Pos(w) l.pos += l.width return r }
peek
// peek returns but does not consume the next rune in the input. func (l *lexer) peek() rune { r := l.next() l.backup() return r }
backup
// backup steps back one rune. Can only be called once per call of next. func (l *lexer) backup() { l.pos -= l.width }
读取item
emit
loop
// run runs the state machine for the lexer. func (l *lexer) run() { for l.state = lexStatements; l.state != nil; { l.state = l.state(l) } close(l.items) }
utf8.DecodeRuneInString()
返回一个r和长度,r对应字符本身,长度对应r采用UTF8编码后的编码字节数目
parse
ParseMetric、ParseMetricSelector 处理基本逻辑一致:
初始化新的解析器
使用
func (p *parser) labelMatchers(operators ...ItemType) []*labels.Matcher
获取过滤器中所有matchParseMetric 直接获取labelMatchers中name、value返回labels.Labels
ParseMetricSelector 获取所有p.labelMatchers(ItemEQL, ItemNEQ, ItemEQLRegex, ItemNEQRegex)过滤并根据传入的name 字符串创建一个
__name__="name"
的Matcher
func newParser(input string) *parser { p := &parser{ lex: lex(input), } return p }
ParseMetric
newParser(input string) --> metric() 判断第一个item类型为左大括号:p.labelSet() 判断最后一个是不是 ItemComma ItemRightBrace 作为终止标志 获取label name、value以及 matchType(过滤类型)
ParseMetricSelector
newParser(input string) --> parseExpr() --> VectorSelector(name)
ParseExpr
newParser(input string) --> parseExpr() --> typecheck(expr)
- 点赞
- 收藏
- 关注作者
评论(0)