diff --git a/parser/parser.go b/parser/parser.go index 08f9dfe..7e2370b 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -754,6 +754,11 @@ func (p *parser) parseMapValue(ctx *context, key ast.MapKeyNode, colonTk *Token) // &anchor return nil, errors.ErrSyntax("anchor is not allowed in this context", tk.RawToken()) } + if tk.Column() <= keyCol && tk.Type() == token.TagType { + // key: + // !!tag + return nil, errors.ErrSyntax("tag is not allowed in this context", tk.RawToken()) + } if tk.Column() < keyCol { // in this case, @@ -785,9 +790,43 @@ func (p *parser) parseMapValue(ctx *context, key ast.MapKeyNode, colonTk *Token) if err != nil { return nil, err } + if err := p.validateAnchorValueInMapOrSeq(value, keyCol); err != nil { + return nil, err + } return value, nil } +func (p *parser) validateAnchorValueInMapOrSeq(value ast.Node, col int) error { + anchor, ok := value.(*ast.AnchorNode) + if !ok { + return nil + } + tag, ok := anchor.Value.(*ast.TagNode) + if !ok { + return nil + } + anchorTk := anchor.GetToken() + tagTk := tag.GetToken() + + if anchorTk.Position.Line == tagTk.Position.Line { + // key: + // &anchor !!tag + // + // - &anchor !!tag + return nil + } + + if tagTk.Position.Column <= col { + // key: &anchor + // !!tag + // + // - &anchor + // !!tag + return errors.ErrSyntax("tag is not allowed in this context", tagTk) + } + return nil +} + func (p *parser) parseAnchor(ctx *context, g *TokenGroup) (*ast.AnchorNode, error) { anchorNameGroup := g.First().Group anchor, err := p.parseAnchorName(ctx.withGroup(anchorNameGroup)) @@ -1089,6 +1128,11 @@ func (p *parser) parseSequenceValue(ctx *context, seqTk *Token) (ast.Node, error // &anchor return nil, errors.ErrSyntax("anchor is not allowed in this sequence context", tk.RawToken()) } + if tk.Column() <= seqCol && tk.Type() == token.TagType { + // - + // !!tag + return nil, errors.ErrSyntax("tag is not allowed in this sequence context", tk.RawToken()) + } if tk.Column() < seqCol { // in this case, @@ -1120,6 +1164,9 @@ func (p *parser) parseSequenceValue(ctx *context, seqTk *Token) (ast.Node, error if err != nil { return nil, err } + if err := p.validateAnchorValueInMapOrSeq(value, seqCol); err != nil { + return nil, err + } return value, nil } diff --git a/yaml_test_suite_test.go b/yaml_test_suite_test.go index edfe3f1..346ecc9 100644 --- a/yaml_test_suite_test.go +++ b/yaml_test_suite_test.go @@ -45,7 +45,6 @@ var failureTestNames = []string{ "multiline-scalar-at-top-level", // pass yamlv3. "multiline-scalar-at-top-level-1-3", // pass yamlv3. "nested-implicit-complex-keys", // no json. - "node-anchor-not-indented", // pass yamlv3. "plain-dashes-in-flow-sequence", "question-mark-edge-cases/00", // no json. "question-mark-edge-cases/01", // no json.