MCPcopy
hub / github.com/hashicorp/hcl / parseBinaryOps

Method parseBinaryOps

hclsyntax/parser.go:546–616  ·  hclsyntax/parser.go::parser.parseBinaryOps

parseBinaryOps calls itself recursively to work through all of the operator precedence groups, and then eventually calls parseExpressionTerm for each operand.

(ops []map[TokenType]*Operation)

Source from the content-addressed store, hash-verified

544// operator precedence groups, and then eventually calls parseExpressionTerm
545// for each operand.
546func (p *parser) parseBinaryOps(ops []map[TokenType]*Operation) (Expression, hcl.Diagnostics) {
547 if len(ops) == 0 {
548 // We've run out of operators, so now we'll just try to parse a term.
549 return p.parseExpressionWithTraversals()
550 }
551
552 thisLevel := ops[0]
553 remaining := ops[1:]
554
555 var lhs, rhs Expression
556 var operation *Operation
557 var diags hcl.Diagnostics
558
559 // Parse a term that might be the first operand of a binary
560 // operation or it might just be a standalone term.
561 // We won't know until we've parsed it and can look ahead
562 // to see if there's an operator token for this level.
563 lhs, lhsDiags := p.parseBinaryOps(remaining)
564 diags = append(diags, lhsDiags...)
565 if p.recovery && lhsDiags.HasErrors() {
566 return lhs, diags
567 }
568
569 // We'll keep eating up operators until we run out, so that operators
570 // with the same precedence will combine in a left-associative manner:
571 // a+b+c => (a+b)+c, not a+(b+c)
572 //
573 // Should we later want to have right-associative operators, a way
574 // to achieve that would be to call back up to ParseExpression here
575 // instead of iteratively parsing only the remaining operators.
576 for {
577 next := p.Peek()
578 var newOp *Operation
579 var ok bool
580 if newOp, ok = thisLevel[next.Type]; !ok {
581 break
582 }
583
584 // Are we extending an expression started on the previous iteration?
585 if operation != nil {
586 lhs = &BinaryOpExpr{
587 LHS: lhs,
588 Op: operation,
589 RHS: rhs,
590
591 SrcRange: hcl.RangeBetween(lhs.Range(), rhs.Range()),
592 }
593 }
594
595 operation = newOp
596 p.Read() // eat operator token
597 var rhsDiags hcl.Diagnostics
598 rhs, rhsDiags = p.parseBinaryOps(remaining)
599 diags = append(diags, rhsDiags...)
600 if p.recovery && rhsDiags.HasErrors() {
601 return lhs, diags
602 }
603 }

Callers 1

Calls 5

HasErrorsMethod · 0.95
RangeMethod · 0.95
PeekMethod · 0.45
ReadMethod · 0.45

Tested by

no test coverage detected