From a2d04d6cf5dc8e63ad171ea23f24c453c4fc774d Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Tue, 12 Nov 2024 22:08:26 +0900 Subject: [PATCH] fix parsing of tag (#526) --- parser/parser.go | 16 +++++++++++----- parser/parser_test.go | 38 +++++++++++++++++++++++++++++++++++++- scanner/scanner.go | 14 ++++++++++---- 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/parser/parser.go b/parser/parser.go index 60f9db57..5776a08d 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -226,9 +226,16 @@ func (p *parser) parseTag(ctx *context) (*ast.TagNode, error) { err error ) switch token.ReservedTagKeyword(tagToken.Value) { - case token.MappingTag, - token.OrderedMapTag: - value, err = p.parseMapping(ctx) + case token.MappingTag, token.OrderedMapTag: + tk := p.currentToken() + if tk.Type == token.CommentType { + tk = p.nextNotCommentToken() + } + if tk != nil && tk.Type == token.MappingStartType { + value, err = p.parseMapping(ctx) + } else { + value, err = p.parseMappingValue(ctx) + } case token.IntegerTag, token.FloatTag, token.StringTag, @@ -245,8 +252,7 @@ func (p *parser) parseTag(ctx *context) (*ast.TagNode, error) { token.SetTag: err = errors.ErrSyntax(fmt.Sprintf("sorry, currently not supported %s tag", tagToken.Value), tagToken) default: - // custom tag - value, err = p.parseToken(ctx, p.currentToken()) + err = errors.ErrSyntax(fmt.Sprintf("unknown tag name %q specified", tagToken.Value), tagToken) } if err != nil { return nil, err diff --git a/parser/parser_test.go b/parser/parser_test.go index b6153bf4..f1961cf7 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -70,7 +70,6 @@ func TestParser(t *testing.T) { "%YAML 1.2\n---\n", "a: !!binary gIGC\n", "a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n", - "- !tag\n a: b\n c: d\n", "v:\n- A\n- |-\n B\n C\n", "v:\n- A\n- >-\n B\n C\n", "v: |-\n 0\n", @@ -960,6 +959,43 @@ func TestSyntaxError(t *testing.T) { }{ { ` +- !tag + a: b + c: d +`, + ` +[2:3] unknown tag name "!tag" specified +> 2 | - !tag + ^ + 3 | a: b + 4 | c: d`, + }, + { + ` +a: !tag + b: c +`, + ` +[2:4] unknown tag name "!tag" specified +> 2 | a: !tag + ^ + 3 | b: c`, + }, + { + ` +a: !tag + b: c + d: e +`, + ` +[2:4] unknown tag name "!tag" specified +> 2 | a: !tag + ^ + 3 | b: c + 4 | d: e`, + }, + { + ` a: - b c: d diff --git a/scanner/scanner.go b/scanner/scanner.go index 913c8784..50e24b1a 100644 --- a/scanner/scanner.go +++ b/scanner/scanner.go @@ -504,14 +504,20 @@ func (s *Scanner) scanTag(ctx *Context) bool { progress = idx + 1 ctx.addOriginBuf(c) switch c { - case ' ', '\n', '\r': + case ' ': + value := ctx.source(ctx.idx-1, ctx.idx+idx) + ctx.addToken(token.Tag(value, string(ctx.obuf), s.pos())) + s.progressColumn(ctx, len([]rune(value))) + ctx.clear() + return true + case '\n', '\r': value := ctx.source(ctx.idx-1, ctx.idx+idx) ctx.addToken(token.Tag(value, string(ctx.obuf), s.pos())) - progress = len([]rune(value)) - goto END + s.progressColumn(ctx, len([]rune(value))-1) // progress column before new-line-char for scanning new-line-char at scanNewLine function. + ctx.clear() + return true } } -END: s.progressColumn(ctx, progress) ctx.clear() return true