zclsyntax: parse expressions in newline-ignoring mode

This applies both two the whole of bare expressions and to any nested
expressions within parentheses. The latter means that an attribute value
can span over multiple lines if it's wrapped in parens:

    foo = (
        1 + 2 + 3 + 4 + 5
    )
This commit is contained in:
Martin Atkins 2017-06-02 07:26:45 -07:00
parent 302487ce0f
commit 6052cb9938
3 changed files with 19 additions and 1 deletions

View File

@ -30,6 +30,14 @@ func TestExpressionParseAndValue(t *testing.T) {
cty.NumberIntVal(1),
0,
},
{
`(
1
)`,
nil,
cty.NumberIntVal(1),
0,
},
{
`(1`,
nil,

View File

@ -400,12 +400,16 @@ func (p *parser) parseExpressionTerm() (Expression, zcl.Diagnostics) {
switch start.Type {
case TokenOParen:
p.Read() // eat open paren
p.PushIncludeNewlines(false)
expr, diags := p.ParseExpression()
if diags.HasErrors() {
// attempt to place the peeker after our closing paren
// before we return, so that the next parser has some
// chance of finding a valid expression.
p.recover(TokenCParen)
p.PopIncludeNewlines()
return expr, diags
}
@ -422,6 +426,7 @@ func (p *parser) parseExpressionTerm() (Expression, zcl.Diagnostics) {
}
p.Read() // eat closing paren
p.PopIncludeNewlines()
return expr, diags

View File

@ -31,10 +31,15 @@ func ParseExpression(src []byte, filename string, start zcl.Pos) (Expression, zc
tokens := LexExpression(src, filename, start)
peeker := newPeeker(tokens, false)
parser := &parser{peeker: peeker}
// Bare expressions are always parsed in "ignore newlines" mode, as if
// they were wrapped in parentheses.
parser.PushIncludeNewlines(false)
expr, diags := parser.ParseExpression()
next := parser.Peek()
if next.Type != TokenEOF {
if next.Type != TokenEOF && !parser.recovery {
diags = append(diags, &zcl.Diagnostic{
Severity: zcl.DiagError,
Summary: "Extra characters after expression",