zclsyntax: allow numeric "attributes" inside attr-only splats
Terraform interprets HIL variables in such a way that it allows numeric attribute names which then get interpreted as numeric indices into a list. This is used to work around the fact that the splat expressions don't work for the index operator. zcl has "full splats" that _do_ support the index operator, but to allow old Terraform configs to be processed by zcl we'll accept this special case within attribute-only-splats only. For the moment this is a special exception made by this specific implementation of zcl rather than part of the spec, since it's specifically a pragmatic Terraform migration strategy, but it might get upgraded to full spec status later if we end up needing to support it in other host languages. This requires the scanner to be a little more picky about the ending of numeric literals, so that they won't absorb the trailing period after the number in foo.*.baz.1.baz . This is okay because the spec doesn't allow trailing periods anyway, and this is not actually a change in final behavior because the parser was already catching this situation and rejecting it at a later point.
This commit is contained in:
parent
2c9302b699
commit
59a1343216
@ -700,6 +700,24 @@ upper(
|
||||
}),
|
||||
0,
|
||||
},
|
||||
{
|
||||
`[["hello"], ["world", "unused"]].*.0`,
|
||||
nil,
|
||||
cty.TupleVal([]cty.Value{
|
||||
cty.StringVal("hello"),
|
||||
cty.StringVal("world"),
|
||||
}),
|
||||
0,
|
||||
},
|
||||
{
|
||||
`[[{name:"foo"}], [{name:"bar"}, {name:"baz"}]].*.0.name`,
|
||||
nil,
|
||||
cty.TupleVal([]cty.Value{
|
||||
cty.StringVal("foo"),
|
||||
cty.StringVal("bar"),
|
||||
}),
|
||||
0,
|
||||
},
|
||||
{
|
||||
// For an "attribute-only" splat, an index operator applies to
|
||||
// the splat result as a whole, rather than being incorporated
|
||||
|
@ -508,6 +508,24 @@ Traversal:
|
||||
firstRange = p.NextRange()
|
||||
for p.Peek().Type == TokenDot {
|
||||
dot := p.Read()
|
||||
|
||||
if p.Peek().Type == TokenNumberLit {
|
||||
// Continuing the "weird stuff inherited from HIL"
|
||||
// theme, we also allow numbers as attribute names
|
||||
// inside splats and interpret them as indexing
|
||||
// into a list, for expressions like:
|
||||
// foo.bar.*.baz.0.foo
|
||||
numTok := p.Read()
|
||||
numVal, numDiags := p.numberLitValue(numTok)
|
||||
diags = append(diags, numDiags...)
|
||||
trav = append(trav, zcl.TraverseIndex{
|
||||
Key: numVal,
|
||||
SrcRange: zcl.RangeBetween(dot.Range, numTok.Range),
|
||||
})
|
||||
lastRange = numTok.Range
|
||||
continue
|
||||
}
|
||||
|
||||
if p.Peek().Type != TokenIdent {
|
||||
if !p.recovery {
|
||||
if p.Peek().Type == TokenStar {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -33,7 +33,8 @@ func scanTokens(data []byte, filename string, start zcl.Pos, mode scanMode) []To
|
||||
);
|
||||
BrokenUTF8 = any - AnyUTF8;
|
||||
|
||||
NumberLit = digit (digit|'.'|('e'|'E') ('+'|'-')? digit)*;
|
||||
NumberLitContinue = (digit|'.'|('e'|'E') ('+'|'-')? digit);
|
||||
NumberLit = digit ("" | (NumberLitContinue - '.') | (NumberLitContinue* (NumberLitContinue - '.')));
|
||||
Ident = ID_Start (ID_Continue | '-')*;
|
||||
|
||||
# Symbols that just represent themselves are handled as a single rule.
|
||||
|
Loading…
Reference in New Issue
Block a user