()
| 949 | } |
| 950 | |
| 951 | func (p *parser) parseExpressionTerm() (Expression, hcl.Diagnostics) { |
| 952 | start := p.Peek() |
| 953 | |
| 954 | switch start.Type { |
| 955 | case TokenOParen: |
| 956 | oParen := p.Read() // eat open paren |
| 957 | |
| 958 | p.PushIncludeNewlines(false) |
| 959 | |
| 960 | expr, diags := p.ParseExpression() |
| 961 | if diags.HasErrors() { |
| 962 | // attempt to place the peeker after our closing paren |
| 963 | // before we return, so that the next parser has some |
| 964 | // chance of finding a valid expression. |
| 965 | p.recover(TokenCParen) |
| 966 | p.PopIncludeNewlines() |
| 967 | return expr, diags |
| 968 | } |
| 969 | |
| 970 | close := p.Peek() |
| 971 | if close.Type != TokenCParen { |
| 972 | diags = append(diags, &hcl.Diagnostic{ |
| 973 | Severity: hcl.DiagError, |
| 974 | Summary: "Unbalanced parentheses", |
| 975 | Detail: "Expected a closing parenthesis to terminate the expression.", |
| 976 | Subject: &close.Range, |
| 977 | Context: hcl.RangeBetween(start.Range, close.Range).Ptr(), |
| 978 | }) |
| 979 | p.setRecovery() |
| 980 | } |
| 981 | |
| 982 | cParen := p.Read() // eat closing paren |
| 983 | p.PopIncludeNewlines() |
| 984 | |
| 985 | // Our parser's already taken care of the precedence effect of the |
| 986 | // parentheses by considering them to be a kind of "term", but we |
| 987 | // still need to include the parentheses in our AST so we can give |
| 988 | // an accurate representation of the source range that includes the |
| 989 | // open and closing parentheses. |
| 990 | expr = &ParenthesesExpr{ |
| 991 | Expression: expr, |
| 992 | SrcRange: hcl.RangeBetween(oParen.Range, cParen.Range), |
| 993 | } |
| 994 | |
| 995 | return expr, diags |
| 996 | |
| 997 | case TokenNumberLit: |
| 998 | tok := p.Read() // eat number token |
| 999 | |
| 1000 | numVal, diags := p.numberLitValue(tok) |
| 1001 | return &LiteralValueExpr{ |
| 1002 | Val: numVal, |
| 1003 | SrcRange: tok.Range, |
| 1004 | }, diags |
| 1005 | |
| 1006 | case TokenIdent: |
| 1007 | tok := p.Read() // eat identifier token |
| 1008 |
no test coverage detected