Repository: goccy/go-yaml
Pull request #412 (2023-12-15 16:56:04)

feat: preserve line breaks from original input
## Motivation

Preserve the line breaks from input.

We use this project as dependency in a project that round trips YAML, this attempts to try and preserve the formatting. It will only ever add one line break between lines regardless of input.

## Changes
- add `checkLineBreak` method that uses the previous token to calculate if there should be a line break
- account for `token.SequenceEntryType`  using the previous token of that.
- ensure multiline strings are accounted for in the logic
- add a new table test
- update existing test to validate string output has changed
- update existing tests to output differences on failure

<!--Before submitting your PR, please confirm the following.-->

## Checks

- [x] Describe the purpose for which you created this PR.  
- [x] Create test code that corresponds to the modification

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/goccy/go-yaml/pull/412?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Masaaki+Goshima) Report
> Merging [#412](https://app.codecov.io/gh/goccy/go-yaml/pull/412?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Masaaki+Goshima) (bf7faf1) into [master](https://app.codecov.io/gh/goccy/go-yaml/commit/0640a158e99023787bc503fd4476e472d804c3a3?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Masaaki+Goshima) (0640a15) will **not change** coverage.
> The diff coverage is `n/a`.

:exclamation: Your organization needs to install the [Codecov GitHub app](https://github.com/apps/codecov/installations/select_target) to enable full functionality.

<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##           master     #412   +/-   ##
=======================================
  Coverage   76.02%   76.02%           
=======================================
  Files          13       13           
  Lines        4692     4692           
=======================================
  Hits         3567     3567           
  Misses        866      866           
  Partials      259      259           
```

</details>
mcwarman: @goccy I'd be interested to get your thoughts on this.

Patch:
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index 647c692..27337dd 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -5,12 +5,26 @@ on:
       - master
   pull_request:
 jobs:
+  lint:
+    name: lint
+    runs-on: ubuntu-latest
+    steps:
+      - name: checkout
+        uses: actions/checkout@v4
+      - name: setup Go
+        uses: actions/setup-go@v4
+        with:
+          go-version: "1.23"
+      - name: run linters
+        run: |
+          make lint
+
   race-test:
     name: Test with -race
     strategy:
       matrix:
         os: [ "ubuntu-latest", "macos-latest", "windows-latest" ]
-        go-version: [ "1.19", "1.20", "1.21" ]
+        go-version: [ "1.21", "1.22", "1.23" ]
     runs-on: ${{ matrix.os }}
     steps:
     - name: checkout
@@ -28,7 +42,7 @@ jobs:
     strategy:
       matrix:
         os: [ "ubuntu-latest", "windows-latest" ]
-        go-version: [ "1.19", "1.20", "1.21" ]
+        go-version: [ "1.21", "1.22", "1.23" ]
     runs-on: ${{ matrix.os }}
     env:
       GOARCH: "386"
@@ -52,7 +66,7 @@ jobs:
       - name: setup Go
         uses: actions/setup-go@v4
         with:
-          go-version: "1.21"
+          go-version: "1.23"
       - name: build
         run: |
           make ycat/build
@@ -69,11 +83,12 @@ jobs:
       - name: setup Go
         uses: actions/setup-go@v4
         with:
-          go-version: "1.21"
+          go-version: "1.23"
       - name: measure coverage
         run: |
           make cover
-      - uses: codecov/codecov-action@v3
+      - uses: codecov/codecov-action@v4
         with:
           fail_ci_if_error: true
           verbose: true
+          token: ${{ secrets.CODECOV_TOKEN }}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e660fd9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,1 @@
+bin/
diff --git a/.golangci.yml b/.golangci.yml
new file mode 100644
index 0000000..ec8d731
--- /dev/null
+++ b/.golangci.yml
@@ -0,0 +1,42 @@
+run:
+  timeout: 5m
+
+linters-settings:
+  errcheck:
+    check-type-assertions: true
+  gci:
+    sections:
+      - "standard"
+      - "default"
+      - "prefix(github.com/goccy/go-yaml)"
+      - "blank"
+      - "dot"
+  gofmt:
+    simplify: true
+  govet:
+    disable:
+      - tests
+  misspell:
+    locale: US
+  staticcheck:
+    checks: ["all", "-ST1000", "-ST1005"]
+
+linters:
+  disable-all: true
+  enable:
+    - errcheck
+    - gci
+    - gofmt
+    - gosimple
+    - govet
+    - ineffassign
+    - misspell
+    - staticcheck
+    - typecheck
+    - unused
+
+issues:
+  exclude-rules:
+    - path: _test\.go
+      linters:
+        - staticcheck
diff --git a/Makefile b/Makefile
index 1b1d923..02a38dd 100644
--- a/Makefile
+++ b/Makefile
@@ -17,3 +17,31 @@ cover-html: cover
 .PHONY: ycat/build
 ycat/build:
 	go build -o ycat ./cmd/ycat
+
+.PHONY: lint
+lint: golangci-lint ## Run golangci-lint
+	@$(GOLANGCI_LINT) run
+
+.PHONY: fmt
+fmt: golangci-lint ## Ensure consistent code style
+	@go mod tidy
+	@go fmt ./...
+	@$(GOLANGCI_LINT) run --fix
+
+## Location to install dependencies to
+LOCALBIN ?= $(shell pwd)/bin
+$(LOCALBIN):
+	mkdir -p $(LOCALBIN)
+
+## Tool Binaries
+GOLANGCI_LINT ?= $(LOCALBIN)/golangci-lint
+
+## Tool Versions
+GOLANGCI_VERSION := 1.61.0
+
+.PHONY: golangci-lint
+.PHONY: $(GOLANGCI_LINT)
+golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary.
+$(GOLANGCI_LINT): $(LOCALBIN)
+	@test -s $(LOCALBIN)/golangci-lint && $(LOCALBIN)/golangci-lint version --format short | grep -q $(GOLANGCI_VERSION) || \
+	curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(LOCALBIN) v$(GOLANGCI_VERSION)
diff --git a/README.md b/README.md
index 9452349..06c6ab0 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,11 @@
 
 <img width="300px" src="https://user-images.githubusercontent.com/209884/67159116-64d94b80-f37b-11e9-9b28-f8379636a43c.png"></img>
 
+## This library has **NO** relation to the go-yaml/yaml library
+
+This library is developed from scratch to replace [`go-yaml/yaml`](https://github.com/go-yaml/yaml).
+If you're looking for a better YAML library, this one should be helpful.
+
 # Why a new library?
 
 As of this writing, there already exists a de facto standard library for YAML processing for Go: [https://github.com/go-yaml/yaml](https://github.com/go-yaml/yaml). However we feel that some features are lacking, namely:
diff --git a/ast/ast.go b/ast/ast.go
index b4d5ec4..29eb6b2 100644
--- a/ast/ast.go
+++ b/ast/ast.go
@@ -1,6 +1,7 @@
 package ast
 
 import (
+	"errors"
 	"fmt"
 	"io"
 	"math"
@@ -8,13 +9,12 @@ import (
 	"strings"
 
 	"github.com/goccy/go-yaml/token"
-	"golang.org/x/xerrors"
 )
 
 var (
-	ErrInvalidTokenType  = xerrors.New("invalid token type")
-	ErrInvalidAnchorName = xerrors.New("invalid anchor name")
-	ErrInvalidAliasName  = xerrors.New("invalid alias name")
+	ErrInvalidTokenType  = errors.New("invalid token type")
+	ErrInvalidAnchorName = errors.New("invalid anchor name")
+	ErrInvalidAliasName  = errors.New("invalid alias name")
 )
 
 // NodeType type identifier of node
@@ -278,6 +278,49 @@ func readNode(p []byte, node Node) (int, error) {
 	return size, nil
 }
 
+func checkLineBreak(t *token.Token) bool {
+	if t.Prev != nil {
+		lbc := "\n"
+		prev := t.Prev
+		var adjustment int
+		// if the previous type is sequence entry use the previous type for that
+		if prev.Type == token.SequenceEntryType {
+			// as well as switching to previous type count any new lines in origin to account for:
+			// -
+			//   b: c
+			adjustment = strings.Count(strings.TrimRight(t.Origin, lbc), lbc)
+			if prev.Prev != nil {
+				prev = prev.Prev
+			}
+		}
+		lineDiff := t.Position.Line - prev.Position.Line - 1
+		if lineDiff > 0 {
+			if prev.Type == token.StringType {
+				// Remove any line breaks included in multiline string
+				adjustment += strings.Count(strings.TrimRight(strings.TrimSpace(prev.Origin), lbc), lbc)
+			}
+			// Due to the way that comment parsing works its assumed that when a null value does not have new line in origin
+			// it was squashed therefore difference is ignored.
+			//foo:
+			//  bar:
+			//  # comment
+			//  baz: 1
+			//becomes
+			//foo:
+			//  bar: null # comment
+			//
+			//  baz: 1
+			if prev.Type == token.NullType {
+				return strings.Count(prev.Origin, lbc) > 0
+			}
+			if lineDiff-adjustment > 0 {
+				return true
+			}
+		}
+	}
+	return false
+}
+
 // Null create node for null value
 func Null(tk *token.Token) *NullNode {
 	return &NullNode{
@@ -1390,6 +1433,9 @@ func (n *MappingValueNode) String() string {
 
 func (n *MappingValueNode) toString() string {
 	space := strings.Repeat(" ", n.Key.GetToken().Position.Column-1)
+	if checkLineBreak(n.Key.GetToken()) {
+		space = fmt.Sprintf("%s%s", "\n", space)
+	}
 	keyIndentLevel := n.Key.GetToken().Position.IndentLevel
 	valueIndentLevel := n.Value.GetToken().Position.IndentLevel
 	keyComment := n.Key.GetComment()
@@ -1491,7 +1537,7 @@ type SequenceNode struct {
 // Replace replace value node.
 func (n *SequenceNode) Replace(idx int, value Node) error {
 	if len(n.Values) <= idx {
-		return xerrors.Errorf(
+		return fmt.Errorf(
 			"invalid index for sequence: sequence length is %d, but specified %d index",
 			len(n.Values), idx,
 		)
@@ -1563,6 +1609,11 @@ func (n *SequenceNode) blockStyleString() string {
 
 	for idx, value := range n.Values {
 		valueStr := value.String()
+		newLinePrefix := ""
+		if strings.HasPrefix(valueStr, "\n") {
+			valueStr = valueStr[1:]
+			newLinePrefix = "\n"
+		}
 		splittedValues := strings.Split(valueStr, "\n")
 		trimmedFirstValue := strings.TrimLeft(splittedValues[0], " ")
 		diffLength := len(splittedValues[0]) - len(trimmedFirstValue)
@@ -1585,9 +1636,10 @@ func (n *SequenceNode) blockStyleString() string {
 		}
 		newValue := strings.Join(newValues, "\n")
 		if len(n.ValueHeadComments) == len(n.Values) && n.ValueHeadComments[idx] != nil {
-			values = append(values, n.ValueHeadComments[idx].StringWithSpace(n.Start.Position.Column-1))
+			values = append(values, fmt.Sprintf("%s%s", newLinePrefix, n.ValueHeadComments[idx].StringWithSpace(n.Start.Position.Column-1)))
+			newLinePrefix = ""
 		}
-		values = append(values, fmt.Sprintf("%s- %s", space, newValue))
+		values = append(values, fmt.Sprintf("%s%s- %s", newLinePrefix, space, newValue))
 	}
 	if n.FootComment != nil {
 		values = append(values, n.FootComment.StringWithSpace(n.Start.Position.Column-1))
@@ -1880,10 +1932,13 @@ func (n *CommentGroupNode) StringWithSpace(col int) string {
 	values := []string{}
 	space := strings.Repeat(" ", col)
 	for _, comment := range n.Comments {
+		space := space
+		if checkLineBreak(comment.Token) {
+			space = fmt.Sprintf("%s%s", "\n", space)
+		}
 		values = append(values, space+comment.String())
 	}
 	return strings.Join(values, "\n")
-
 }
 
 // MarshalYAML encodes to a YAML text
@@ -2092,10 +2147,10 @@ func Merge(dst Node, src Node) error {
 	err := &ErrInvalidMergeType{dst: dst, src: src}
 	switch dst.Type() {
 	case DocumentType:
-		node := dst.(*DocumentNode)
+		node, _ := dst.(*DocumentNode)
 		return Merge(node.Body, src)
 	case MappingType:
-		node := dst.(*MappingNode)
+		node, _ := dst.(*MappingNode)
 		target, ok := src.(*MappingNode)
 		if !ok {
 			return err
@@ -2103,7 +2158,7 @@ func Merge(dst Node, src Node) error {
 		node.Merge(target)
 		return nil
 	case SequenceType:
-		node := dst.(*SequenceNode)
+		node, _ := dst.(*SequenceNode)
 		target, ok := src.(*SequenceNode)
 		if !ok {
 			return err
diff --git a/benchmarks/go.mod b/benchmarks/go.mod
index e167631..195db58 100644
--- a/benchmarks/go.mod
+++ b/benchmarks/go.mod
@@ -6,6 +6,6 @@ replace github.com/goccy/go-yaml => ../
 
 require (
 	github.com/goccy/go-yaml v0.0.0-00010101000000-000000000000
-	gopkg.in/yaml.v2 v2.3.0
-	gopkg.in/yaml.v3 v3.0.0-20200506231410-2ff61e1afc86
+	gopkg.in/yaml.v2 v2.4.0
+	gopkg.in/yaml.v3 v3.0.1
 )
diff --git a/benchmarks/go.sum b/benchmarks/go.sum
index 4bac589..3c36f01 100644
--- a/benchmarks/go.sum
+++ b/benchmarks/go.sum
@@ -1,39 +1,116 @@
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
-github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
-github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
-github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
-github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
-github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
-github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
-github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
-github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
-github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
-github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
-github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
+github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
+github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
+github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
+github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
+github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
+github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
-golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
+golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
+golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
+golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
+golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
+golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
+golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
+golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
+golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
+golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
+golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
+golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
+golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
+golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
-gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
-gopkg.in/go-playground/validator.v9 v9.30.0 h1:Wk0Z37oBmKj9/n+tPyBHZmeL19LaCoK3Qq48VwYENss=
-gopkg.in/go-playground/validator.v9 v9.30.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
-gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v3 v3.0.0-20200506231410-2ff61e1afc86 h1:OfFoIUYv/me30yv7XlMy4F9RJw8DEm8WQ6QG1Ph4bH0=
-gopkg.in/yaml.v3 v3.0.0-20200506231410-2ff61e1afc86/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/cmd/ycat/ycat.go b/cmd/ycat/ycat.go
index c70cb3b..b810b6f 100644
--- a/cmd/ycat/ycat.go
+++ b/cmd/ycat/ycat.go
@@ -3,14 +3,14 @@ package main
 import (
 	"errors"
 	"fmt"
-	"io/ioutil"
 	"os"
 
 	"github.com/fatih/color"
+	"github.com/mattn/go-colorable"
+
 	"github.com/goccy/go-yaml"
 	"github.com/goccy/go-yaml/lexer"
 	"github.com/goccy/go-yaml/printer"
-	"github.com/mattn/go-colorable"
 )
 
 const escape = "\x1b"
@@ -24,7 +24,7 @@ func _main(args []string) error {
 		return errors.New("ycat: usage: ycat file.yml")
 	}
 	filename := args[1]
-	bytes, err := ioutil.ReadFile(filename)
+	bytes, err := os.ReadFile(filename)
 	if err != nil {
 		return err
 	}
@@ -72,7 +72,7 @@ func _main(args []string) error {
 		}
 	}
 	writer := colorable.NewColorableStdout()
-	writer.Write([]byte(p.PrintTokens(tokens) + "\n"))
+	_, _ = writer.Write([]byte(p.PrintTokens(tokens) + "\n"))
 	return nil
 }
 
diff --git a/decode.go b/decode.go
index d3dbabc..9ff9f3e 100644
--- a/decode.go
+++ b/decode.go
@@ -7,7 +7,6 @@ import (
 	"encoding/base64"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"math"
 	"os"
 	"path/filepath"
@@ -20,7 +19,6 @@ import (
 	"github.com/goccy/go-yaml/internal/errors"
 	"github.com/goccy/go-yaml/parser"
 	"github.com/goccy/go-yaml/token"
-	"golang.org/x/xerrors"
 )
 
 // Decoder reads and decodes YAML values from an input stream.
@@ -28,6 +26,7 @@ type Decoder struct {
 	reader               io.Reader
 	referenceReaders     []io.Reader
 	anchorNodeMap        map[string]ast.Node
+	aliasValueMap        map[*ast.AliasNode]any
 	anchorValueMap       map[string]reflect.Value
 	customUnmarshalerMap map[reflect.Type]func(interface{}, []byte) error
 	toCommentMap         CommentMap
@@ -50,6 +49,7 @@ func NewDecoder(r io.Reader, opts ...DecodeOption) *Decoder {
 	return &Decoder{
 		reader:               r,
 		anchorNodeMap:        map[string]ast.Node{},
+		aliasValueMap:        make(map[*ast.AliasNode]any),
 		anchorValueMap:       map[string]reflect.Value{},
 		customUnmarshalerMap: map[reflect.Type]func(interface{}, []byte) error{},
 		opts:                 opts,
@@ -100,7 +100,7 @@ func (d *Decoder) castToFloat(v interface{}) interface{} {
 
 func (d *Decoder) mergeValueNode(value ast.Node) ast.Node {
 	if value.Type() == ast.AliasType {
-		aliasNode := value.(*ast.AliasNode)
+		aliasNode, _ := value.(*ast.AliasNode)
 		aliasName := aliasNode.Value.GetToken().Value
 		return d.anchorNodeMap[aliasName]
 	}
@@ -303,9 +303,19 @@ func (d *Decoder) nodeToValue(node ast.Node) interface{} {
 		d.anchorNodeMap[anchorName] = n.Value
 		return anchorValue
 	case *ast.AliasNode:
+		if v, exists := d.aliasValueMap[n]; exists {
+			return v
+		}
+		// To handle the case where alias is processed recursively, the result of alias can be set to nil in advance.
+		d.aliasValueMap[n] = nil
+
 		aliasName := n.Value.GetToken().Value
 		node := d.anchorNodeMap[aliasName]
-		return d.nodeToValue(node)
+		aliasValue := d.nodeToValue(node)
+
+		// once the correct alias value is obtained, overwrite with that value.
+		d.aliasValueMap[n] = aliasValue
+		return aliasValue
 	case *ast.LiteralNode:
 		return n.Value.GetValue()
 	case *ast.MappingKeyNode:
@@ -360,7 +370,7 @@ func (d *Decoder) resolveAlias(node ast.Node) (ast.Node, error) {
 			if err != nil {
 				return nil, err
 			}
-			n.Values[idx] = value.(*ast.MappingValueNode)
+			n.Values[idx], _ = value.(*ast.MappingValueNode)
 		}
 	case *ast.TagNode:
 		value, err := d.resolveAlias(n.Value)
@@ -389,7 +399,7 @@ func (d *Decoder) resolveAlias(node ast.Node) (ast.Node, error) {
 			if err != nil {
 				return nil, err
 			}
-			n.Key = key.(ast.MapKeyNode)
+			n.Key, _ = key.(ast.MapKeyNode)
 			value, err := d.resolveAlias(n.Value)
 			if err != nil {
 				return nil, err
@@ -408,7 +418,7 @@ func (d *Decoder) resolveAlias(node ast.Node) (ast.Node, error) {
 		aliasName := n.Value.GetToken().Value
 		node := d.anchorNodeMap[aliasName]
 		if node == nil {
-			return nil, xerrors.Errorf("cannot find anchor by alias name %s", aliasName)
+			return nil, fmt.Errorf("cannot find anchor by alias name %s", aliasName)
 		}
 		return d.resolveAlias(node)
 	}
@@ -430,7 +440,7 @@ func (d *Decoder) getMapNode(node ast.Node) (ast.MapNode, error) {
 		aliasName := alias.Value.GetToken().Value
 		node := d.anchorNodeMap[aliasName]
 		if node == nil {
-			return nil, xerrors.Errorf("cannot find anchor by alias name %s", aliasName)
+			return nil, fmt.Errorf("cannot find anchor by alias name %s", aliasName)
 		}
 		mapNode, ok := node.(ast.MapNode)
 		if ok {
@@ -461,7 +471,7 @@ func (d *Decoder) getArrayNode(node ast.Node) (ast.ArrayNode, error) {
 		aliasName := alias.Value.GetToken().Value
 		node := d.anchorNodeMap[aliasName]
 		if node == nil {
-			return nil, xerrors.Errorf("cannot find anchor by alias name %s", aliasName)
+			return nil, fmt.Errorf("cannot find anchor by alias name %s", aliasName)
 		}
 		arrayNode, ok := node.(ast.ArrayNode)
 		if ok {
@@ -476,18 +486,24 @@ func (d *Decoder) getArrayNode(node ast.Node) (ast.ArrayNode, error) {
 	return arrayNode, nil
 }
 
-func (d *Decoder) fileToNode(f *ast.File) ast.Node {
-	for _, doc := range f.Docs {
-		if v := d.nodeToValue(doc.Body); v != nil {
-			return doc.Body
-		}
-	}
-	return nil
-}
-
 func (d *Decoder) convertValue(v reflect.Value, typ reflect.Type, src ast.Node) (reflect.Value, error) {
 	if typ.Kind() != reflect.String {
 		if !v.Type().ConvertibleTo(typ) {
+
+			// Special case for "strings -> floats" aka scientific notation
+			// If the destination type is a float and the source type is a string, check if we can
+			// use strconv.ParseFloat to convert the string to a float.
+			if (typ.Kind() == reflect.Float32 || typ.Kind() == reflect.Float64) &&
+				v.Type().Kind() == reflect.String {
+				if f, err := strconv.ParseFloat(v.String(), 64); err == nil {
+					if typ.Kind() == reflect.Float32 {
+						return reflect.ValueOf(float32(f)), nil
+					} else if typ.Kind() == reflect.Float64 {
+						return reflect.ValueOf(f), nil
+					}
+					// else, fall through to the error below
+				}
+			}
 			return reflect.Zero(typ), errTypeMismatch(typ, v.Type(), src.GetToken())
 		}
 		return v.Convert(typ), nil
@@ -509,19 +525,6 @@ func (d *Decoder) convertValue(v reflect.Value, typ reflect.Type, src ast.Node)
 	return v.Convert(typ), nil
 }
 
-type overflowError struct {
-	dstType reflect.Type
-	srcNum  string
-}
-
-func (e *overflowError) Error() string {
-	return fmt.Sprintf("cannot unmarshal %s into Go value of type %s ( overflow )", e.srcNum, e.dstType)
-}
-
-func errOverflow(dstType reflect.Type, num string) *overflowError {
-	return &overflowError{dstType: dstType, srcNum: num}
-}
-
 func errTypeMismatch(dstType, srcType reflect.Type, token *token.Token) *errors.TypeError {
 	return &errors.TypeError{DstType: dstType, SrcType: srcType, Token: token}
 }
@@ -560,7 +563,7 @@ func (d *Decoder) deleteStructKeys(structType reflect.Type, unknownFields map[st
 	}
 	structFieldMap, err := structFieldMap(structType)
 	if err != nil {
-		return errors.Wrapf(err, "failed to create struct field map")
+		return err
 	}
 
 	for j := 0; j < structType.NumField(); j++ {
@@ -575,7 +578,7 @@ func (d *Decoder) deleteStructKeys(structType reflect.Type, unknownFields map[st
 		}
 
 		if structField.IsInline {
-			d.deleteStructKeys(field.Type, unknownFields)
+			_ = d.deleteStructKeys(field.Type, unknownFields)
 		} else {
 			delete(unknownFields, structField.RenderName)
 		}
@@ -698,10 +701,10 @@ func (d *Decoder) decodeByUnmarshaler(ctx context.Context, dst reflect.Value, sr
 	if unmarshaler, exists := d.unmarshalerFromCustomUnmarshalerMap(ptrValue.Type()); exists {
 		b, err := d.unmarshalableDocument(src)
 		if err != nil {
-			return errors.Wrapf(err, "failed to UnmarshalYAML")
+			return err
 		}
 		if err := unmarshaler(ptrValue.Interface(), b); err != nil {
-			return errors.Wrapf(err, "failed to UnmarshalYAML")
+			return err
 		}
 		return nil
 	}
@@ -710,10 +713,10 @@ func (d *Decoder) decodeByUnmarshaler(ctx context.Context, dst reflect.Value, sr
 	if unmarshaler, ok := iface.(BytesUnmarshalerContext); ok {
 		b, err := d.unmarshalableDocument(src)
 		if err != nil {
-			return errors.Wrapf(err, "failed to UnmarshalYAML")
+			return err
 		}
 		if err := unmarshaler.UnmarshalYAML(ctx, b); err != nil {
-			return errors.Wrapf(err, "failed to UnmarshalYAML")
+			return err
 		}
 		return nil
 	}
@@ -721,10 +724,10 @@ func (d *Decoder) decodeByUnmarshaler(ctx context.Context, dst reflect.Value, sr
 	if unmarshaler, ok := iface.(BytesUnmarshaler); ok {
 		b, err := d.unmarshalableDocument(src)
 		if err != nil {
-			return errors.Wrapf(err, "failed to UnmarshalYAML")
+			return err
 		}
 		if err := unmarshaler.UnmarshalYAML(b); err != nil {
-			return errors.Wrapf(err, "failed to UnmarshalYAML")
+			return err
 		}
 		return nil
 	}
@@ -733,14 +736,14 @@ func (d *Decoder) decodeByUnmarshaler(ctx context.Context, dst reflect.Value, sr
 		if err := unmarshaler.UnmarshalYAML(ctx, func(v interface{}) error {
 			rv := reflect.ValueOf(v)
 			if rv.Type().Kind() != reflect.Ptr {
-				return errors.ErrDecodeRequiredPointerType
+				return ErrDecodeRequiredPointerType
 			}
 			if err := d.decodeValue(ctx, rv.Elem(), src); err != nil {
-				return errors.Wrapf(err, "failed to decode value")
+				return err
 			}
 			return nil
 		}); err != nil {
-			return errors.Wrapf(err, "failed to UnmarshalYAML")
+			return err
 		}
 		return nil
 	}
@@ -749,14 +752,14 @@ func (d *Decoder) decodeByUnmarshaler(ctx context.Context, dst reflect.Value, sr
 		if err := unmarshaler.UnmarshalYAML(func(v interface{}) error {
 			rv := reflect.ValueOf(v)
 			if rv.Type().Kind() != reflect.Ptr {
-				return errors.ErrDecodeRequiredPointerType
+				return ErrDecodeRequiredPointerType
 			}
 			if err := d.decodeValue(ctx, rv.Elem(), src); err != nil {
-				return errors.Wrapf(err, "failed to decode value")
+				return err
 			}
 			return nil
 		}); err != nil {
-			return errors.Wrapf(err, "failed to UnmarshalYAML")
+			return err
 		}
 		return nil
 	}
@@ -772,11 +775,11 @@ func (d *Decoder) decodeByUnmarshaler(ctx context.Context, dst reflect.Value, sr
 	if unmarshaler, isText := iface.(encoding.TextUnmarshaler); isText {
 		b, ok, err := d.unmarshalableText(src)
 		if err != nil {
-			return errors.Wrapf(err, "failed to UnmarshalText")
+			return err
 		}
 		if ok {
 			if err := unmarshaler.UnmarshalText(b); err != nil {
-				return errors.Wrapf(err, "failed to UnmarshalText")
+				return err
 			}
 			return nil
 		}
@@ -786,21 +789,21 @@ func (d *Decoder) decodeByUnmarshaler(ctx context.Context, dst reflect.Value, sr
 		if unmarshaler, ok := iface.(jsonUnmarshaler); ok {
 			b, err := d.unmarshalableDocument(src)
 			if err != nil {
-				return errors.Wrapf(err, "failed to UnmarshalJSON")
+				return err
 			}
 			jsonBytes, err := YAMLToJSON(b)
 			if err != nil {
-				return errors.Wrapf(err, "failed to convert yaml to json")
+				return err
 			}
 			jsonBytes = bytes.TrimRight(jsonBytes, "\n")
 			if err := unmarshaler.UnmarshalJSON(jsonBytes); err != nil {
-				return errors.Wrapf(err, "failed to UnmarshalJSON")
+				return err
 			}
 			return nil
 		}
 	}
 
-	return xerrors.Errorf("does not implemented Unmarshaler")
+	return fmt.Errorf("does not implemented Unmarshaler")
 }
 
 var (
@@ -816,7 +819,7 @@ func (d *Decoder) decodeValue(ctx context.Context, dst reflect.Value, src ast.No
 	}
 	if d.canDecodeByUnmarshaler(dst) {
 		if err := d.decodeByUnmarshaler(ctx, dst, src); err != nil {
-			return errors.Wrapf(err, "failed to decode by unmarshaler")
+			return err
 		}
 		return nil
 	}
@@ -833,7 +836,7 @@ func (d *Decoder) decodeValue(ctx context.Context, dst reflect.Value, src ast.No
 		}
 		v := d.createDecodableValue(dst.Type())
 		if err := d.decodeValue(ctx, v, src); err != nil {
-			return errors.Wrapf(err, "failed to decode ptr value")
+			return err
 		}
 		dst.Set(d.castToAssignableValue(v, dst.Type()))
 	case reflect.Interface:
@@ -877,10 +880,19 @@ func (d *Decoder) decodeValue(ctx context.Context, dst reflect.Value, src ast.No
 				dst.SetInt(int64(vv))
 				return nil
 			}
+		case string: // handle scientific notation
+			if i, err := strconv.ParseFloat(vv, 64); err == nil {
+				if 0 <= i && i <= math.MaxUint64 && !dst.OverflowInt(int64(i)) {
+					dst.SetInt(int64(i))
+					return nil
+				}
+			} else { // couldn't be parsed as float
+				return errTypeMismatch(valueType, reflect.TypeOf(v), src.GetToken())
+			}
 		default:
 			return errTypeMismatch(valueType, reflect.TypeOf(v), src.GetToken())
 		}
-		return errOverflow(valueType, fmt.Sprint(v))
+		return errors.ErrOverflow(valueType, fmt.Sprint(v), src.GetToken())
 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
 		v := d.nodeToValue(src)
 		switch vv := v.(type) {
@@ -899,16 +911,26 @@ func (d *Decoder) decodeValue(ctx context.Context, dst reflect.Value, src ast.No
 				dst.SetUint(uint64(vv))
 				return nil
 			}
+		case string: // handle scientific notation
+			if i, err := strconv.ParseFloat(vv, 64); err == nil {
+				if 0 <= i && i <= math.MaxUint64 && !dst.OverflowUint(uint64(i)) {
+					dst.SetUint(uint64(i))
+					return nil
+				}
+			} else { // couldn't be parsed as float
+				return errTypeMismatch(valueType, reflect.TypeOf(v), src.GetToken())
+			}
+
 		default:
 			return errTypeMismatch(valueType, reflect.TypeOf(v), src.GetToken())
 		}
-		return errOverflow(valueType, fmt.Sprint(v))
+		return errors.ErrOverflow(valueType, fmt.Sprint(v), src.GetToken())
 	}
 	v := reflect.ValueOf(d.nodeToValue(src))
 	if v.IsValid() {
 		convertedValue, err := d.convertValue(v, dst.Type(), src)
 		if err != nil {
-			return errors.Wrapf(err, "failed to convert value")
+			return err
 		}
 		dst.Set(convertedValue)
 	}
@@ -955,18 +977,22 @@ func (d *Decoder) createDecodedNewValue(
 			return newValue, nil
 		}
 	}
+	var newValue reflect.Value
 	if node.Type() == ast.NullType {
-		return reflect.Zero(typ), nil
+		newValue = reflect.New(typ).Elem()
+	} else {
+		newValue = d.createDecodableValue(typ)
 	}
-	newValue := d.createDecodableValue(typ)
 	for defaultVal.Kind() == reflect.Ptr {
 		defaultVal = defaultVal.Elem()
 	}
 	if defaultVal.IsValid() && defaultVal.Type().AssignableTo(newValue.Type()) {
 		newValue.Set(defaultVal)
 	}
-	if err := d.decodeValue(ctx, newValue, node); err != nil {
-		return newValue, errors.Wrapf(err, "failed to decode value")
+	if node.Type() != ast.NullType {
+		if err := d.decodeValue(ctx, newValue, node); err != nil {
+			return newValue, err
+		}
 	}
 	return newValue, nil
 }
@@ -974,7 +1000,7 @@ func (d *Decoder) createDecodedNewValue(
 func (d *Decoder) keyToNodeMap(node ast.Node, ignoreMergeKey bool, getKeyOrValueNode func(*ast.MapNodeIter) ast.Node) (map[string]ast.Node, error) {
 	mapNode, err := d.getMapNode(node)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to get map node")
+		return nil, err
 	}
 	keyMap := map[string]struct{}{}
 	keyToNodeMap := map[string]ast.Node{}
@@ -990,21 +1016,21 @@ func (d *Decoder) keyToNodeMap(node ast.Node, ignoreMergeKey bool, getKeyOrValue
 			}
 			mergeMap, err := d.keyToNodeMap(mapIter.Value(), ignoreMergeKey, getKeyOrValueNode)
 			if err != nil {
-				return nil, errors.Wrapf(err, "failed to get keyToNodeMap by MergeKey node")
+				return nil, err
 			}
 			for k, v := range mergeMap {
 				if err := d.validateDuplicateKey(keyMap, k, v); err != nil {
-					return nil, errors.Wrapf(err, "invalid struct key")
+					return nil, err
 				}
 				keyToNodeMap[k] = v
 			}
 		} else {
 			key, ok := d.nodeToValue(keyNode).(string)
 			if !ok {
-				return nil, errors.Wrapf(err, "failed to decode map key")
+				return nil, err
 			}
 			if err := d.validateDuplicateKey(keyMap, key, keyNode); err != nil {
-				return nil, errors.Wrapf(err, "invalid struct key")
+				return nil, err
 			}
 			keyToNodeMap[key] = getKeyOrValueNode(mapIter)
 		}
@@ -1015,7 +1041,7 @@ func (d *Decoder) keyToNodeMap(node ast.Node, ignoreMergeKey bool, getKeyOrValue
 func (d *Decoder) keyToKeyNodeMap(node ast.Node, ignoreMergeKey bool) (map[string]ast.Node, error) {
 	m, err := d.keyToNodeMap(node, ignoreMergeKey, func(nodeMap *ast.MapNodeIter) ast.Node { return nodeMap.Key() })
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to get keyToNodeMap")
+		return nil, err
 	}
 	return m, nil
 }
@@ -1023,7 +1049,7 @@ func (d *Decoder) keyToKeyNodeMap(node ast.Node, ignoreMergeKey bool) (map[strin
 func (d *Decoder) keyToValueNodeMap(node ast.Node, ignoreMergeKey bool) (map[string]ast.Node, error) {
 	m, err := d.keyToNodeMap(node, ignoreMergeKey, func(nodeMap *ast.MapNodeIter) ast.Node { return nodeMap.Value() })
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to get keyToNodeMap")
+		return nil, err
 	}
 	return m, nil
 }
@@ -1035,7 +1061,7 @@ func (d *Decoder) setDefaultValueIfConflicted(v reflect.Value, fieldMap StructFi
 	}
 	embeddedStructFieldMap, err := structFieldMap(typ)
 	if err != nil {
-		return errors.Wrapf(err, "failed to get struct field map by embedded type")
+		return err
 	}
 	for i := 0; i < typ.NumField(); i++ {
 		field := typ.Field(i)
@@ -1090,7 +1116,7 @@ func (d *Decoder) castToTime(src ast.Node) (time.Time, error) {
 func (d *Decoder) decodeTime(ctx context.Context, dst reflect.Value, src ast.Node) error {
 	t, err := d.castToTime(src)
 	if err != nil {
-		return errors.Wrapf(err, "failed to convert to time")
+		return err
 	}
 	dst.Set(reflect.ValueOf(t))
 	return nil
@@ -1110,7 +1136,7 @@ func (d *Decoder) castToDuration(src ast.Node) (time.Duration, error) {
 	}
 	t, err := time.ParseDuration(s)
 	if err != nil {
-		return 0, errors.Wrapf(err, "failed to parse duration")
+		return 0, err
 	}
 	return t, nil
 }
@@ -1118,7 +1144,7 @@ func (d *Decoder) castToDuration(src ast.Node) (time.Duration, error) {
 func (d *Decoder) decodeDuration(ctx context.Context, dst reflect.Value, src ast.Node) error {
 	t, err := d.castToDuration(src)
 	if err != nil {
-		return errors.Wrapf(err, "failed to convert to duration")
+		return err
 	}
 	dst.Set(reflect.ValueOf(t))
 	return nil
@@ -1162,18 +1188,18 @@ func (d *Decoder) decodeStruct(ctx context.Context, dst reflect.Value, src ast.N
 	}
 	structFieldMap, err := structFieldMap(structType)
 	if err != nil {
-		return errors.Wrapf(err, "failed to create struct field map")
+		return err
 	}
 	ignoreMergeKey := structFieldMap.hasMergeProperty()
 	keyToNodeMap, err := d.keyToValueNodeMap(src, ignoreMergeKey)
 	if err != nil {
-		return errors.Wrapf(err, "failed to get keyToValueNodeMap")
+		return err
 	}
 	var unknownFields map[string]ast.Node
 	if d.disallowUnknownField {
 		unknownFields, err = d.keyToKeyNodeMap(src, ignoreMergeKey)
 		if err != nil {
-			return errors.Wrapf(err, "failed to get keyToKeyNodeMap")
+			return err
 		}
 	}
 
@@ -1198,7 +1224,7 @@ func (d *Decoder) decodeStruct(ctx context.Context, dst reflect.Value, src ast.N
 				continue
 			}
 			if !fieldValue.CanSet() {
-				return xerrors.Errorf("cannot set embedded type as unexported field %s.%s", field.PkgPath, field.Name)
+				return fmt.Errorf("cannot set embedded type as unexported field %s.%s", field.PkgPath, field.Name)
 			}
 			if fieldValue.Type().Kind() == reflect.Ptr && src.Type() == ast.NullType {
 				// set nil value to pointer
@@ -1213,7 +1239,7 @@ func (d *Decoder) decodeStruct(ctx context.Context, dst reflect.Value, src ast.N
 			newFieldValue, err := d.createDecodedNewValue(ctx, fieldValue.Type(), fieldValue, mapNode)
 			if d.disallowUnknownField {
 				if err := d.deleteStructKeys(fieldValue.Type(), unknownFields); err != nil {
-					return errors.Wrapf(err, "cannot delete struct keys")
+					return err
 				}
 			}
 
@@ -1222,7 +1248,7 @@ func (d *Decoder) decodeStruct(ctx context.Context, dst reflect.Value, src ast.N
 					continue
 				}
 				var te *errors.TypeError
-				if xerrors.As(err, &te) {
+				if errors.As(err, &te) {
 					if te.StructFieldName != nil {
 						fieldName := fmt.Sprintf("%s.%s", structType.Name(), *te.StructFieldName)
 						te.StructFieldName = &fieldName
@@ -1237,7 +1263,7 @@ func (d *Decoder) decodeStruct(ctx context.Context, dst reflect.Value, src ast.N
 				}
 				continue
 			}
-			d.setDefaultValueIfConflicted(newFieldValue, structFieldMap)
+			_ = d.setDefaultValueIfConflicted(newFieldValue, structFieldMap)
 			fieldValue.Set(d.castToAssignableValue(newFieldValue, fieldValue.Type()))
 			continue
 		}
@@ -1258,7 +1284,7 @@ func (d *Decoder) decodeStruct(ctx context.Context, dst reflect.Value, src ast.N
 				continue
 			}
 			var te *errors.TypeError
-			if xerrors.As(err, &te) {
+			if errors.As(err, &te) {
 				fieldName := fmt.Sprintf("%s.%s", structType.Name(), field.Name)
 				te.StructFieldName = &fieldName
 				foundErr = te
@@ -1270,7 +1296,7 @@ func (d *Decoder) decodeStruct(ctx context.Context, dst reflect.Value, src ast.N
 		fieldValue.Set(d.castToAssignableValue(newFieldValue, fieldValue.Type()))
 	}
 	if foundErr != nil {
-		return errors.Wrapf(foundErr, "failed to decode value")
+		return foundErr
 	}
 
 	// Ignore unknown fields when parsing an inline struct (recognized by a nil token).
@@ -1315,7 +1341,7 @@ func (d *Decoder) decodeStruct(ctx context.Context, dst reflect.Value, src ast.N
 func (d *Decoder) decodeArray(ctx context.Context, dst reflect.Value, src ast.Node) error {
 	arrayNode, err := d.getArrayNode(src)
 	if err != nil {
-		return errors.Wrapf(err, "failed to get array node")
+		return err
 	}
 	if arrayNode == nil {
 		return nil
@@ -1347,7 +1373,7 @@ func (d *Decoder) decodeArray(ctx context.Context, dst reflect.Value, src ast.No
 	}
 	dst.Set(arrayValue)
 	if foundErr != nil {
-		return errors.Wrapf(foundErr, "failed to decode value")
+		return foundErr
 	}
 	return nil
 }
@@ -1355,7 +1381,7 @@ func (d *Decoder) decodeArray(ctx context.Context, dst reflect.Value, src ast.No
 func (d *Decoder) decodeSlice(ctx context.Context, dst reflect.Value, src ast.Node) error {
 	arrayNode, err := d.getArrayNode(src)
 	if err != nil {
-		return errors.Wrapf(err, "failed to get array node")
+		return err
 	}
 	if arrayNode == nil {
 		return nil
@@ -1384,7 +1410,7 @@ func (d *Decoder) decodeSlice(ctx context.Context, dst reflect.Value, src ast.No
 	}
 	dst.Set(sliceValue)
 	if foundErr != nil {
-		return errors.Wrapf(foundErr, "failed to decode value")
+		return foundErr
 	}
 	return nil
 }
@@ -1392,7 +1418,7 @@ func (d *Decoder) decodeSlice(ctx context.Context, dst reflect.Value, src ast.No
 func (d *Decoder) decodeMapItem(ctx context.Context, dst *MapItem, src ast.Node) error {
 	mapNode, err := d.getMapNode(src)
 	if err != nil {
-		return errors.Wrapf(err, "failed to get map node")
+		return err
 	}
 	if mapNode == nil {
 		return nil
@@ -1405,7 +1431,7 @@ func (d *Decoder) decodeMapItem(ctx context.Context, dst *MapItem, src ast.Node)
 	value := mapIter.Value()
 	if key.Type() == ast.MergeKeyType {
 		if err := d.decodeMapItem(ctx, dst, value); err != nil {
-			return errors.Wrapf(err, "failed to decode map with merge key")
+			return err
 		}
 		return nil
 	}
@@ -1433,7 +1459,7 @@ func (d *Decoder) validateDuplicateKey(keyMap map[string]struct{}, key interface
 func (d *Decoder) decodeMapSlice(ctx context.Context, dst *MapSlice, src ast.Node) error {
 	mapNode, err := d.getMapNode(src)
 	if err != nil {
-		return errors.Wrapf(err, "failed to get map node")
+		return err
 	}
 	if mapNode == nil {
 		return nil
@@ -1447,11 +1473,11 @@ func (d *Decoder) decodeMapSlice(ctx context.Context, dst *MapSlice, src ast.Nod
 		if key.Type() == ast.MergeKeyType {
 			var m MapSlice
 			if err := d.decodeMapSlice(ctx, &m, value); err != nil {
-				return errors.Wrapf(err, "failed to decode map with merge key")
+				return err
 			}
 			for _, v := range m {
 				if err := d.validateDuplicateKey(keyMap, v.Key, value); err != nil {
-					return errors.Wrapf(err, "invalid map key")
+					return err
 				}
 				mapSlice = append(mapSlice, v)
 			}
@@ -1459,7 +1485,7 @@ func (d *Decoder) decodeMapSlice(ctx context.Context, dst *MapSlice, src ast.Nod
 		}
 		k := d.nodeToValue(key)
 		if err := d.validateDuplicateKey(keyMap, k, key); err != nil {
-			return errors.Wrapf(err, "invalid map key")
+			return err
 		}
 		mapSlice = append(mapSlice, MapItem{
 			Key:   k,
@@ -1473,7 +1499,7 @@ func (d *Decoder) decodeMapSlice(ctx context.Context, dst *MapSlice, src ast.Nod
 func (d *Decoder) decodeMap(ctx context.Context, dst reflect.Value, src ast.Node) error {
 	mapNode, err := d.getMapNode(src)
 	if err != nil {
-		return errors.Wrapf(err, "failed to get map node")
+		return err
 	}
 	if mapNode == nil {
 		return nil
@@ -1490,24 +1516,33 @@ func (d *Decoder) decodeMap(ctx context.Context, dst reflect.Value, src ast.Node
 		value := mapIter.Value()
 		if key.Type() == ast.MergeKeyType {
 			if err := d.decodeMap(ctx, dst, value); err != nil {
-				return errors.Wrapf(err, "failed to decode map with merge key")
+				return err
 			}
 			iter := dst.MapRange()
 			for iter.Next() {
 				if err := d.validateDuplicateKey(keyMap, iter.Key(), value); err != nil {
-					return errors.Wrapf(err, "invalid map key")
+					return err
 				}
 				mapValue.SetMapIndex(iter.Key(), iter.Value())
 			}
 			continue
 		}
-		k := reflect.ValueOf(d.nodeToValue(key))
-		if k.IsValid() && k.Type().ConvertibleTo(keyType) {
-			k = k.Convert(keyType)
+
+		k := d.createDecodableValue(keyType)
+		if d.canDecodeByUnmarshaler(k) {
+			if err := d.decodeByUnmarshaler(ctx, k, key); err != nil {
+				return err
+			}
+		} else {
+			k = reflect.ValueOf(d.nodeToValue(key))
+			if k.IsValid() && k.Type().ConvertibleTo(keyType) {
+				k = k.Convert(keyType)
+			}
 		}
+
 		if k.IsValid() {
 			if err := d.validateDuplicateKey(keyMap, k.Interface(), key); err != nil {
-				return errors.Wrapf(err, "invalid map key")
+				return err
 			}
 		}
 		if valueType.Kind() == reflect.Ptr && value.Type() == ast.NullType {
@@ -1530,7 +1565,7 @@ func (d *Decoder) decodeMap(ctx context.Context, dst reflect.Value, src ast.Node
 	}
 	dst.Set(mapValue)
 	if foundErr != nil {
-		return errors.Wrapf(foundErr, "failed to decode value")
+		return foundErr
 	}
 	return nil
 }
@@ -1538,7 +1573,7 @@ func (d *Decoder) decodeMap(ctx context.Context, dst reflect.Value, src ast.Node
 func (d *Decoder) fileToReader(file string) (io.Reader, error) {
 	reader, err := os.Open(file)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to open file")
+		return nil, err
 	}
 	return reader, nil
 }
@@ -1558,7 +1593,7 @@ func (d *Decoder) readersUnderDir(dir string) ([]io.Reader, error) {
 	pattern := fmt.Sprintf("%s/*", dir)
 	matches, err := filepath.Glob(pattern)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to get files by %s", pattern)
+		return nil, err
 	}
 	readers := []io.Reader{}
 	for _, match := range matches {
@@ -1567,7 +1602,7 @@ func (d *Decoder) readersUnderDir(dir string) ([]io.Reader, error) {
 		}
 		reader, err := d.fileToReader(match)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to get reader")
+			return nil, err
 		}
 		readers = append(readers, reader)
 	}
@@ -1576,18 +1611,18 @@ func (d *Decoder) readersUnderDir(dir string) ([]io.Reader, error) {
 
 func (d *Decoder) readersUnderDirRecursive(dir string) ([]io.Reader, error) {
 	readers := []io.Reader{}
-	if err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
+	if err := filepath.Walk(dir, func(path string, info os.FileInfo, _ error) error {
 		if !d.isYAMLFile(path) {
 			return nil
 		}
-		reader, err := d.fileToReader(path)
-		if err != nil {
-			return errors.Wrapf(err, "failed to get reader")
+		reader, readerErr := d.fileToReader(path)
+		if readerErr != nil {
+			return readerErr
 		}
 		readers = append(readers, reader)
 		return nil
 	}); err != nil {
-		return nil, errors.Wrapf(err, "interrupt walk in %s", dir)
+		return nil, err
 	}
 	return readers, nil
 }
@@ -1595,13 +1630,13 @@ func (d *Decoder) readersUnderDirRecursive(dir string) ([]io.Reader, error) {
 func (d *Decoder) resolveReference() error {
 	for _, opt := range d.opts {
 		if err := opt(d); err != nil {
-			return errors.Wrapf(err, "failed to exec option")
+			return err
 		}
 	}
 	for _, file := range d.referenceFiles {
 		reader, err := d.fileToReader(file)
 		if err != nil {
-			return errors.Wrapf(err, "failed to get reader")
+			return err
 		}
 		d.referenceReaders = append(d.referenceReaders, reader)
 	}
@@ -1609,26 +1644,26 @@ func (d *Decoder) resolveReference() error {
 		if !d.isRecursiveDir {
 			readers, err := d.readersUnderDir(dir)
 			if err != nil {
-				return errors.Wrapf(err, "failed to get readers from under the %s", dir)
+				return err
 			}
 			d.referenceReaders = append(d.referenceReaders, readers...)
 		} else {
 			readers, err := d.readersUnderDirRecursive(dir)
 			if err != nil {
-				return errors.Wrapf(err, "failed to get readers from under the %s", dir)
+				return err
 			}
 			d.referenceReaders = append(d.referenceReaders, readers...)
 		}
 	}
 	for _, reader := range d.referenceReaders {
-		bytes, err := ioutil.ReadAll(reader)
+		bytes, err := io.ReadAll(reader)
 		if err != nil {
-			return errors.Wrapf(err, "failed to read buffer")
+			return err
 		}
 
 		// assign new anchor definition to anchorMap
 		if _, err := d.parse(bytes); err != nil {
-			return errors.Wrapf(err, "failed to decode")
+			return err
 		}
 	}
 	d.isResolvedReference = true
@@ -1642,7 +1677,7 @@ func (d *Decoder) parse(bytes []byte) (*ast.File, error) {
 	}
 	f, err := parser.ParseBytes(bytes, parseMode)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse yaml")
+		return nil, err
 	}
 	normalizedFile := &ast.File{}
 	for _, doc := range f.Docs {
@@ -1661,16 +1696,16 @@ func (d *Decoder) isInitialized() bool {
 func (d *Decoder) decodeInit() error {
 	if !d.isResolvedReference {
 		if err := d.resolveReference(); err != nil {
-			return errors.Wrapf(err, "failed to resolve reference")
+			return err
 		}
 	}
 	var buf bytes.Buffer
 	if _, err := io.Copy(&buf, d.reader); err != nil {
-		return errors.Wrapf(err, "failed to copy from reader")
+		return err
 	}
 	file, err := d.parse(buf.Bytes())
 	if err != nil {
-		return errors.Wrapf(err, "failed to decode")
+		return err
 	}
 	d.parsedFile = file
 	return nil
@@ -1685,7 +1720,7 @@ func (d *Decoder) decode(ctx context.Context, v reflect.Value) error {
 		return nil
 	}
 	if err := d.decodeValue(ctx, v.Elem(), body); err != nil {
-		return errors.Wrapf(err, "failed to decode value")
+		return err
 	}
 	d.streamIndex++
 	return nil
@@ -1705,25 +1740,25 @@ func (d *Decoder) Decode(v interface{}) error {
 func (d *Decoder) DecodeContext(ctx context.Context, v interface{}) error {
 	rv := reflect.ValueOf(v)
 	if rv.Type().Kind() != reflect.Ptr {
-		return errors.ErrDecodeRequiredPointerType
+		return ErrDecodeRequiredPointerType
 	}
 	if d.isInitialized() {
 		if err := d.decode(ctx, rv); err != nil {
 			if err == io.EOF {
 				return err
 			}
-			return errors.Wrapf(err, "failed to decode")
+			return err
 		}
 		return nil
 	}
 	if err := d.decodeInit(); err != nil {
-		return errors.Wrapf(err, "failed to decodeInit")
+		return err
 	}
 	if err := d.decode(ctx, rv); err != nil {
 		if err == io.EOF {
 			return err
 		}
-		return errors.Wrapf(err, "failed to decode")
+		return err
 	}
 	return nil
 }
@@ -1737,17 +1772,17 @@ func (d *Decoder) DecodeFromNode(node ast.Node, v interface{}) error {
 func (d *Decoder) DecodeFromNodeContext(ctx context.Context, node ast.Node, v interface{}) error {
 	rv := reflect.ValueOf(v)
 	if rv.Type().Kind() != reflect.Ptr {
-		return errors.ErrDecodeRequiredPointerType
+		return ErrDecodeRequiredPointerType
 	}
 	if !d.isInitialized() {
 		if err := d.decodeInit(); err != nil {
-			return errors.Wrapf(err, "failed to decodInit")
+			return err
 		}
 	}
 	// resolve references to the anchor on the same file
 	d.nodeToValue(node)
 	if err := d.decodeValue(ctx, rv.Elem(), node); err != nil {
-		return errors.Wrapf(err, "failed to decode value")
+		return err
 	}
 	return nil
 }
diff --git a/encode.go b/encode.go
index 3b9b298..97c1fa5 100644
--- a/encode.go
+++ b/encode.go
@@ -17,7 +17,6 @@ import (
 	"github.com/goccy/go-yaml/parser"
 	"github.com/goccy/go-yaml/printer"
 	"github.com/goccy/go-yaml/token"
-	"golang.org/x/xerrors"
 )
 
 const (
@@ -84,19 +83,19 @@ func (e *Encoder) Encode(v interface{}) error {
 func (e *Encoder) EncodeContext(ctx context.Context, v interface{}) error {
 	node, err := e.EncodeToNodeContext(ctx, v)
 	if err != nil {
-		return errors.Wrapf(err, "failed to encode to node")
+		return err
 	}
 	if err := e.setCommentByCommentMap(node); err != nil {
-		return errors.Wrapf(err, "failed to set comment by comment map")
+		return err
 	}
 	if !e.written {
 		e.written = true
 	} else {
 		// write document separator
-		e.writer.Write([]byte("---\n"))
+		_, _ = e.writer.Write([]byte("---\n"))
 	}
 	var p printer.Printer
-	e.writer.Write(p.PrintNode(node))
+	_, _ = e.writer.Write(p.PrintNode(node))
 	return nil
 }
 
@@ -109,12 +108,12 @@ func (e *Encoder) EncodeToNode(v interface{}) (ast.Node, error) {
 func (e *Encoder) EncodeToNodeContext(ctx context.Context, v interface{}) (ast.Node, error) {
 	for _, opt := range e.opts {
 		if err := opt(e); err != nil {
-			return nil, errors.Wrapf(err, "failed to run option for encoder")
+			return nil, err
 		}
 	}
 	node, err := e.encodeValue(ctx, reflect.ValueOf(v), 1)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to encode value")
+		return nil, err
 	}
 	return node, nil
 }
@@ -126,7 +125,7 @@ func (e *Encoder) setCommentByCommentMap(node ast.Node) error {
 	for path, comments := range e.commentMap {
 		n, err := path.FilterNode(node)
 		if err != nil {
-			return errors.Wrapf(err, "failed to filter node")
+			return err
 		}
 		if n == nil {
 			continue
@@ -140,15 +139,15 @@ func (e *Encoder) setCommentByCommentMap(node ast.Node) error {
 			switch comment.Position {
 			case CommentHeadPosition:
 				if err := e.setHeadComment(node, n, commentGroup); err != nil {
-					return errors.Wrapf(err, "failed to set head comment")
+					return err
 				}
 			case CommentLinePosition:
 				if err := e.setLineComment(node, n, commentGroup); err != nil {
-					return errors.Wrapf(err, "failed to set line comment")
+					return err
 				}
 			case CommentFootPosition:
 				if err := e.setFootComment(node, n, commentGroup); err != nil {
-					return errors.Wrapf(err, "failed to set foot comment")
+					return err
 				}
 			default:
 				return ErrUnknownCommentPositionType
@@ -166,11 +165,11 @@ func (e *Encoder) setHeadComment(node ast.Node, filtered ast.Node, comment *ast.
 	switch p := parent.(type) {
 	case *ast.MappingValueNode:
 		if err := p.SetComment(comment); err != nil {
-			return errors.Wrapf(err, "failed to set comment")
+			return err
 		}
 	case *ast.MappingNode:
 		if err := p.SetComment(comment); err != nil {
-			return errors.Wrapf(err, "failed to set comment")
+			return err
 		}
 	case *ast.SequenceNode:
 		if len(p.ValueHeadComments) == 0 {
@@ -196,11 +195,11 @@ func (e *Encoder) setLineComment(node ast.Node, filtered ast.Node, comment *ast.
 		// Line comment cannot be set for mapping value node.
 		// It should probably be set for the parent map node
 		if err := e.setLineCommentToParentMapNode(node, filtered, comment); err != nil {
-			return errors.Wrapf(err, "failed to set line comment to parent node")
+			return err
 		}
 	default:
 		if err := filtered.SetComment(comment); err != nil {
-			return errors.Wrapf(err, "failed to set comment")
+			return err
 		}
 	}
 	return nil
@@ -214,11 +213,11 @@ func (e *Encoder) setLineCommentToParentMapNode(node ast.Node, filtered ast.Node
 	switch p := parent.(type) {
 	case *ast.MappingValueNode:
 		if err := p.Key.SetComment(comment); err != nil {
-			return errors.Wrapf(err, "failed to set comment")
+			return err
 		}
 	case *ast.MappingNode:
 		if err := p.SetComment(comment); err != nil {
-			return errors.Wrapf(err, "failed to set comment")
+			return err
 		}
 	default:
 		return ErrUnsupportedLinePositionType(parent)
@@ -247,7 +246,7 @@ func (e *Encoder) setFootComment(node ast.Node, filtered ast.Node, comment *ast.
 func (e *Encoder) encodeDocument(doc []byte) (ast.Node, error) {
 	f, err := parser.ParseBytes(doc, 0)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse yaml")
+		return nil, err
 	}
 	for _, docNode := range f.Docs {
 		if docNode.Body != nil {
@@ -336,11 +335,11 @@ func (e *Encoder) encodeByMarshaler(ctx context.Context, v reflect.Value, column
 	if marshaler, exists := e.marshalerFromCustomMarshalerMap(v.Type()); exists {
 		doc, err := marshaler(iface)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to MarshalYAML")
+			return nil, err
 		}
 		node, err := e.encodeDocument(doc)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to encode document")
+			return nil, err
 		}
 		return node, nil
 	}
@@ -348,11 +347,11 @@ func (e *Encoder) encodeByMarshaler(ctx context.Context, v reflect.Value, column
 	if marshaler, ok := iface.(BytesMarshalerContext); ok {
 		doc, err := marshaler.MarshalYAML(ctx)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to MarshalYAML")
+			return nil, err
 		}
 		node, err := e.encodeDocument(doc)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to encode document")
+			return nil, err
 		}
 		return node, nil
 	}
@@ -360,11 +359,11 @@ func (e *Encoder) encodeByMarshaler(ctx context.Context, v reflect.Value, column
 	if marshaler, ok := iface.(BytesMarshaler); ok {
 		doc, err := marshaler.MarshalYAML()
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to MarshalYAML")
+			return nil, err
 		}
 		node, err := e.encodeDocument(doc)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to encode document")
+			return nil, err
 		}
 		return node, nil
 	}
@@ -372,7 +371,7 @@ func (e *Encoder) encodeByMarshaler(ctx context.Context, v reflect.Value, column
 	if marshaler, ok := iface.(InterfaceMarshalerContext); ok {
 		marshalV, err := marshaler.MarshalYAML(ctx)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to MarshalYAML")
+			return nil, err
 		}
 		return e.encodeValue(ctx, reflect.ValueOf(marshalV), column)
 	}
@@ -380,7 +379,7 @@ func (e *Encoder) encodeByMarshaler(ctx context.Context, v reflect.Value, column
 	if marshaler, ok := iface.(InterfaceMarshaler); ok {
 		marshalV, err := marshaler.MarshalYAML()
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to MarshalYAML")
+			return nil, err
 		}
 		return e.encodeValue(ctx, reflect.ValueOf(marshalV), column)
 	}
@@ -396,11 +395,11 @@ func (e *Encoder) encodeByMarshaler(ctx context.Context, v reflect.Value, column
 	if marshaler, ok := iface.(encoding.TextMarshaler); ok {
 		doc, err := marshaler.MarshalText()
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to MarshalText")
+			return nil, err
 		}
 		node, err := e.encodeDocument(doc)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to encode document")
+			return nil, err
 		}
 		return node, nil
 	}
@@ -409,21 +408,21 @@ func (e *Encoder) encodeByMarshaler(ctx context.Context, v reflect.Value, column
 		if marshaler, ok := iface.(jsonMarshaler); ok {
 			jsonBytes, err := marshaler.MarshalJSON()
 			if err != nil {
-				return nil, errors.Wrapf(err, "failed to MarshalJSON")
+				return nil, err
 			}
 			doc, err := JSONToYAML(jsonBytes)
 			if err != nil {
-				return nil, errors.Wrapf(err, "failed to convert json to yaml")
+				return nil, err
 			}
 			node, err := e.encodeDocument(doc)
 			if err != nil {
-				return nil, errors.Wrapf(err, "failed to encode document")
+				return nil, err
 			}
 			return node, nil
 		}
 	}
 
-	return nil, xerrors.Errorf("does not implemented Marshaler")
+	return nil, errors.New("does not implemented Marshaler")
 }
 
 func (e *Encoder) encodeValue(ctx context.Context, v reflect.Value, column int) (ast.Node, error) {
@@ -433,7 +432,7 @@ func (e *Encoder) encodeValue(ctx context.Context, v reflect.Value, column int)
 	if e.canEncodeByMarshaler(v) {
 		node, err := e.encodeByMarshaler(ctx, v, column)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to encode by marshaler")
+			return nil, err
 		}
 		return node, nil
 	}
@@ -481,7 +480,7 @@ func (e *Encoder) encodeValue(ctx context.Context, v reflect.Value, column int)
 	case reflect.Map:
 		return e.encodeMap(ctx, v, column), nil
 	default:
-		return nil, xerrors.Errorf("unknown value type %s", v.Type().String())
+		return nil, fmt.Errorf("unknown value type %s", v.Type().String())
 	}
 }
 
@@ -570,7 +569,7 @@ func (e *Encoder) encodeSlice(ctx context.Context, value reflect.Value) (*ast.Se
 	for i := 0; i < value.Len(); i++ {
 		node, err := e.encodeValue(ctx, value.Index(i), column)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to encode value for slice")
+			return nil, err
 		}
 		sequence.Values = append(sequence.Values, node)
 	}
@@ -589,7 +588,7 @@ func (e *Encoder) encodeArray(ctx context.Context, value reflect.Value) (*ast.Se
 	for i := 0; i < value.Len(); i++ {
 		node, err := e.encodeValue(ctx, value.Index(i), column)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to encode value for array")
+			return nil, err
 		}
 		sequence.Values = append(sequence.Values, node)
 	}
@@ -604,7 +603,7 @@ func (e *Encoder) encodeMapItem(ctx context.Context, item MapItem, column int) (
 	v := reflect.ValueOf(item.Value)
 	value, err := e.encodeValue(ctx, v, column)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to encode MapItem")
+		return nil, err
 	}
 	if e.isMapNode(value) {
 		value.AddColumn(e.indent)
@@ -621,7 +620,7 @@ func (e *Encoder) encodeMapSlice(ctx context.Context, value MapSlice, column int
 	for _, item := range value {
 		value, err := e.encodeMapItem(ctx, item, column)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to encode MapItem for MapSlice")
+			return nil, err
 		}
 		node.Values = append(node.Values, value)
 	}
@@ -730,7 +729,7 @@ func (e *Encoder) encodeAnchor(anchorName string, value ast.Node, fieldValue ref
 	anchorNode.Value = value
 	if e.anchorCallback != nil {
 		if err := e.anchorCallback(anchorNode, fieldValue.Interface()); err != nil {
-			return nil, errors.Wrapf(err, "failed to marshal anchor")
+			return nil, err
 		}
 		if snode, ok := anchorNode.Name.(*ast.StringNode); ok {
 			anchorName = snode.Value
@@ -747,7 +746,7 @@ func (e *Encoder) encodeStruct(ctx context.Context, value reflect.Value, column
 	structType := value.Type()
 	structFieldMap, err := structFieldMap(structType)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to get struct field map")
+		return nil, err
 	}
 	hasInlineAnchorField := false
 	var inlineAnchorValue reflect.Value
@@ -770,7 +769,7 @@ func (e *Encoder) encodeStruct(ctx context.Context, value reflect.Value, column
 		}
 		value, err := ve.encodeValue(ctx, fieldValue, column)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to encode value")
+			return nil, err
 		}
 		if e.isMapNode(value) {
 			value.AddColumn(e.indent)
@@ -780,19 +779,19 @@ func (e *Encoder) encodeStruct(ctx context.Context, value reflect.Value, column
 		case structField.AnchorName != "":
 			anchorNode, err := e.encodeAnchor(structField.AnchorName, value, fieldValue, column)
 			if err != nil {
-				return nil, errors.Wrapf(err, "failed to encode anchor")
+				return nil, err
 			}
 			value = anchorNode
 		case structField.IsAutoAlias:
 			if fieldValue.Kind() != reflect.Ptr {
-				return nil, xerrors.Errorf(
+				return nil, fmt.Errorf(
 					"%s in struct is not pointer type. but required automatically alias detection",
 					structField.FieldName,
 				)
 			}
 			anchorName := e.anchorPtrToNameMap[fieldValue.Pointer()]
 			if anchorName == "" {
-				return nil, xerrors.Errorf(
+				return nil, errors.New(
 					"cannot find anchor name from pointer address for automatically alias detection",
 				)
 			}
@@ -827,7 +826,7 @@ func (e *Encoder) encodeStruct(ctx context.Context, value reflect.Value, column
 				if _, ok := value.(*ast.NullNode); ok {
 					continue
 				}
-				return nil, xerrors.Errorf("inline value is must be map or struct type")
+				return nil, errors.New("inline value is must be map or struct type")
 			}
 			mapIter := mapNode.MapRange()
 			for mapIter.Next() {
@@ -846,7 +845,7 @@ func (e *Encoder) encodeStruct(ctx context.Context, value reflect.Value, column
 		case structField.IsAutoAnchor:
 			anchorNode, err := e.encodeAnchor(structField.RenderName, value, fieldValue, column)
 			if err != nil {
-				return nil, errors.Wrapf(err, "failed to encode anchor")
+				return nil, err
 			}
 			value = anchorNode
 		}
@@ -860,7 +859,7 @@ func (e *Encoder) encodeStruct(ctx context.Context, value reflect.Value, column
 		anchorNode.Value = node
 		if e.anchorCallback != nil {
 			if err := e.anchorCallback(anchorNode, value.Addr().Interface()); err != nil {
-				return nil, errors.Wrapf(err, "failed to marshal anchor")
+				return nil, err
 			}
 			if snode, ok := anchorNode.Name.(*ast.StringNode); ok {
 				anchorName = snode.Value
diff --git a/error.go b/error.go
index 163dcc5..36e4f06 100644
--- a/error.go
+++ b/error.go
@@ -1,62 +1,65 @@
 package yaml
 
 import (
+	"errors"
+	"fmt"
+
 	"github.com/goccy/go-yaml/ast"
-	"golang.org/x/xerrors"
 )
 
 var (
-	ErrInvalidQuery               = xerrors.New("invalid query")
-	ErrInvalidPath                = xerrors.New("invalid path instance")
-	ErrInvalidPathString          = xerrors.New("invalid path string")
-	ErrNotFoundNode               = xerrors.New("node not found")
-	ErrUnknownCommentPositionType = xerrors.New("unknown comment position type")
-	ErrInvalidCommentMapValue     = xerrors.New("invalid comment map value. it must be not nil value")
+	ErrInvalidQuery               = errors.New("invalid query")
+	ErrInvalidPath                = errors.New("invalid path instance")
+	ErrInvalidPathString          = errors.New("invalid path string")
+	ErrNotFoundNode               = errors.New("node not found")
+	ErrUnknownCommentPositionType = errors.New("unknown comment position type")
+	ErrInvalidCommentMapValue     = errors.New("invalid comment map value. it must be not nil value")
+	ErrDecodeRequiredPointerType  = errors.New("required pointer type value")
 )
 
 func ErrUnsupportedHeadPositionType(node ast.Node) error {
-	return xerrors.Errorf("unsupported comment head position for %s", node.Type())
+	return fmt.Errorf("unsupported comment head position for %s", node.Type())
 }
 
 func ErrUnsupportedLinePositionType(node ast.Node) error {
-	return xerrors.Errorf("unsupported comment line position for %s", node.Type())
+	return fmt.Errorf("unsupported comment line position for %s", node.Type())
 }
 
 func ErrUnsupportedFootPositionType(node ast.Node) error {
-	return xerrors.Errorf("unsupported comment foot position for %s", node.Type())
+	return fmt.Errorf("unsupported comment foot position for %s", node.Type())
 }
 
 // IsInvalidQueryError whether err is ErrInvalidQuery or not.
 func IsInvalidQueryError(err error) bool {
-	return xerrors.Is(err, ErrInvalidQuery)
+	return errors.Is(err, ErrInvalidQuery)
 }
 
 // IsInvalidPathError whether err is ErrInvalidPath or not.
 func IsInvalidPathError(err error) bool {
-	return xerrors.Is(err, ErrInvalidPath)
+	return errors.Is(err, ErrInvalidPath)
 }
 
 // IsInvalidPathStringError whether err is ErrInvalidPathString or not.
 func IsInvalidPathStringError(err error) bool {
-	return xerrors.Is(err, ErrInvalidPathString)
+	return errors.Is(err, ErrInvalidPathString)
 }
 
 // IsNotFoundNodeError whether err is ErrNotFoundNode or not.
 func IsNotFoundNodeError(err error) bool {
-	return xerrors.Is(err, ErrNotFoundNode)
+	return errors.Is(err, ErrNotFoundNode)
 }
 
 // IsInvalidTokenTypeError whether err is ast.ErrInvalidTokenType or not.
 func IsInvalidTokenTypeError(err error) bool {
-	return xerrors.Is(err, ast.ErrInvalidTokenType)
+	return errors.Is(err, ast.ErrInvalidTokenType)
 }
 
 // IsInvalidAnchorNameError whether err is ast.ErrInvalidAnchorName or not.
 func IsInvalidAnchorNameError(err error) bool {
-	return xerrors.Is(err, ast.ErrInvalidAnchorName)
+	return errors.Is(err, ast.ErrInvalidAnchorName)
 }
 
 // IsInvalidAliasNameError whether err is ast.ErrInvalidAliasName or not.
 func IsInvalidAliasNameError(err error) bool {
-	return xerrors.Is(err, ast.ErrInvalidAliasName)
+	return errors.Is(err, ast.ErrInvalidAliasName)
 }
diff --git a/go.mod b/go.mod
index 4550ff3..ec1a3eb 100644
--- a/go.mod
+++ b/go.mod
@@ -3,18 +3,20 @@ module github.com/goccy/go-yaml
 go 1.19
 
 require (
-	github.com/fatih/color v1.10.0
-	github.com/go-playground/validator/v10 v10.4.1
-	github.com/google/go-cmp v0.5.9
-	github.com/mattn/go-colorable v0.1.8
-	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
+	github.com/fatih/color v1.18.0
+	github.com/go-playground/validator/v10 v10.22.1
+	github.com/google/go-cmp v0.6.0
+	github.com/mattn/go-colorable v0.1.13
 )
 
 require (
-	github.com/go-playground/locales v0.13.0 // indirect
-	github.com/go-playground/universal-translator v0.17.0 // indirect
-	github.com/leodido/go-urn v1.2.0 // indirect
-	github.com/mattn/go-isatty v0.0.12 // indirect
-	golang.org/x/crypto v0.7.0 // indirect
-	golang.org/x/sys v0.6.0 // indirect
+	github.com/gabriel-vasile/mimetype v1.4.3 // indirect
+	github.com/go-playground/locales v0.14.1 // indirect
+	github.com/go-playground/universal-translator v0.18.1 // indirect
+	github.com/leodido/go-urn v1.4.0 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
+	golang.org/x/crypto v0.28.0 // indirect
+	golang.org/x/net v0.30.0 // indirect
+	golang.org/x/sys v0.26.0 // indirect
+	golang.org/x/text v0.19.0 // indirect
 )
diff --git a/go.sum b/go.sum
index 7249df6..d71ac9a 100644
--- a/go.sum
+++ b/go.sum
@@ -1,44 +1,34 @@
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
-github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
-github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
-github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
-github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
-github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
-github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
-github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
-github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
-github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
-github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
-github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
-github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
-github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
-github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
-github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
-github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
+github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
+github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
+github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
+github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
+github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
+github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
-golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
+golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
+golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
+golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
+golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
+golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
diff --git a/internal/errors/error.go b/internal/errors/error.go
index 7f1ea9a..5d3ca4b 100644
--- a/internal/errors/error.go
+++ b/internal/errors/error.go
@@ -2,12 +2,12 @@ package errors
 
 import (
 	"bytes"
+	"errors"
 	"fmt"
 	"reflect"
 
 	"github.com/goccy/go-yaml/printer"
 	"github.com/goccy/go-yaml/token"
-	"golang.org/x/xerrors"
 )
 
 const (
@@ -15,167 +15,79 @@ const (
 	defaultIncludeSource = true
 )
 
-var (
-	ErrDecodeRequiredPointerType = xerrors.New("required pointer type value")
-)
-
-// Wrapf wrap error for stack trace
-func Wrapf(err error, msg string, args ...interface{}) error {
-	return &wrapError{
-		baseError: &baseError{},
-		err:       xerrors.Errorf(msg, args...),
-		nextErr:   err,
-		frame:     xerrors.Caller(1),
-	}
-}
-
 // ErrSyntax create syntax error instance with message and token
 func ErrSyntax(msg string, tk *token.Token) *syntaxError {
 	return &syntaxError{
-		baseError: &baseError{},
-		msg:       msg,
-		token:     tk,
-		frame:     xerrors.Caller(1),
+		msg:   msg,
+		token: tk,
 	}
 }
 
-type baseError struct {
-	state fmt.State
-	verb  rune
+// ErrOverflow creates an overflow error instance with message and a token.
+func ErrOverflow(dstType reflect.Type, num string, tk *token.Token) *overflowError {
+	return &overflowError{dstType: dstType, srcNum: num, token: tk}
 }
 
-func (e *baseError) Error() string {
-	return ""
-}
-
-func (e *baseError) chainStateAndVerb(err error) {
-	wrapErr, ok := err.(*wrapError)
-	if ok {
-		wrapErr.state = e.state
-		wrapErr.verb = e.verb
-	}
-	syntaxErr, ok := err.(*syntaxError)
-	if ok {
-		syntaxErr.state = e.state
-		syntaxErr.verb = e.verb
-	}
-}
-
-type wrapError struct {
-	*baseError
-	err     error
-	nextErr error
-	frame   xerrors.Frame
+type Printer interface {
+	// Print appends args to the message output.
+	Print(args ...any)
 }
 
 type FormatErrorPrinter struct {
-	xerrors.Printer
+	Printer
 	Colored    bool
 	InclSource bool
 }
 
-func (e *wrapError) As(target interface{}) bool {
-	err := e.nextErr
-	for {
-		if wrapErr, ok := err.(*wrapError); ok {
-			err = wrapErr.nextErr
-			continue
-		}
-		break
-	}
-	return xerrors.As(err, target)
-}
-
-func (e *wrapError) Unwrap() error {
-	return e.nextErr
-}
-
-func (e *wrapError) PrettyPrint(p xerrors.Printer, colored, inclSource bool) error {
-	return e.FormatError(&FormatErrorPrinter{Printer: p, Colored: colored, InclSource: inclSource})
-}
-
-func (e *wrapError) FormatError(p xerrors.Printer) error {
-	if _, ok := p.(*FormatErrorPrinter); !ok {
-		p = &FormatErrorPrinter{
-			Printer:    p,
-			Colored:    defaultColorize,
-			InclSource: defaultIncludeSource,
-		}
-	}
-	if e.verb == 'v' && e.state.Flag('+') {
-		// print stack trace for debugging
-		p.Print(e.err, "\n")
-		e.frame.Format(p)
-		e.chainStateAndVerb(e.nextErr)
-		return e.nextErr
-	}
-	err := e.nextErr
-	for {
-		if wrapErr, ok := err.(*wrapError); ok {
-			err = wrapErr.nextErr
-			continue
-		}
-		break
-	}
-	e.chainStateAndVerb(err)
-	if fmtErr, ok := err.(xerrors.Formatter); ok {
-		fmtErr.FormatError(p)
-	} else {
-		p.Print(err)
-	}
-	return nil
-}
+var (
+	As  = errors.As
+	Is  = errors.Is
+	New = errors.New
+)
 
-type wrapState struct {
-	org fmt.State
+type overflowError struct {
+	dstType reflect.Type
+	srcNum  string
+	token   *token.Token
 }
 
-func (s *wrapState) Write(b []byte) (n int, err error) {
-	return s.org.Write(b)
+func (e *overflowError) Error() string {
+	return fmt.Sprintf("cannot unmarshal %s into Go value of type %s ( overflow )", e.srcNum, e.dstType)
 }
 
-func (s *wrapState) Width() (wid int, ok bool) {
-	return s.org.Width()
+func (e *overflowError) PrettyPrint(p Printer, colored, inclSource bool) error {
+	return e.FormatError(&FormatErrorPrinter{Printer: p, Colored: colored, InclSource: inclSource})
 }
 
-func (s *wrapState) Precision() (prec int, ok bool) {
-	return s.org.Precision()
-}
+func (e *overflowError) FormatError(p Printer) error {
+	var pp printer.Printer
 
-func (s *wrapState) Flag(c int) bool {
-	// set true to 'printDetail' forced because when p.Detail() is false, xerrors.Printer no output any text
-	if c == '#' {
-		// ignore '#' keyword because xerrors.FormatError doesn't set true to printDetail.
-		// ( see https://github.com/golang/xerrors/blob/master/adaptor.go#L39-L43 )
-		return false
+	var colored, inclSource bool
+	if fep, ok := p.(*FormatErrorPrinter); ok {
+		colored = fep.Colored
+		inclSource = fep.InclSource
 	}
-	return true
-}
 
-func (e *wrapError) Format(state fmt.State, verb rune) {
-	e.state = state
-	e.verb = verb
-	xerrors.FormatError(e, &wrapState{org: state}, verb)
-}
+	pos := fmt.Sprintf("[%d:%d] ", e.token.Position.Line, e.token.Position.Column)
+	msg := pp.PrintErrorMessage(fmt.Sprintf("%s%s", pos, e.Error()), colored)
+	if inclSource {
+		msg += "\n" + pp.PrintErrorToken(e.token, colored)
+	}
+	p.Print(msg)
 
-func (e *wrapError) Error() string {
-	var buf bytes.Buffer
-	e.PrettyPrint(&Sink{&buf}, defaultColorize, defaultIncludeSource)
-	return buf.String()
+	return nil
 }
 
 type syntaxError struct {
-	*baseError
 	msg   string
 	token *token.Token
-	frame xerrors.Frame
 }
 
-func (e *syntaxError) PrettyPrint(p xerrors.Printer, colored, inclSource bool) error {
+func (e *syntaxError) PrettyPrint(p Printer, colored, inclSource bool) error {
 	return e.FormatError(&FormatErrorPrinter{Printer: p, Colored: colored, InclSource: inclSource})
 }
 
-func (e *syntaxError) FormatError(p xerrors.Printer) error {
+func (e *syntaxError) FormatError(p Printer) error {
 	var pp printer.Printer
 
 	var colored, inclSource bool
@@ -190,18 +102,13 @@ func (e *syntaxError) FormatError(p xerrors.Printer) error {
 		msg += "\n" + pp.PrintErrorToken(e.token, colored)
 	}
 	p.Print(msg)
-
-	if e.verb == 'v' && e.state.Flag('+') {
-		// %+v
-		// print stack trace for debugging
-		e.frame.Format(p)
-	}
 	return nil
 }
 
 type PrettyPrinter interface {
-	PrettyPrint(xerrors.Printer, bool, bool) error
+	PrettyPrint(Printer, bool, bool) error
 }
+
 type Sink struct{ *bytes.Buffer }
 
 func (es *Sink) Print(args ...interface{}) {
@@ -236,11 +143,11 @@ func (e *TypeError) Error() string {
 	return fmt.Sprintf("cannot unmarshal %s into Go value of type %s", e.SrcType, e.DstType)
 }
 
-func (e *TypeError) PrettyPrint(p xerrors.Printer, colored, inclSource bool) error {
+func (e *TypeError) PrettyPrint(p Printer, colored, inclSource bool) error {
 	return e.FormatError(&FormatErrorPrinter{Printer: p, Colored: colored, InclSource: inclSource})
 }
 
-func (e *TypeError) FormatError(p xerrors.Printer) error {
+func (e *TypeError) FormatError(p Printer) error {
 	var pp printer.Printer
 
 	var colored, inclSource bool
diff --git a/parser/context.go b/parser/context.go
index 42cc4f8..39b23cb 100644
--- a/parser/context.go
+++ b/parser/context.go
@@ -3,17 +3,11 @@ package parser
 import (
 	"fmt"
 	"strings"
-
-	"github.com/goccy/go-yaml/token"
 )
 
 // context context at parsing
 type context struct {
-	parent *context
-	idx    int
-	size   int
-	tokens token.Tokens
-	path   string
+	path string
 }
 
 var pathSpecialChars = []string{
@@ -37,156 +31,19 @@ func normalizePath(path string) string {
 }
 
 func (c *context) withChild(path string) *context {
-	ctx := c.copy()
-	path = normalizePath(path)
-	ctx.path += fmt.Sprintf(".%s", path)
-	return ctx
+	ctx := *c
+	ctx.path = c.path + "." + normalizePath(path)
+	return &ctx
 }
 
 func (c *context) withIndex(idx uint) *context {
-	ctx := c.copy()
-	ctx.path += fmt.Sprintf("[%d]", idx)
-	return ctx
-}
-
-func (c *context) copy() *context {
-	return &context{
-		parent: c,
-		idx:    c.idx,
-		size:   c.size,
-		tokens: append(token.Tokens{}, c.tokens...),
-		path:   c.path,
-	}
-}
-
-func (c *context) next() bool {
-	return c.idx < c.size
-}
-
-func (c *context) previousToken() *token.Token {
-	if c.idx > 0 {
-		return c.tokens[c.idx-1]
-	}
-	return nil
-}
-
-func (c *context) insertToken(idx int, tk *token.Token) {
-	if c.parent != nil {
-		c.parent.insertToken(idx, tk)
-	}
-	if c.size < idx {
-		return
-	}
-	if c.size == idx {
-		curToken := c.tokens[c.size-1]
-		tk.Next = curToken
-		curToken.Prev = tk
-
-		c.tokens = append(c.tokens, tk)
-		c.size = len(c.tokens)
-		return
-	}
-
-	curToken := c.tokens[idx]
-	tk.Next = curToken
-	curToken.Prev = tk
-
-	c.tokens = append(c.tokens[:idx+1], c.tokens[idx:]...)
-	c.tokens[idx] = tk
-	c.size = len(c.tokens)
-}
-
-func (c *context) currentToken() *token.Token {
-	if c.idx >= c.size {
-		return nil
-	}
-	return c.tokens[c.idx]
-}
-
-func (c *context) nextToken() *token.Token {
-	if c.idx+1 >= c.size {
-		return nil
-	}
-	return c.tokens[c.idx+1]
+	ctx := *c
+	ctx.path = c.path + "[" + fmt.Sprint(idx) + "]"
+	return &ctx
 }
 
-func (c *context) afterNextToken() *token.Token {
-	if c.idx+2 >= c.size {
-		return nil
-	}
-	return c.tokens[c.idx+2]
-}
-
-func (c *context) nextNotCommentToken() *token.Token {
-	for i := c.idx + 1; i < c.size; i++ {
-		tk := c.tokens[i]
-		if tk.Type == token.CommentType {
-			continue
-		}
-		return tk
-	}
-	return nil
-}
-
-func (c *context) afterNextNotCommentToken() *token.Token {
-	notCommentTokenCount := 0
-	for i := c.idx + 1; i < c.size; i++ {
-		tk := c.tokens[i]
-		if tk.Type == token.CommentType {
-			continue
-		}
-		notCommentTokenCount++
-		if notCommentTokenCount == 2 {
-			return tk
-		}
-	}
-	return nil
-}
-
-func (c *context) isCurrentCommentToken() bool {
-	tk := c.currentToken()
-	if tk == nil {
-		return false
-	}
-	return tk.Type == token.CommentType
-}
-
-func (c *context) progressIgnoreComment(num int) {
-	if c.parent != nil {
-		c.parent.progressIgnoreComment(num)
-	}
-	if c.size <= c.idx+num {
-		c.idx = c.size
-	} else {
-		c.idx += num
-	}
-}
-
-func (c *context) progress(num int) {
-	if c.isCurrentCommentToken() {
-		return
-	}
-	c.progressIgnoreComment(num)
-}
-
-func newContext(tokens token.Tokens, mode Mode) *context {
-	filteredTokens := []*token.Token{}
-	if mode&ParseComments != 0 {
-		filteredTokens = tokens
-	} else {
-		for _, tk := range tokens {
-			if tk.Type == token.CommentType {
-				continue
-			}
-			// keep prev/next reference between tokens containing comments
-			// https://github.com/goccy/go-yaml/issues/254
-			filteredTokens = append(filteredTokens, tk)
-		}
-	}
+func newContext() *context {
 	return &context{
-		idx:    0,
-		size:   len(filteredTokens),
-		tokens: token.Tokens(filteredTokens),
-		path:   "$",
+		path: "$",
 	}
 }
diff --git a/parser/parser.go b/parser/parser.go
index 13ada50..de102ee 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -2,76 +2,211 @@ package parser
 
 import (
 	"fmt"
-	"io/ioutil"
+	"os"
 	"strings"
 
 	"github.com/goccy/go-yaml/ast"
 	"github.com/goccy/go-yaml/internal/errors"
 	"github.com/goccy/go-yaml/lexer"
 	"github.com/goccy/go-yaml/token"
-	"golang.org/x/xerrors"
 )
 
-type parser struct{}
+type parser struct {
+	idx    int
+	size   int
+	tokens token.Tokens
+}
+
+func newParser(tokens token.Tokens, mode Mode) *parser {
+	filteredTokens := []*token.Token{}
+	if mode&ParseComments != 0 {
+		filteredTokens = tokens
+	} else {
+		for _, tk := range tokens {
+			if tk.Type == token.CommentType {
+				continue
+			}
+			// keep prev/next reference between tokens containing comments
+			// https://github.com/goccy/go-yaml/issues/254
+			filteredTokens = append(filteredTokens, tk)
+		}
+	}
+	return &parser{
+		idx:    0,
+		size:   len(filteredTokens),
+		tokens: token.Tokens(filteredTokens),
+	}
+}
+
+func (p *parser) next() bool {
+	return p.idx < p.size
+}
+
+func (p *parser) previousToken() *token.Token {
+	if p.idx > 0 {
+		return p.tokens[p.idx-1]
+	}
+	return nil
+}
+
+func (p *parser) insertToken(idx int, tk *token.Token) {
+	if p.size < idx {
+		return
+	}
+	if p.size == idx {
+		curToken := p.tokens[p.size-1]
+		tk.Next = curToken
+		curToken.Prev = tk
+
+		p.tokens = append(p.tokens, tk)
+		p.size = len(p.tokens)
+		return
+	}
+
+	curToken := p.tokens[idx]
+	tk.Next = curToken
+	curToken.Prev = tk
+
+	p.tokens = append(p.tokens[:idx+1], p.tokens[idx:]...)
+	p.tokens[idx] = tk
+	p.size = len(p.tokens)
+}
+
+func (p *parser) currentToken() *token.Token {
+	if p.idx >= p.size {
+		return nil
+	}
+	return p.tokens[p.idx]
+}
+
+func (p *parser) nextToken() *token.Token {
+	if p.idx+1 >= p.size {
+		return nil
+	}
+	return p.tokens[p.idx+1]
+}
+
+func (p *parser) nextNotCommentToken() *token.Token {
+	for i := p.idx + 1; i < p.size; i++ {
+		tk := p.tokens[i]
+		if tk.Type == token.CommentType {
+			continue
+		}
+		return tk
+	}
+	return nil
+}
+
+func (p *parser) afterNextNotCommentToken() *token.Token {
+	notCommentTokenCount := 0
+	for i := p.idx + 1; i < p.size; i++ {
+		tk := p.tokens[i]
+		if tk.Type == token.CommentType {
+			continue
+		}
+		notCommentTokenCount++
+		if notCommentTokenCount == 2 {
+			return tk
+		}
+	}
+	return nil
+}
+
+func (p *parser) isCurrentCommentToken() bool {
+	tk := p.currentToken()
+	if tk == nil {
+		return false
+	}
+	return tk.Type == token.CommentType
+}
+
+func (p *parser) progressIgnoreComment(num int) {
+	if p.size <= p.idx+num {
+		p.idx = p.size
+	} else {
+		p.idx += num
+	}
+}
+
+func (p *parser) progress(num int) {
+	if p.isCurrentCommentToken() {
+		return
+	}
+	p.progressIgnoreComment(num)
+}
 
 func (p *parser) parseMapping(ctx *context) (*ast.MappingNode, error) {
-	mapTk := ctx.currentToken()
+	mapTk := p.currentToken()
 	node := ast.Mapping(mapTk, true)
 	node.SetPath(ctx.path)
-	ctx.progress(1) // skip MappingStart token
-	for ctx.next() {
-		tk := ctx.currentToken()
+	p.progress(1) // skip MappingStart token
+	for p.next() {
+		tk := p.currentToken()
 		if tk.Type == token.MappingEndType {
 			node.End = tk
 			return node, nil
 		} else if tk.Type == token.CollectEntryType {
-			ctx.progress(1)
+			p.progress(1)
 			continue
 		}
 
 		value, err := p.parseMappingValue(ctx)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to parse mapping value in mapping node")
+			return nil, err
 		}
 		mvnode, ok := value.(*ast.MappingValueNode)
 		if !ok {
 			return nil, errors.ErrSyntax("failed to parse flow mapping node", value.GetToken())
 		}
 		node.Values = append(node.Values, mvnode)
-		ctx.progress(1)
+		p.progress(1)
 	}
 	return nil, errors.ErrSyntax("unterminated flow mapping", node.GetToken())
 }
 
 func (p *parser) parseSequence(ctx *context) (*ast.SequenceNode, error) {
-	node := ast.Sequence(ctx.currentToken(), true)
+	node := ast.Sequence(p.currentToken(), true)
 	node.SetPath(ctx.path)
-	ctx.progress(1) // skip SequenceStart token
-	for ctx.next() {
-		tk := ctx.currentToken()
+	p.progress(1) // skip SequenceStart token
+
+	isFirst := true
+	for p.next() {
+		tk := p.currentToken()
 		if tk.Type == token.SequenceEndType {
 			node.End = tk
 			break
 		} else if tk.Type == token.CollectEntryType {
-			ctx.progress(1)
-			continue
+			p.progress(1)
+		} else if !isFirst {
+			return nil, errors.ErrSyntax("',' or ']' must be specified", tk)
 		}
 
-		value, err := p.parseToken(ctx.withIndex(uint(len(node.Values))), tk)
+		if tk := p.currentToken(); tk != nil && tk.Type == token.SequenceEndType {
+			// this case is here: "[ elem, ]".
+			// In this case, ignore the last element and break sequence parsing.
+			node.End = tk
+			break
+		}
+
+		value, err := p.parseToken(ctx.withIndex(uint(len(node.Values))), p.currentToken())
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to parse sequence value in flow sequence node")
+			return nil, err
 		}
 		node.Values = append(node.Values, value)
-		ctx.progress(1)
+		p.progress(1)
+		isFirst = false
+	}
+	if node.End == nil || node.End.Type != token.SequenceEndType {
+		return nil, errors.ErrSyntax("sequence end token ']' not found", node.Start)
 	}
 	return node, nil
 }
 
 func (p *parser) parseTag(ctx *context) (*ast.TagNode, error) {
-	tagToken := ctx.currentToken()
+	tagToken := p.currentToken()
 	node := ast.Tag(tagToken)
 	node.SetPath(ctx.path)
-	ctx.progress(1) // skip tag token
+	p.progress(1) // skip tag token
 	var (
 		value ast.Node
 		err   error
@@ -86,21 +221,21 @@ func (p *parser) parseTag(ctx *context) (*ast.TagNode, error) {
 		token.BinaryTag,
 		token.TimestampTag,
 		token.NullTag:
-		typ := ctx.currentToken().Type
+		typ := p.currentToken().Type
 		if typ == token.LiteralType || typ == token.FoldedType {
 			value, err = p.parseLiteral(ctx)
 		} else {
-			value = p.parseScalarValue(ctx.currentToken())
+			value = p.parseScalarValue(p.currentToken())
 		}
 	case token.SequenceTag,
 		token.SetTag:
 		err = errors.ErrSyntax(fmt.Sprintf("sorry, currently not supported %s tag", tagToken.Value), tagToken)
 	default:
 		// custom tag
-		value, err = p.parseToken(ctx, ctx.currentToken())
+		value, err = p.parseToken(ctx, p.currentToken())
 	}
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse tag value")
+		return nil, err
 	}
 	node.Value = value
 	return node, nil
@@ -141,7 +276,7 @@ func (p *parser) createNullToken(base *token.Token) *token.Token {
 func (p *parser) parseMapValue(ctx *context, key ast.MapKeyNode, colonToken *token.Token) (ast.Node, error) {
 	node, err := p.createMapValueNode(ctx, key, colonToken)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to create map value node")
+		return nil, err
 	}
 	if node != nil && node.GetPath() == "" {
 		node.SetPath(ctx.path)
@@ -150,11 +285,14 @@ func (p *parser) parseMapValue(ctx *context, key ast.MapKeyNode, colonToken *tok
 }
 
 func (p *parser) createMapValueNode(ctx *context, key ast.MapKeyNode, colonToken *token.Token) (ast.Node, error) {
-	tk := ctx.currentToken()
+	tk := p.currentToken()
 	if tk == nil {
 		nullToken := p.createNullToken(colonToken)
-		ctx.insertToken(ctx.idx, nullToken)
+		p.insertToken(p.idx, nullToken)
 		return ast.Null(nullToken), nil
+	} else if tk.Type == token.CollectEntryType {
+		// implicit null value.
+		return ast.Null(tk), nil
 	}
 	var comment *ast.CommentGroupNode
 	if tk.Type == token.CommentType {
@@ -162,7 +300,7 @@ func (p *parser) createMapValueNode(ctx *context, key ast.MapKeyNode, colonToken
 		if comment != nil {
 			comment.SetPath(ctx.withChild(key.GetToken().Value).path)
 		}
-		tk = ctx.currentToken()
+		tk = p.currentToken()
 	}
 	if tk.Position.Column == key.GetToken().Position.Column && tk.Type == token.StringType {
 		// in this case,
@@ -171,11 +309,11 @@ func (p *parser) createMapValueNode(ctx *context, key ast.MapKeyNode, colonToken
 		// next
 
 		nullToken := p.createNullToken(colonToken)
-		ctx.insertToken(ctx.idx, nullToken)
+		p.insertToken(p.idx, nullToken)
 		nullNode := ast.Null(nullToken)
 
 		if comment != nil {
-			nullNode.SetComment(comment)
+			_ = nullNode.SetComment(comment)
 		} else {
 			// If there is a comment, it is already bound to the key node,
 			// so remove the comment from the key to bind it to the null value.
@@ -184,7 +322,7 @@ func (p *parser) createMapValueNode(ctx *context, key ast.MapKeyNode, colonToken
 				if err := key.SetComment(nil); err != nil {
 					return nil, err
 				}
-				nullNode.SetComment(keyComment)
+				_ = nullNode.SetComment(keyComment)
 			}
 		}
 		return nullNode, nil
@@ -196,36 +334,40 @@ func (p *parser) createMapValueNode(ctx *context, key ast.MapKeyNode, colonToken
 		//   key: <value does not defined>
 		// next
 		nullToken := p.createNullToken(colonToken)
-		ctx.insertToken(ctx.idx, nullToken)
+		p.insertToken(p.idx, nullToken)
 		nullNode := ast.Null(nullToken)
 		if comment != nil {
-			nullNode.SetComment(comment)
+			_ = nullNode.SetComment(comment)
 		}
 		return nullNode, nil
 	}
 
-	value, err := p.parseToken(ctx, ctx.currentToken())
+	value, err := p.parseToken(ctx, p.currentToken())
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse mapping 'value' node")
+		return nil, err
 	}
 	if comment != nil {
-		value.SetComment(comment)
+		_ = value.SetComment(comment)
 	}
 	return value, nil
 }
 
 func (p *parser) validateMapValue(ctx *context, key, value ast.Node) error {
-	keyColumn := key.GetToken().Position.Column
-	valueColumn := value.GetToken().Position.Column
-	if keyColumn != valueColumn {
+	keyTk := key.GetToken()
+	valueTk := value.GetToken()
+
+	if keyTk.Position.Line == valueTk.Position.Line && valueTk.Type == token.SequenceEntryType {
+		return errors.ErrSyntax("block sequence entries are not allowed in this context", valueTk)
+	}
+	if keyTk.Position.Column != valueTk.Position.Column {
 		return nil
 	}
 	if value.Type() != ast.StringType {
 		return nil
 	}
-	ntk := ctx.nextToken()
+	ntk := p.nextToken()
 	if ntk == nil || (ntk.Type != token.MappingValueType && ntk.Type != token.SequenceEntryType) {
-		return errors.ErrSyntax("could not found expected ':' token", value.GetToken())
+		return errors.ErrSyntax("could not find expected ':' token", valueTk)
 	}
 	return nil
 }
@@ -233,34 +375,34 @@ func (p *parser) validateMapValue(ctx *context, key, value ast.Node) error {
 func (p *parser) parseMappingValue(ctx *context) (ast.Node, error) {
 	key, err := p.parseMapKey(ctx)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse map key")
+		return nil, err
 	}
 	keyText := key.GetToken().Value
 	key.SetPath(ctx.withChild(keyText).path)
 	if err := p.validateMapKey(key.GetToken()); err != nil {
-		return nil, errors.Wrapf(err, "validate mapping key error")
+		return nil, err
 	}
-	ctx.progress(1)          // progress to mapping value token
-	tk := ctx.currentToken() // get mapping value token
+	p.progress(1)          // progress to mapping value token
+	tk := p.currentToken() // get mapping value token
 	if tk == nil {
 		return nil, errors.ErrSyntax("unexpected map", key.GetToken())
 	}
-	ctx.progress(1) // progress to value token
+	p.progress(1) // progress to value token
 	if err := p.setSameLineCommentIfExists(ctx.withChild(keyText), key); err != nil {
-		return nil, errors.Wrapf(err, "failed to set same line comment to node")
+		return nil, err
 	}
 	if key.GetComment() != nil {
 		// if current token is comment, GetComment() is not nil.
 		// then progress to value token
-		ctx.progressIgnoreComment(1)
+		p.progressIgnoreComment(1)
 	}
 
 	value, err := p.parseMapValue(ctx.withChild(keyText), key, tk)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse map value")
+		return nil, err
 	}
 	if err := p.validateMapValue(ctx, key, value); err != nil {
-		return nil, errors.Wrapf(err, "failed to validate map value")
+		return nil, err
 	}
 
 	mvnode := ast.MappingValue(tk, key, value)
@@ -268,23 +410,31 @@ func (p *parser) parseMappingValue(ctx *context) (ast.Node, error) {
 	node := ast.Mapping(tk, false, mvnode)
 	node.SetPath(ctx.withChild(keyText).path)
 
-	ntk := ctx.nextNotCommentToken()
-	antk := ctx.afterNextNotCommentToken()
-	for antk != nil && antk.Type == token.MappingValueType &&
-		ntk.Position.Column == key.GetToken().Position.Column {
-		ctx.progressIgnoreComment(1)
-		value, err := p.parseToken(ctx, ctx.currentToken())
+	ntk := p.nextNotCommentToken()
+	antk := p.afterNextNotCommentToken()
+	for ntk != nil && ntk.Position.Column == key.GetToken().Position.Column {
+		if ntk.Type == token.DocumentHeaderType || ntk.Type == token.DocumentEndType {
+			break
+		}
+		if antk == nil {
+			return nil, errors.ErrSyntax("required ':' and map value", ntk)
+		}
+		if antk.Type != token.MappingValueType {
+			return nil, errors.ErrSyntax("required ':' and map value", antk)
+		}
+		p.progressIgnoreComment(1)
+		value, err := p.parseToken(ctx, p.currentToken())
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to parse mapping node")
+			return nil, err
 		}
 		switch value.Type() {
 		case ast.MappingType:
-			c := value.(*ast.MappingNode)
+			c, _ := value.(*ast.MappingNode)
 			comment := c.GetComment()
 			for idx, v := range c.Values {
 				if idx == 0 && comment != nil {
 					if err := v.SetComment(comment); err != nil {
-						return nil, errors.Wrapf(err, "failed to set comment token to node")
+						return nil, err
 					}
 				}
 				node.Values = append(node.Values, v)
@@ -292,14 +442,14 @@ func (p *parser) parseMappingValue(ctx *context) (ast.Node, error) {
 		case ast.MappingValueType:
 			node.Values = append(node.Values, value.(*ast.MappingValueNode))
 		default:
-			return nil, xerrors.Errorf("failed to parse mapping value node node is %s", value.Type())
+			return nil, fmt.Errorf("failed to parse mapping value node node is %s", value.Type())
 		}
-		ntk = ctx.nextNotCommentToken()
-		antk = ctx.afterNextNotCommentToken()
+		ntk = p.nextNotCommentToken()
+		antk = p.afterNextNotCommentToken()
 	}
 	if len(node.Values) == 1 {
 		mapKeyCol := mvnode.Key.GetToken().Position.Column
-		commentTk := ctx.nextToken()
+		commentTk := p.nextToken()
 		if commentTk != nil && commentTk.Type == token.CommentType && mapKeyCol <= commentTk.Position.Column {
 			// If the comment is in the same or deeper column as the last element column in map value,
 			// treat it as a footer comment for the last element.
@@ -309,7 +459,7 @@ func (p *parser) parseMappingValue(ctx *context) (ast.Node, error) {
 		return mvnode, nil
 	}
 	mapCol := node.GetToken().Position.Column
-	commentTk := ctx.nextToken()
+	commentTk := p.nextToken()
 	if commentTk != nil && commentTk.Type == token.CommentType && mapCol <= commentTk.Position.Column {
 		// If the comment is in the same or deeper column as the last element column in map value,
 		// treat it as a footer comment for the last element.
@@ -320,27 +470,27 @@ func (p *parser) parseMappingValue(ctx *context) (ast.Node, error) {
 }
 
 func (p *parser) parseSequenceEntry(ctx *context) (*ast.SequenceNode, error) {
-	tk := ctx.currentToken()
+	tk := p.currentToken()
 	sequenceNode := ast.Sequence(tk, false)
 	sequenceNode.SetPath(ctx.path)
 	curColumn := tk.Position.Column
 	for tk.Type == token.SequenceEntryType {
-		ctx.progress(1) // skip sequence token
-		tk = ctx.currentToken()
+		p.progress(1) // skip sequence token
+		tk = p.currentToken()
 		if tk == nil {
-			return nil, errors.ErrSyntax("empty sequence entry", ctx.previousToken())
+			return nil, errors.ErrSyntax("empty sequence value", p.previousToken())
 		}
 		var comment *ast.CommentGroupNode
 		if tk.Type == token.CommentType {
 			comment = p.parseCommentOnly(ctx)
-			tk = ctx.currentToken()
+			tk = p.currentToken()
 			if tk.Type == token.SequenceEntryType {
-				ctx.progress(1) // skip sequence token
+				p.progress(1) // skip sequence token
 			}
 		}
-		value, err := p.parseToken(ctx.withIndex(uint(len(sequenceNode.Values))), ctx.currentToken())
+		value, err := p.parseToken(ctx.withIndex(uint(len(sequenceNode.Values))), p.currentToken())
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to parse sequence")
+			return nil, err
 		}
 		if comment != nil {
 			comment.SetPath(ctx.withIndex(uint(len(sequenceNode.Values))).path)
@@ -349,7 +499,7 @@ func (p *parser) parseSequenceEntry(ctx *context) (*ast.SequenceNode, error) {
 			sequenceNode.ValueHeadComments = append(sequenceNode.ValueHeadComments, nil)
 		}
 		sequenceNode.Values = append(sequenceNode.Values, value)
-		tk = ctx.nextNotCommentToken()
+		tk = p.nextNotCommentToken()
 		if tk == nil {
 			break
 		}
@@ -359,9 +509,9 @@ func (p *parser) parseSequenceEntry(ctx *context) (*ast.SequenceNode, error) {
 		if tk.Position.Column != curColumn {
 			break
 		}
-		ctx.progressIgnoreComment(1)
+		p.progressIgnoreComment(1)
 	}
-	commentTk := ctx.nextToken()
+	commentTk := p.nextToken()
 	if commentTk != nil && commentTk.Type == token.CommentType && curColumn <= commentTk.Position.Column {
 		// If the comment is in the same or deeper column as the last element column in sequence value,
 		// treat it as a footer comment for the last element.
@@ -372,51 +522,51 @@ func (p *parser) parseSequenceEntry(ctx *context) (*ast.SequenceNode, error) {
 }
 
 func (p *parser) parseAnchor(ctx *context) (*ast.AnchorNode, error) {
-	tk := ctx.currentToken()
+	tk := p.currentToken()
 	anchor := ast.Anchor(tk)
 	anchor.SetPath(ctx.path)
-	ntk := ctx.nextToken()
+	ntk := p.nextToken()
 	if ntk == nil {
 		return nil, errors.ErrSyntax("unexpected anchor. anchor name is undefined", tk)
 	}
-	ctx.progress(1) // skip anchor token
-	name, err := p.parseToken(ctx, ctx.currentToken())
+	p.progress(1) // skip anchor token
+	name, err := p.parseToken(ctx, p.currentToken())
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parser anchor name node")
+		return nil, err
 	}
 	anchor.Name = name
-	ntk = ctx.nextToken()
+	ntk = p.nextToken()
 	if ntk == nil {
-		return nil, errors.ErrSyntax("unexpected anchor. anchor value is undefined", ctx.currentToken())
+		return nil, errors.ErrSyntax("unexpected anchor. anchor value is undefined", p.currentToken())
 	}
-	ctx.progress(1)
-	value, err := p.parseToken(ctx, ctx.currentToken())
+	p.progress(1)
+	value, err := p.parseToken(ctx, p.currentToken())
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parser anchor name node")
+		return nil, err
 	}
 	anchor.Value = value
 	return anchor, nil
 }
 
 func (p *parser) parseAlias(ctx *context) (*ast.AliasNode, error) {
-	tk := ctx.currentToken()
+	tk := p.currentToken()
 	alias := ast.Alias(tk)
 	alias.SetPath(ctx.path)
-	ntk := ctx.nextToken()
+	ntk := p.nextToken()
 	if ntk == nil {
 		return nil, errors.ErrSyntax("unexpected alias. alias name is undefined", tk)
 	}
-	ctx.progress(1) // skip alias token
-	name, err := p.parseToken(ctx, ctx.currentToken())
+	p.progress(1) // skip alias token
+	name, err := p.parseToken(ctx, p.currentToken())
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parser alias name node")
+		return nil, err
 	}
 	alias.Value = name
 	return alias, nil
 }
 
 func (p *parser) parseMapKey(ctx *context) (ast.MapKeyNode, error) {
-	tk := ctx.currentToken()
+	tk := p.currentToken()
 	if value := p.parseScalarValue(tk); value != nil {
 		return value, nil
 	}
@@ -445,10 +595,10 @@ func (p *parser) parseScalarValueWithComment(ctx *context, tk *token.Token) (ast
 		return nil, nil
 	}
 	node.SetPath(ctx.path)
-	if p.isSameLineComment(ctx.nextToken(), node) {
-		ctx.progress(1)
+	if p.isSameLineComment(p.nextToken(), node) {
+		p.progress(1)
 		if err := p.setSameLineCommentIfExists(ctx, node); err != nil {
-			return nil, errors.Wrapf(err, "failed to set same line comment to node")
+			return nil, err
 		}
 	}
 	return node, nil
@@ -479,43 +629,47 @@ func (p *parser) parseScalarValue(tk *token.Token) ast.ScalarNode {
 }
 
 func (p *parser) parseDirective(ctx *context) (*ast.DirectiveNode, error) {
-	node := ast.Directive(ctx.currentToken())
-	ctx.progress(1) // skip directive token
-	value, err := p.parseToken(ctx, ctx.currentToken())
+	node := ast.Directive(p.currentToken())
+	p.progress(1) // skip directive token
+	value, err := p.parseToken(ctx, p.currentToken())
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse directive value")
+		return nil, err
 	}
 	node.Value = value
-	ctx.progress(1)
-	tk := ctx.currentToken()
+	p.progress(1)
+	tk := p.currentToken()
 	if tk == nil {
 		// Since current token is nil, use the previous token to specify
 		// the syntax error location.
-		return nil, errors.ErrSyntax("unexpected directive value. document not started", ctx.previousToken())
+		return nil, errors.ErrSyntax("unexpected directive value. document not started", p.previousToken())
 	}
 	if tk.Type != token.DocumentHeaderType {
-		return nil, errors.ErrSyntax("unexpected directive value. document not started", ctx.currentToken())
+		return nil, errors.ErrSyntax("unexpected directive value. document not started", p.currentToken())
 	}
 	return node, nil
 }
 
 func (p *parser) parseLiteral(ctx *context) (*ast.LiteralNode, error) {
-	node := ast.Literal(ctx.currentToken())
-	ctx.progress(1) // skip literal/folded token
+	node := ast.Literal(p.currentToken())
+	p.progress(1) // skip literal/folded token
 
-	tk := ctx.currentToken()
+	tk := p.currentToken()
+	if tk == nil {
+		node.Value = ast.String(token.New("", "", node.Start.Position))
+		return node, nil
+	}
 	var comment *ast.CommentGroupNode
 	if tk.Type == token.CommentType {
 		comment = p.parseCommentOnly(ctx)
 		comment.SetPath(ctx.path)
 		if err := node.SetComment(comment); err != nil {
-			return nil, errors.Wrapf(err, "failed to set comment to literal")
+			return nil, err
 		}
-		tk = ctx.currentToken()
+		tk = p.currentToken()
 	}
 	value, err := p.parseToken(ctx, tk)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse literal/folded value")
+		return nil, err
 	}
 	snode, ok := value.(*ast.StringNode)
 	if !ok {
@@ -536,29 +690,29 @@ func (p *parser) isSameLineComment(tk *token.Token, node ast.Node) bool {
 }
 
 func (p *parser) setSameLineCommentIfExists(ctx *context, node ast.Node) error {
-	tk := ctx.currentToken()
+	tk := p.currentToken()
 	if !p.isSameLineComment(tk, node) {
 		return nil
 	}
 	comment := ast.CommentGroup([]*token.Token{tk})
 	comment.SetPath(ctx.path)
 	if err := node.SetComment(comment); err != nil {
-		return errors.Wrapf(err, "failed to set comment token to ast.Node")
+		return err
 	}
 	return nil
 }
 
 func (p *parser) parseDocument(ctx *context) (*ast.DocumentNode, error) {
-	startTk := ctx.currentToken()
-	ctx.progress(1) // skip document header token
-	body, err := p.parseToken(ctx, ctx.currentToken())
+	startTk := p.currentToken()
+	p.progress(1) // skip document header token
+	body, err := p.parseToken(ctx, p.currentToken())
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse document body")
+		return nil, err
 	}
 	node := ast.Document(startTk, body)
-	if ntk := ctx.nextToken(); ntk != nil && ntk.Type == token.DocumentEndType {
+	if ntk := p.nextToken(); ntk != nil && ntk.Type == token.DocumentEndType {
 		node.End = ntk
-		ctx.progress(1)
+		p.progress(1)
 	}
 	return node, nil
 }
@@ -566,7 +720,7 @@ func (p *parser) parseDocument(ctx *context) (*ast.DocumentNode, error) {
 func (p *parser) parseCommentOnly(ctx *context) *ast.CommentGroupNode {
 	commentTokens := []*token.Token{}
 	for {
-		tk := ctx.currentToken()
+		tk := p.currentToken()
 		if tk == nil {
 			break
 		}
@@ -574,7 +728,7 @@ func (p *parser) parseCommentOnly(ctx *context) *ast.CommentGroupNode {
 			break
 		}
 		commentTokens = append(commentTokens, tk)
-		ctx.progressIgnoreComment(1) // skip comment token
+		p.progressIgnoreComment(1) // skip comment token
 	}
 	return ast.CommentGroup(commentTokens)
 }
@@ -582,10 +736,10 @@ func (p *parser) parseCommentOnly(ctx *context) *ast.CommentGroupNode {
 func (p *parser) parseFootComment(ctx *context, col int) *ast.CommentGroupNode {
 	commentTokens := []*token.Token{}
 	for {
-		ctx.progressIgnoreComment(1)
-		commentTokens = append(commentTokens, ctx.currentToken())
+		p.progressIgnoreComment(1)
+		commentTokens = append(commentTokens, p.currentToken())
 
-		nextTk := ctx.nextToken()
+		nextTk := p.nextToken()
 		if nextTk == nil {
 			break
 		}
@@ -601,28 +755,28 @@ func (p *parser) parseFootComment(ctx *context, col int) *ast.CommentGroupNode {
 
 func (p *parser) parseComment(ctx *context) (ast.Node, error) {
 	group := p.parseCommentOnly(ctx)
-	node, err := p.parseToken(ctx, ctx.currentToken())
+	node, err := p.parseToken(ctx, p.currentToken())
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse node after comment")
+		return nil, err
 	}
 	if node == nil {
 		return group, nil
 	}
 	group.SetPath(node.GetPath())
 	if err := node.SetComment(group); err != nil {
-		return nil, errors.Wrapf(err, "failed to set comment token to node")
+		return nil, err
 	}
 	return node, nil
 }
 
 func (p *parser) parseMappingKey(ctx *context) (*ast.MappingKeyNode, error) {
-	keyTk := ctx.currentToken()
+	keyTk := p.currentToken()
 	node := ast.MappingKey(keyTk)
 	node.SetPath(ctx.path)
-	ctx.progress(1) // skip mapping key token
-	value, err := p.parseToken(ctx.withChild(keyTk.Value), ctx.currentToken())
+	p.progress(1) // skip mapping key token
+	value, err := p.parseToken(ctx.withChild(keyTk.Value), p.currentToken())
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse map key")
+		return nil, err
 	}
 	node.Value = value
 	return node, nil
@@ -631,7 +785,7 @@ func (p *parser) parseMappingKey(ctx *context) (*ast.MappingKeyNode, error) {
 func (p *parser) parseToken(ctx *context, tk *token.Token) (ast.Node, error) {
 	node, err := p.createNodeFromToken(ctx, tk)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to create node from token")
+		return nil, err
 	}
 	if node != nil && node.GetPath() == "" {
 		node.SetPath(ctx.path)
@@ -649,7 +803,7 @@ func (p *parser) createNodeFromToken(ctx *context, tk *token.Token) (ast.Node, e
 	}
 	node, err := p.parseScalarValueWithComment(ctx, tk)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse scalar value")
+		return nil, err
 	}
 	if node != nil {
 		return node, nil
@@ -665,6 +819,10 @@ func (p *parser) createNodeFromToken(ctx *context, tk *token.Token) (ast.Node, e
 		return p.parseMapping(ctx)
 	case token.SequenceStartType:
 		return p.parseSequence(ctx)
+	case token.SequenceEndType:
+		// SequenceEndType is always validated in parseSequence.
+		// Therefore, if this is found in other cases, it is treated as a syntax error.
+		return nil, errors.ErrSyntax("could not find '[' character corresponding to ']'", tk)
 	case token.SequenceEntryType:
 		return p.parseSequenceEntry(ctx)
 	case token.AnchorType:
@@ -681,15 +839,14 @@ func (p *parser) createNodeFromToken(ctx *context, tk *token.Token) (ast.Node, e
 	return nil, nil
 }
 
-func (p *parser) parse(tokens token.Tokens, mode Mode) (*ast.File, error) {
-	ctx := newContext(tokens, mode)
+func (p *parser) parse(ctx *context) (*ast.File, error) {
 	file := &ast.File{Docs: []*ast.DocumentNode{}}
-	for ctx.next() {
-		node, err := p.parseToken(ctx, ctx.currentToken())
+	for p.next() {
+		node, err := p.parseToken(ctx, p.currentToken())
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to parse")
+			return nil, err
 		}
-		ctx.progressIgnoreComment(1)
+		p.progressIgnoreComment(1)
 		if node == nil {
 			continue
 		}
@@ -713,30 +870,32 @@ func ParseBytes(bytes []byte, mode Mode) (*ast.File, error) {
 	tokens := lexer.Tokenize(string(bytes))
 	f, err := Parse(tokens, mode)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse")
+		return nil, err
 	}
 	return f, nil
 }
 
 // Parse parse from token instances, and returns ast.File
 func Parse(tokens token.Tokens, mode Mode) (*ast.File, error) {
-	var p parser
-	f, err := p.parse(tokens, mode)
+	if tk := tokens.InvalidToken(); tk != nil {
+		return nil, errors.ErrSyntax("found invalid token", tk)
+	}
+	f, err := newParser(tokens, mode).parse(newContext())
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse")
+		return nil, err
 	}
 	return f, nil
 }
 
 // Parse parse from filename, and returns ast.File
 func ParseFile(filename string, mode Mode) (*ast.File, error) {
-	file, err := ioutil.ReadFile(filename)
+	file, err := os.ReadFile(filename)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to read file: %s", filename)
+		return nil, err
 	}
 	f, err := ParseBytes(file, mode)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse")
+		return nil, err
 	}
 	f.Name = filename
 	return f, nil
diff --git a/path.go b/path.go
index 72554bd..fcb5681 100644
--- a/path.go
+++ b/path.go
@@ -8,7 +8,6 @@ import (
 	"strings"
 
 	"github.com/goccy/go-yaml/ast"
-	"github.com/goccy/go-yaml/internal/errors"
 	"github.com/goccy/go-yaml/parser"
 	"github.com/goccy/go-yaml/printer"
 )
@@ -39,7 +38,7 @@ func PathString(s string) (*Path, error) {
 		case '.':
 			b, buf, c, err := parsePathDot(builder, buf, cursor)
 			if err != nil {
-				return nil, errors.Wrapf(err, "failed to parse path of dot")
+				return nil, err
 			}
 			length = len(buf)
 			builder = b
@@ -47,13 +46,13 @@ func PathString(s string) (*Path, error) {
 		case '[':
 			b, buf, c, err := parsePathIndex(builder, buf, cursor)
 			if err != nil {
-				return nil, errors.Wrapf(err, "failed to parse path of index")
+				return nil, err
 			}
 			length = len(buf)
 			builder = b
 			cursor = c
 		default:
-			return nil, errors.Wrapf(ErrInvalidPathString, "invalid path at %d", cursor)
+			return nil, fmt.Errorf("invalid path at %d: %w", cursor, ErrInvalidPathString)
 		}
 	}
 	return builder.Build(), nil
@@ -67,18 +66,18 @@ func parsePathRecursive(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, [
 		c := buf[cursor]
 		switch c {
 		case '$':
-			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '$' after '..' character")
+			return nil, nil, 0, fmt.Errorf("specified '$' after '..' character: %w", ErrInvalidPathString)
 		case '*':
-			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '*' after '..' character")
+			return nil, nil, 0, fmt.Errorf("specified '*' after '..' character: %w", ErrInvalidPathString)
 		case '.', '[':
 			goto end
 		case ']':
-			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified ']' after '..' character")
+			return nil, nil, 0, fmt.Errorf("specified ']' after '..' character: %w", ErrInvalidPathString)
 		}
 	}
 end:
 	if start == cursor {
-		return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "not found recursive selector")
+		return nil, nil, 0, fmt.Errorf("not found recursive selector: %w", ErrInvalidPathString)
 	}
 	return b.Recursive(string(buf[start:cursor])), buf, cursor, nil
 }
@@ -88,7 +87,7 @@ func parsePathDot(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []rune,
 	if cursor+1 < length && buf[cursor+1] == '.' {
 		b, buf, c, err := parsePathRecursive(b, buf, cursor)
 		if err != nil {
-			return nil, nil, 0, errors.Wrapf(err, "failed to parse path of recursive")
+			return nil, nil, 0, err
 		}
 		return b, buf, c, nil
 	}
@@ -103,18 +102,18 @@ func parsePathDot(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []rune,
 		c := buf[cursor]
 		switch c {
 		case '$':
-			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '$' after '.' character")
+			return nil, nil, 0, fmt.Errorf("specified '$' after '.' character: %w", ErrInvalidPathString)
 		case '*':
-			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '*' after '.' character")
+			return nil, nil, 0, fmt.Errorf("specified '*' after '.' character: %w", ErrInvalidPathString)
 		case '.', '[':
 			goto end
 		case ']':
-			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified ']' after '.' character")
+			return nil, nil, 0, fmt.Errorf("specified ']' after '.' character: %w", ErrInvalidPathString)
 		}
 	}
 end:
 	if start == cursor {
-		return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "cloud not find by empty key")
+		return nil, nil, 0, fmt.Errorf("cloud not find by empty key: %w", ErrInvalidPathString)
 	}
 	return b.child(string(buf[start:cursor])), buf, cursor, nil
 }
@@ -136,21 +135,21 @@ func parseQuotedKey(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []run
 	}
 end:
 	if !foundEndDelim {
-		return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "could not find end delimiter for key")
+		return nil, nil, 0, fmt.Errorf("could not find end delimiter for key: %w", ErrInvalidPathString)
 	}
 	if start == cursor {
-		return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "could not find by empty key")
+		return nil, nil, 0, fmt.Errorf("could not find by empty key: %w", ErrInvalidPathString)
 	}
 	selector := buf[start:cursor]
 	cursor++
 	if cursor < length {
 		switch buf[cursor] {
 		case '$':
-			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '$' after '.' character")
+			return nil, nil, 0, fmt.Errorf("specified '$' after '.' character: %w", ErrInvalidPathString)
 		case '*':
-			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified '*' after '.' character")
+			return nil, nil, 0, fmt.Errorf("specified '*' after '.' character: %w", ErrInvalidPathString)
 		case ']':
-			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "specified ']' after '.' character")
+			return nil, nil, 0, fmt.Errorf("specified ']' after '.' character: %w", ErrInvalidPathString)
 		}
 	}
 	return b.child(string(selector)), buf, cursor, nil
@@ -160,7 +159,7 @@ func parsePathIndex(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []run
 	length := len(buf)
 	cursor++ // skip '[' character
 	if length <= cursor {
-		return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "unexpected end of YAML Path")
+		return nil, nil, 0, fmt.Errorf("unexpected end of YAML Path: %w", ErrInvalidPathString)
 	}
 	c := buf[cursor]
 	switch c {
@@ -176,7 +175,7 @@ func parsePathIndex(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []run
 			break
 		}
 		if buf[cursor] != ']' {
-			return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "invalid character %s at %d", string(buf[cursor]), cursor)
+			return nil, nil, 0, fmt.Errorf("invalid character %s at %d: %w", string(buf[cursor]), cursor, ErrInvalidPathString)
 		}
 		numOrAll := string(buf[start:cursor])
 		if numOrAll == "*" {
@@ -184,11 +183,11 @@ func parsePathIndex(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []run
 		}
 		num, err := strconv.ParseInt(numOrAll, 10, 64)
 		if err != nil {
-			return nil, nil, 0, errors.Wrapf(err, "failed to parse number")
+			return nil, nil, 0, err
 		}
 		return b.Index(uint(num)), buf, cursor + 1, nil
 	}
-	return nil, nil, 0, errors.Wrapf(ErrInvalidPathString, "invalid character %s at %d", c, cursor)
+	return nil, nil, 0, fmt.Errorf("invalid character %q at %d: %w", c, cursor, ErrInvalidPathString)
 }
 
 // Path represent YAMLPath ( like a JSONPath ).
@@ -205,10 +204,10 @@ func (p *Path) String() string {
 func (p *Path) Read(r io.Reader, v interface{}) error {
 	node, err := p.ReadNode(r)
 	if err != nil {
-		return errors.Wrapf(err, "failed to read node")
+		return err
 	}
 	if err := Unmarshal([]byte(node.String()), v); err != nil {
-		return errors.Wrapf(err, "failed to unmarshal")
+		return err
 	}
 	return nil
 }
@@ -220,15 +219,15 @@ func (p *Path) ReadNode(r io.Reader) (ast.Node, error) {
 	}
 	var buf bytes.Buffer
 	if _, err := io.Copy(&buf, r); err != nil {
-		return nil, errors.Wrapf(err, "failed to copy from reader")
+		return nil, err
 	}
 	f, err := parser.ParseBytes(buf.Bytes(), 0)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to parse yaml")
+		return nil, err
 	}
 	node, err := p.FilterFile(f)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to filter from ast.File")
+		return nil, err
 	}
 	return node, nil
 }
@@ -237,10 +236,10 @@ func (p *Path) ReadNode(r io.Reader) (ast.Node, error) {
 func (p *Path) Filter(target, v interface{}) error {
 	b, err := Marshal(target)
 	if err != nil {
-		return errors.Wrapf(err, "failed to marshal target value")
+		return err
 	}
 	if err := p.Read(bytes.NewBuffer(b), v); err != nil {
-		return errors.Wrapf(err, "failed to read")
+		return err
 	}
 	return nil
 }
@@ -250,20 +249,20 @@ func (p *Path) FilterFile(f *ast.File) (ast.Node, error) {
 	for _, doc := range f.Docs {
 		node, err := p.FilterNode(doc.Body)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to filter node by path ( %s )", p.node)
+			return nil, err
 		}
 		if node != nil {
 			return node, nil
 		}
 	}
-	return nil, errors.Wrapf(ErrNotFoundNode, "failed to find path ( %s )", p.node)
+	return nil, fmt.Errorf("failed to find path ( %s ): %w", p.node, ErrNotFoundNode)
 }
 
 // FilterNode filter from node by YAMLPath.
 func (p *Path) FilterNode(node ast.Node) (ast.Node, error) {
 	n, err := p.node.filter(node)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to filter node by path ( %s )", p.node)
+		return nil, err
 	}
 	return n, nil
 }
@@ -272,14 +271,14 @@ func (p *Path) FilterNode(node ast.Node) (ast.Node, error) {
 func (p *Path) MergeFromReader(dst *ast.File, src io.Reader) error {
 	var buf bytes.Buffer
 	if _, err := io.Copy(&buf, src); err != nil {
-		return errors.Wrapf(err, "failed to copy from reader")
+		return err
 	}
 	file, err := parser.ParseBytes(buf.Bytes(), 0)
 	if err != nil {
-		return errors.Wrapf(err, "failed to parse")
+		return err
 	}
 	if err := p.MergeFromFile(dst, file); err != nil {
-		return errors.Wrapf(err, "failed to merge file")
+		return err
 	}
 	return nil
 }
@@ -288,11 +287,11 @@ func (p *Path) MergeFromReader(dst *ast.File, src io.Reader) error {
 func (p *Path) MergeFromFile(dst *ast.File, src *ast.File) error {
 	base, err := p.FilterFile(dst)
 	if err != nil {
-		return errors.Wrapf(err, "failed to filter file")
+		return err
 	}
 	for _, doc := range src.Docs {
 		if err := ast.Merge(base, doc); err != nil {
-			return errors.Wrapf(err, "failed to merge")
+			return err
 		}
 	}
 	return nil
@@ -302,10 +301,10 @@ func (p *Path) MergeFromFile(dst *ast.File, src *ast.File) error {
 func (p *Path) MergeFromNode(dst *ast.File, src ast.Node) error {
 	base, err := p.FilterFile(dst)
 	if err != nil {
-		return errors.Wrapf(err, "failed to filter file")
+		return err
 	}
 	if err := ast.Merge(base, src); err != nil {
-		return errors.Wrapf(err, "failed to merge")
+		return err
 	}
 	return nil
 }
@@ -314,14 +313,14 @@ func (p *Path) MergeFromNode(dst *ast.File, src ast.Node) error {
 func (p *Path) ReplaceWithReader(dst *ast.File, src io.Reader) error {
 	var buf bytes.Buffer
 	if _, err := io.Copy(&buf, src); err != nil {
-		return errors.Wrapf(err, "failed to copy from reader")
+		return err
 	}
 	file, err := parser.ParseBytes(buf.Bytes(), 0)
 	if err != nil {
-		return errors.Wrapf(err, "failed to parse")
+		return err
 	}
 	if err := p.ReplaceWithFile(dst, file); err != nil {
-		return errors.Wrapf(err, "failed to replace file")
+		return err
 	}
 	return nil
 }
@@ -330,7 +329,7 @@ func (p *Path) ReplaceWithReader(dst *ast.File, src io.Reader) error {
 func (p *Path) ReplaceWithFile(dst *ast.File, src *ast.File) error {
 	for _, doc := range src.Docs {
 		if err := p.ReplaceWithNode(dst, doc); err != nil {
-			return errors.Wrapf(err, "failed to replace file by path ( %s )", p.node)
+			return err
 		}
 	}
 	return nil
@@ -343,7 +342,7 @@ func (p *Path) ReplaceWithNode(dst *ast.File, node ast.Node) error {
 			node = node.(*ast.DocumentNode).Body
 		}
 		if err := p.node.replace(doc.Body, node); err != nil {
-			return errors.Wrapf(err, "failed to replace node by path ( %s )", p.node)
+			return err
 		}
 	}
 	return nil
@@ -468,11 +467,11 @@ func (n *rootNode) String() string {
 
 func (n *rootNode) filter(node ast.Node) (ast.Node, error) {
 	if n.child == nil {
-		return nil, nil
+		return node, nil
 	}
 	filtered, err := n.child.filter(node)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to filter")
+		return nil, err
 	}
 	return filtered, nil
 }
@@ -482,7 +481,7 @@ func (n *rootNode) replace(node ast.Node, target ast.Node) error {
 		return nil
 	}
 	if err := n.child.replace(node, target); err != nil {
-		return errors.Wrapf(err, "failed to replace")
+		return err
 	}
 	return nil
 }
@@ -514,7 +513,7 @@ func (n *selectorNode) filter(node ast.Node) (ast.Node, error) {
 					var err error
 					key, err = strconv.Unquote(key)
 					if err != nil {
-						return nil, errors.Wrapf(err, "failed to unquote")
+						return nil, err
 					}
 				case '\'':
 					if len(key) > 1 && key[len(key)-1] == '\'' {
@@ -528,13 +527,13 @@ func (n *selectorNode) filter(node ast.Node) (ast.Node, error) {
 				}
 				filtered, err := n.child.filter(value.Value)
 				if err != nil {
-					return nil, errors.Wrapf(err, "failed to filter")
+					return nil, err
 				}
 				return filtered, nil
 			}
 		}
 	case ast.MappingValueType:
-		value := node.(*ast.MappingValueNode)
+		value, _ := node.(*ast.MappingValueNode)
 		key := value.Key.GetToken().Value
 		if key == selector {
 			if n.child == nil {
@@ -542,12 +541,12 @@ func (n *selectorNode) filter(node ast.Node) (ast.Node, error) {
 			}
 			filtered, err := n.child.filter(value.Value)
 			if err != nil {
-				return nil, errors.Wrapf(err, "failed to filter")
+				return nil, err
 			}
 			return filtered, nil
 		}
 	default:
-		return nil, errors.Wrapf(ErrInvalidQuery, "expected node type is map or map value. but got %s", node.Type())
+		return nil, fmt.Errorf("expected node type is map or map value. but got %s: %w", node.Type(), ErrInvalidQuery)
 	}
 	return nil, nil
 }
@@ -559,11 +558,11 @@ func (n *selectorNode) replaceMapValue(value *ast.MappingValueNode, target ast.N
 	}
 	if n.child == nil {
 		if err := value.Replace(target); err != nil {
-			return errors.Wrapf(err, "failed to replace")
+			return err
 		}
 	} else {
 		if err := n.child.replace(value.Value, target); err != nil {
-			return errors.Wrapf(err, "failed to replace")
+			return err
 		}
 	}
 	return nil
@@ -574,16 +573,16 @@ func (n *selectorNode) replace(node ast.Node, target ast.Node) error {
 	case ast.MappingType:
 		for _, value := range node.(*ast.MappingNode).Values {
 			if err := n.replaceMapValue(value, target); err != nil {
-				return errors.Wrapf(err, "failed to replace map value")
+				return err
 			}
 		}
 	case ast.MappingValueType:
-		value := node.(*ast.MappingValueNode)
+		value, _ := node.(*ast.MappingValueNode)
 		if err := n.replaceMapValue(value, target); err != nil {
-			return errors.Wrapf(err, "failed to replace map value")
+			return err
 		}
 	default:
-		return errors.Wrapf(ErrInvalidQuery, "expected node type is map or map value. but got %s", node.Type())
+		return fmt.Errorf("expected node type is map or map value. but got %s: %w", node.Type(), ErrInvalidQuery)
 	}
 	return nil
 }
@@ -612,11 +611,11 @@ func newIndexNode(selector uint) *indexNode {
 
 func (n *indexNode) filter(node ast.Node) (ast.Node, error) {
 	if node.Type() != ast.SequenceType {
-		return nil, errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type())
+		return nil, fmt.Errorf("expected sequence type node. but got %s: %w", node.Type(), ErrInvalidQuery)
 	}
-	sequence := node.(*ast.SequenceNode)
+	sequence, _ := node.(*ast.SequenceNode)
 	if n.selector >= uint(len(sequence.Values)) {
-		return nil, errors.Wrapf(ErrInvalidQuery, "expected index is %d. but got sequences has %d items", n.selector, sequence.Values)
+		return nil, fmt.Errorf("expected index is %d. but got sequences has %d items: %w", n.selector, sequence.Values, ErrInvalidQuery)
 	}
 	value := sequence.Values[n.selector]
 	if n.child == nil {
@@ -624,27 +623,27 @@ func (n *indexNode) filter(node ast.Node) (ast.Node, error) {
 	}
 	filtered, err := n.child.filter(value)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to filter")
+		return nil, err
 	}
 	return filtered, nil
 }
 
 func (n *indexNode) replace(node ast.Node, target ast.Node) error {
 	if node.Type() != ast.SequenceType {
-		return errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type())
+		return fmt.Errorf("expected sequence type node. but got %s: %w", node.Type(), ErrInvalidQuery)
 	}
-	sequence := node.(*ast.SequenceNode)
+	sequence, _ := node.(*ast.SequenceNode)
 	if n.selector >= uint(len(sequence.Values)) {
-		return errors.Wrapf(ErrInvalidQuery, "expected index is %d. but got sequences has %d items", n.selector, sequence.Values)
+		return fmt.Errorf("expected index is %d. but got sequences has %d items: %w", n.selector, sequence.Values, ErrInvalidQuery)
 	}
 	if n.child == nil {
 		if err := sequence.Replace(int(n.selector), target); err != nil {
-			return errors.Wrapf(err, "failed to replace")
+			return err
 		}
 		return nil
 	}
 	if err := n.child.replace(sequence.Values[n.selector], target); err != nil {
-		return errors.Wrapf(err, "failed to replace")
+		return err
 	}
 	return nil
 }
@@ -677,9 +676,9 @@ func (n *indexAllNode) String() string {
 
 func (n *indexAllNode) filter(node ast.Node) (ast.Node, error) {
 	if node.Type() != ast.SequenceType {
-		return nil, errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type())
+		return nil, fmt.Errorf("expected sequence type node. but got %s: %w", node.Type(), ErrInvalidQuery)
 	}
-	sequence := node.(*ast.SequenceNode)
+	sequence, _ := node.(*ast.SequenceNode)
 	if n.child == nil {
 		return sequence, nil
 	}
@@ -688,7 +687,7 @@ func (n *indexAllNode) filter(node ast.Node) (ast.Node, error) {
 	for _, value := range sequence.Values {
 		filtered, err := n.child.filter(value)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to filter")
+			return nil, err
 		}
 		out.Values = append(out.Values, filtered)
 	}
@@ -697,20 +696,20 @@ func (n *indexAllNode) filter(node ast.Node) (ast.Node, error) {
 
 func (n *indexAllNode) replace(node ast.Node, target ast.Node) error {
 	if node.Type() != ast.SequenceType {
-		return errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type())
+		return fmt.Errorf("expected sequence type node. but got %s: %w", node.Type(), ErrInvalidQuery)
 	}
-	sequence := node.(*ast.SequenceNode)
+	sequence, _ := node.(*ast.SequenceNode)
 	if n.child == nil {
 		for idx := range sequence.Values {
 			if err := sequence.Replace(idx, target); err != nil {
-				return errors.Wrapf(err, "failed to replace")
+				return err
 			}
 		}
 		return nil
 	}
 	for _, value := range sequence.Values {
 		if err := n.child.replace(value, target); err != nil {
-			return errors.Wrapf(err, "failed to replace")
+			return err
 		}
 	}
 	return nil
@@ -743,7 +742,7 @@ func (n *recursiveNode) filterNode(node ast.Node) (*ast.SequenceNode, error) {
 		for _, value := range typedNode.Values {
 			seq, err := n.filterNode(value)
 			if err != nil {
-				return nil, errors.Wrapf(err, "failed to filter")
+				return nil, err
 			}
 			sequence.Values = append(sequence.Values, seq.Values...)
 		}
@@ -754,14 +753,14 @@ func (n *recursiveNode) filterNode(node ast.Node) (*ast.SequenceNode, error) {
 		}
 		seq, err := n.filterNode(typedNode.Value)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to filter")
+			return nil, err
 		}
 		sequence.Values = append(sequence.Values, seq.Values...)
 	case *ast.SequenceNode:
 		for _, value := range typedNode.Values {
 			seq, err := n.filterNode(value)
 			if err != nil {
-				return nil, errors.Wrapf(err, "failed to filter")
+				return nil, err
 			}
 			sequence.Values = append(sequence.Values, seq.Values...)
 		}
@@ -772,7 +771,7 @@ func (n *recursiveNode) filterNode(node ast.Node) (*ast.SequenceNode, error) {
 func (n *recursiveNode) filter(node ast.Node) (ast.Node, error) {
 	sequence, err := n.filterNode(node)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to filter")
+		return nil, err
 	}
 	sequence.Start = node.GetToken()
 	return sequence, nil
@@ -783,23 +782,23 @@ func (n *recursiveNode) replaceNode(node ast.Node, target ast.Node) error {
 	case *ast.MappingNode:
 		for _, value := range typedNode.Values {
 			if err := n.replaceNode(value, target); err != nil {
-				return errors.Wrapf(err, "failed to replace")
+				return err
 			}
 		}
 	case *ast.MappingValueNode:
 		key := typedNode.Key.GetToken().Value
 		if n.selector == key {
 			if err := typedNode.Replace(target); err != nil {
-				return errors.Wrapf(err, "failed to replace")
+				return err
 			}
 		}
 		if err := n.replaceNode(typedNode.Value, target); err != nil {
-			return errors.Wrapf(err, "failed to replace")
+			return err
 		}
 	case *ast.SequenceNode:
 		for _, value := range typedNode.Values {
 			if err := n.replaceNode(value, target); err != nil {
-				return errors.Wrapf(err, "failed to replace")
+				return err
 			}
 		}
 	}
@@ -808,7 +807,7 @@ func (n *recursiveNode) replaceNode(node ast.Node, target ast.Node) error {
 
 func (n *recursiveNode) replace(node ast.Node, target ast.Node) error {
 	if err := n.replaceNode(node, target); err != nil {
-		return errors.Wrapf(err, "failed to replace")
+		return err
 	}
 	return nil
 }
diff --git a/printer/printer.go b/printer/printer.go
index d5e25dc..c714812 100644
--- a/printer/printer.go
+++ b/printer/printer.go
@@ -6,6 +6,7 @@ import (
 	"strings"
 
 	"github.com/fatih/color"
+
 	"github.com/goccy/go-yaml/ast"
 	"github.com/goccy/go-yaml/token"
 )
@@ -29,6 +30,7 @@ type Printer struct {
 	Bool             PrintFunc
 	String           PrintFunc
 	Number           PrintFunc
+	Comment          PrintFunc
 }
 
 func defaultLineNumberFormat(num int) string {
@@ -82,6 +84,11 @@ func (p *Printer) property(tk *token.Token) *Property {
 			return p.Number()
 		}
 		return prop
+	case token.CommentType:
+		if p.Comment != nil {
+			return p.Comment()
+		}
+		return prop
 	default:
 	}
 	return prop
diff --git a/scanner/context.go b/scanner/context.go
index 09d0a2d..54dc0b7 100644
--- a/scanner/context.go
+++ b/scanner/context.go
@@ -6,8 +6,6 @@ import (
 	"github.com/goccy/go-yaml/token"
 )
 
-const whitespace = ' '
-
 // Context context at scanning
 type Context struct {
 	idx                int
@@ -21,7 +19,6 @@ type Context struct {
 	isRawFolded        bool
 	isLiteral          bool
 	isFolded           bool
-	isSingleLine       bool
 	literalOpt         string
 }
 
@@ -35,14 +32,13 @@ var (
 
 func createContext() *Context {
 	return &Context{
-		idx:          0,
-		tokens:       token.Tokens{},
-		isSingleLine: true,
+		idx:    0,
+		tokens: token.Tokens{},
 	}
 }
 
 func newContext(src []rune) *Context {
-	ctx := ctxPool.Get().(*Context)
+	ctx, _ := ctxPool.Get().(*Context)
 	ctx.reset(src)
 	return ctx
 }
@@ -51,6 +47,14 @@ func (c *Context) release() {
 	ctxPool.Put(c)
 }
 
+func (c *Context) clear() {
+	c.resetBuffer()
+	c.isRawFolded = false
+	c.isLiteral = false
+	c.isFolded = false
+	c.literalOpt = ""
+}
+
 func (c *Context) reset(src []rune) {
 	c.idx = 0
 	c.size = len(src)
@@ -58,7 +62,6 @@ func (c *Context) reset(src []rune) {
 	c.tokens = c.tokens[:0]
 	c.resetBuffer()
 	c.isRawFolded = false
-	c.isSingleLine = true
 	c.isLiteral = false
 	c.isFolded = false
 	c.literalOpt = ""
@@ -71,10 +74,6 @@ func (c *Context) resetBuffer() {
 	c.notSpaceOrgCharPos = 0
 }
 
-func (c *Context) isSaveIndentMode() bool {
-	return c.isLiteral || c.isFolded || c.isRawFolded
-}
-
 func (c *Context) breakLiteral() {
 	c.isLiteral = false
 	c.isRawFolded = false
@@ -126,7 +125,7 @@ func (c *Context) isEOS() bool {
 }
 
 func (c *Context) isNextEOS() bool {
-	return len(c.src)-1 <= c.idx+1
+	return len(c.src) <= c.idx+1
 }
 
 func (c *Context) next() bool {
@@ -151,18 +150,6 @@ func (c *Context) currentChar() rune {
 	return rune(0)
 }
 
-func (c *Context) currentCharWithSkipWhitespace() rune {
-	idx := c.idx
-	for c.size > idx {
-		ch := c.src[idx]
-		if ch != whitespace {
-			return ch
-		}
-		idx++
-	}
-	return rune(0)
-}
-
 func (c *Context) nextChar() rune {
 	if c.size > c.idx+1 {
 		return c.src[c.idx+1]
@@ -186,19 +173,22 @@ func (c *Context) progress(num int) {
 	c.idx += num
 }
 
-func (c *Context) nextPos() int {
-	return c.idx + 1
-}
-
 func (c *Context) existsBuffer() bool {
 	return len(c.bufferedSrc()) != 0
 }
 
 func (c *Context) bufferedSrc() []rune {
 	src := c.buf[:c.notSpaceCharPos]
-	if len(src) > 0 && src[len(src)-1] == '\n' && c.isDocument() && c.literalOpt == "-" {
-		// remove end '\n' character
-		src = src[:len(src)-1]
+	if c.isDocument() && c.literalOpt == "-" {
+		// remove end '\n' character and trailing empty lines
+		// https://yaml.org/spec/1.2.2/#8112-block-chomping-indicator
+		for {
+			if len(src) > 0 && src[len(src)-1] == '\n' {
+				src = src[:len(src)-1]
+				continue
+			}
+			break
+		}
 	}
 	return src
 }
diff --git a/scanner/error.go b/scanner/error.go
new file mode 100644
index 0000000..4298be4
--- /dev/null
+++ b/scanner/error.go
@@ -0,0 +1,19 @@
+package scanner
+
+import "github.com/goccy/go-yaml/token"
+
+type InvalidTokenError struct {
+	Message string
+	Token   *token.Token
+}
+
+func (e *InvalidTokenError) Error() string {
+	return e.Message
+}
+
+func ErrInvalidToken(msg string, tk *token.Token) *InvalidTokenError {
+	return &InvalidTokenError{
+		Message: msg,
+		Token:   tk,
+	}
+}
diff --git a/scanner/scanner.go b/scanner/scanner.go
index b0eac48..4e7d0aa 100644
--- a/scanner/scanner.go
+++ b/scanner/scanner.go
@@ -1,11 +1,12 @@
 package scanner
 
 import (
+	"errors"
+	"fmt"
 	"io"
 	"strings"
 
 	"github.com/goccy/go-yaml/token"
-	"golang.org/x/xerrors"
 )
 
 // IndentState state for indent
@@ -25,18 +26,24 @@ const (
 // Scanner holds the scanner's internal state while processing a given text.
 // It can be allocated as part of another data structure but must be initialized via Init before use.
 type Scanner struct {
-	source                 []rune
-	sourcePos              int
-	sourceSize             int
-	line                   int
-	column                 int
-	offset                 int
-	prevIndentLevel        int
-	prevIndentNum          int
-	prevIndentColumn       int
-	docStartColumn         int
+	source     []rune
+	sourcePos  int
+	sourceSize int
+	// line number. This number starts from 1.
+	line int
+	// column number. This number starts from 1.
+	column int
+	// offset represents the offset from the beginning of the source.
+	offset int
+	// lastDelimColumn is the last column needed to compare indent is retained.
+	lastDelimColumn int
+	// indentNum indicates the number of spaces used for indentation.
+	indentNum int
+	// prevLineIndentNum indicates the number of spaces used for indentation at previous line.
+	prevLineIndentNum int
+	// indentLevel indicates the level of indent depth. This value does not match the column value.
 	indentLevel            int
-	indentNum              int
+	docStartColumn         int
 	isFirstCharAtLine      bool
 	isAnchor               bool
 	startedFlowSequenceNum int
@@ -64,7 +71,7 @@ func (s *Scanner) bufferedToken(ctx *Context) *token.Token {
 	line := s.line
 	column := s.column - len(ctx.buf)
 	level := s.indentLevel
-	if ctx.isSaveIndentMode() {
+	if ctx.isDocument() {
 		line -= s.newLineCount(ctx.buf)
 		column = strings.Index(string(ctx.obuf), string(ctx.buf)) + 1
 		// Since we are in a literal, folded or raw folded
@@ -86,30 +93,23 @@ func (s *Scanner) bufferedToken(ctx *Context) *token.Token {
 func (s *Scanner) progressColumn(ctx *Context, num int) {
 	s.column += num
 	s.offset += num
-	ctx.progress(num)
+	s.progress(ctx, num)
 }
 
 func (s *Scanner) progressLine(ctx *Context) {
+	s.prevLineIndentNum = s.indentNum
 	s.column = 1
 	s.line++
 	s.offset++
 	s.indentNum = 0
 	s.isFirstCharAtLine = true
 	s.isAnchor = false
-	ctx.progress(1)
+	s.progress(ctx, 1)
 }
 
-func (s *Scanner) isNeededKeepPreviousIndentNum(ctx *Context, c rune) bool {
-	if !s.isChangedToIndentStateUp() {
-		return false
-	}
-	if ctx.isDocument() {
-		return true
-	}
-	if c == '-' && ctx.existsBuffer() {
-		return true
-	}
-	return false
+func (s *Scanner) progress(ctx *Context, num int) {
+	ctx.progress(num)
+	s.sourcePos += num
 }
 
 func (s *Scanner) isNewLineChar(c rune) bool {
@@ -140,42 +140,38 @@ func (s *Scanner) newLineCount(src []rune) int {
 	return cnt
 }
 
-func (s *Scanner) updateIndentState(ctx *Context) {
-	indentNumBasedIndentState := s.indentState
-	if s.prevIndentNum < s.indentNum {
-		s.indentLevel = s.prevIndentLevel + 1
-		indentNumBasedIndentState = IndentStateUp
-	} else if s.prevIndentNum == s.indentNum {
-		s.indentLevel = s.prevIndentLevel
-		indentNumBasedIndentState = IndentStateEqual
-	} else {
-		indentNumBasedIndentState = IndentStateDown
-		if s.prevIndentLevel > 0 {
-			s.indentLevel = s.prevIndentLevel - 1
+func (s *Scanner) updateIndentLevel() {
+	if s.prevLineIndentNum < s.indentNum {
+		s.indentLevel++
+	} else if s.prevLineIndentNum > s.indentNum {
+		if s.indentLevel > 0 {
+			s.indentLevel--
 		}
 	}
+}
 
-	if s.prevIndentColumn > 0 {
-		if s.prevIndentColumn < s.column {
+func (s *Scanner) updateIndentState(ctx *Context) {
+	if s.lastDelimColumn > 0 {
+		if s.lastDelimColumn < s.column {
 			s.indentState = IndentStateUp
-		} else if s.prevIndentColumn != s.column || indentNumBasedIndentState != IndentStateEqual {
-			// The following case ( current position is 'd' ), some variables becomes like here
-			// - prevIndentColumn: 1 of 'a'
-			// - indentNumBasedIndentState: IndentStateDown because d's indentNum(1) is less than c's indentNum(3).
-			// Therefore, s.prevIndentColumn(1) == s.column(1) is true, but we want to treat this as IndentStateDown.
-			// So, we look also current indentState value by the above prevIndentNum based logic, and determins finally indentState.
-			// ---
-			// a:
-			//   b
-			//   c
-			// d: e
-			// ^
-			s.indentState = IndentStateDown
 		} else {
-			s.indentState = IndentStateEqual
+			// If lastDelimColumn and s.column are the same,
+			// treat as Down state since it is the same column as delimiter.
+			s.indentState = IndentStateDown
 		}
 	} else {
-		s.indentState = indentNumBasedIndentState
+		s.indentState = s.indentStateFromIndentNumDifference()
+	}
+}
+
+func (s *Scanner) indentStateFromIndentNumDifference() IndentState {
+	switch {
+	case s.prevLineIndentNum < s.indentNum:
+		return IndentStateUp
+	case s.prevLineIndentNum == s.indentNum:
+		return IndentStateEqual
+	default:
+		return IndentStateDown
 	}
 }
 
@@ -191,16 +187,9 @@ func (s *Scanner) updateIndent(ctx *Context, c rune) {
 		s.indentState = IndentStateKeep
 		return
 	}
+	s.updateIndentLevel()
 	s.updateIndentState(ctx)
 	s.isFirstCharAtLine = false
-	if s.isNeededKeepPreviousIndentNum(ctx, c) {
-		return
-	}
-	if s.indentState != IndentStateUp {
-		s.prevIndentColumn = 0
-	}
-	s.prevIndentNum = s.indentNum
-	s.prevIndentLevel = s.indentLevel
 }
 
 func (s *Scanner) isChangedToIndentStateDown() bool {
@@ -211,10 +200,6 @@ func (s *Scanner) isChangedToIndentStateUp() bool {
 	return s.indentState == IndentStateUp
 }
 
-func (s *Scanner) isChangedToIndentStateEqual() bool {
-	return s.indentState == IndentStateEqual
-}
-
 func (s *Scanner) addBufferedTokenIfExists(ctx *Context) {
 	ctx.addToken(s.bufferedToken(ctx))
 }
@@ -224,7 +209,7 @@ func (s *Scanner) breakLiteral(ctx *Context) {
 	ctx.breakLiteral()
 }
 
-func (s *Scanner) scanSingleQuote(ctx *Context) (tk *token.Token, pos int) {
+func (s *Scanner) scanSingleQuote(ctx *Context) (*token.Token, error) {
 	ctx.addOriginBuf('\'')
 	srcpos := s.pos()
 	startIndex := ctx.idx + 1
@@ -233,6 +218,7 @@ func (s *Scanner) scanSingleQuote(ctx *Context) (tk *token.Token, pos int) {
 	value := []rune{}
 	isFirstLineChar := false
 	isNewLine := false
+
 	for idx := startIndex; idx < size; idx++ {
 		if !isNewLine {
 			s.progressColumn(ctx, 1)
@@ -240,7 +226,6 @@ func (s *Scanner) scanSingleQuote(ctx *Context) (tk *token.Token, pos int) {
 			isNewLine = false
 		}
 		c := src[idx]
-		pos = idx + 1
 		ctx.addOriginBuf(c)
 		if s.isNewLineChar(c) {
 			value = append(value, ' ')
@@ -260,14 +245,17 @@ func (s *Scanner) scanSingleQuote(ctx *Context) (tk *token.Token, pos int) {
 			value = append(value, c)
 			ctx.addOriginBuf(c)
 			idx++
+			s.progressColumn(ctx, 1)
 			continue
 		}
 		s.progressColumn(ctx, 1)
-		tk = token.SingleQuote(string(value), string(ctx.obuf), srcpos)
-		pos = idx - startIndex + 1
-		return
+		return token.SingleQuote(string(value), string(ctx.obuf), srcpos), nil
 	}
-	return
+	s.progressColumn(ctx, 1)
+	return nil, ErrInvalidToken(
+		"could not find end character of single-quotated text",
+		token.Invalid(string(ctx.obuf), srcpos),
+	)
 }
 
 func hexToInt(b rune) int {
@@ -288,7 +276,7 @@ func hexRunesToInt(b []rune) int {
 	return sum
 }
 
-func (s *Scanner) scanDoubleQuote(ctx *Context) (tk *token.Token, pos int) {
+func (s *Scanner) scanDoubleQuote(ctx *Context) (*token.Token, error) {
 	ctx.addOriginBuf('"')
 	srcpos := s.pos()
 	startIndex := ctx.idx + 1
@@ -297,6 +285,7 @@ func (s *Scanner) scanDoubleQuote(ctx *Context) (tk *token.Token, pos int) {
 	value := []rune{}
 	isFirstLineChar := false
 	isNewLine := false
+
 	for idx := startIndex; idx < size; idx++ {
 		if !isNewLine {
 			s.progressColumn(ctx, 1)
@@ -304,7 +293,6 @@ func (s *Scanner) scanDoubleQuote(ctx *Context) (tk *token.Token, pos int) {
 			isNewLine = false
 		}
 		c := src[idx]
-		pos = idx + 1
 		ctx.addOriginBuf(c)
 		if s.isNewLineChar(c) {
 			value = append(value, ' ')
@@ -316,100 +304,96 @@ func (s *Scanner) scanDoubleQuote(ctx *Context) (tk *token.Token, pos int) {
 			continue
 		} else if c == '\\' {
 			isFirstLineChar = false
-			if idx+1 < size {
-				nextChar := src[idx+1]
-				switch nextChar {
-				case 'b':
-					ctx.addOriginBuf(nextChar)
-					value = append(value, '\b')
-					idx++
-					continue
-				case 'e':
-					ctx.addOriginBuf(nextChar)
-					value = append(value, '\x1B')
-					idx++
-					continue
-				case 'f':
-					ctx.addOriginBuf(nextChar)
-					value = append(value, '\f')
-					idx++
-					continue
-				case 'n':
-					ctx.addOriginBuf(nextChar)
-					value = append(value, '\n')
-					idx++
-					continue
-				case 'r':
-					ctx.addOriginBuf(nextChar)
-					value = append(value, '\r')
-					idx++
-					continue
-				case 'v':
-					ctx.addOriginBuf(nextChar)
-					value = append(value, '\v')
-					idx++
-					continue
-				case 'L': // LS (#x2028)
-					ctx.addOriginBuf(nextChar)
-					value = append(value, []rune{'\xE2', '\x80', '\xA8'}...)
-					idx++
-					continue
-				case 'N': // NEL (#x85)
-					ctx.addOriginBuf(nextChar)
-					value = append(value, []rune{'\xC2', '\x85'}...)
-					idx++
-					continue
-				case 'P': // PS (#x2029)
-					ctx.addOriginBuf(nextChar)
-					value = append(value, []rune{'\xE2', '\x80', '\xA9'}...)
-					idx++
-					continue
-				case '_': // #xA0
-					ctx.addOriginBuf(nextChar)
-					value = append(value, []rune{'\xC2', '\xA0'}...)
-					idx++
-					continue
-				case '"':
+			if idx+1 >= size {
+				value = append(value, c)
+				continue
+			}
+			nextChar := src[idx+1]
+			progress := 0
+			switch nextChar {
+			case 'b':
+				progress = 1
+				ctx.addOriginBuf(nextChar)
+				value = append(value, '\b')
+			case 'e':
+				progress = 1
+				ctx.addOriginBuf(nextChar)
+				value = append(value, '\x1B')
+			case 'f':
+				progress = 1
+				ctx.addOriginBuf(nextChar)
+				value = append(value, '\f')
+			case 'n':
+				progress = 1
+				ctx.addOriginBuf(nextChar)
+				value = append(value, '\n')
+			case 'r':
+				progress = 1
+				ctx.addOriginBuf(nextChar)
+				value = append(value, '\r')
+			case 'v':
+				progress = 1
+				ctx.addOriginBuf(nextChar)
+				value = append(value, '\v')
+			case 'L': // LS (#x2028)
+				progress = 1
+				ctx.addOriginBuf(nextChar)
+				value = append(value, []rune{'\xE2', '\x80', '\xA8'}...)
+			case 'N': // NEL (#x85)
+				progress = 1
+				ctx.addOriginBuf(nextChar)
+				value = append(value, []rune{'\xC2', '\x85'}...)
+			case 'P': // PS (#x2029)
+				progress = 1
+				ctx.addOriginBuf(nextChar)
+				value = append(value, []rune{'\xE2', '\x80', '\xA9'}...)
+			case '_': // #xA0
+				progress = 1
+				ctx.addOriginBuf(nextChar)
+				value = append(value, []rune{'\xC2', '\xA0'}...)
+			case '"':
+				progress = 1
+				ctx.addOriginBuf(nextChar)
+				value = append(value, nextChar)
+			case 'x':
+				if idx+3 >= size {
+					progress = 1
 					ctx.addOriginBuf(nextChar)
 					value = append(value, nextChar)
-					idx++
-					continue
-				case 'x':
-					if idx+3 >= size {
-						// TODO: need to return error
-						//err = xerrors.New("invalid escape character \\x")
-						return
-					}
-					codeNum := hexRunesToInt(src[idx+2 : idx+4])
+				} else {
+					progress = 3
+					codeNum := hexRunesToInt(src[idx+2 : idx+progress+1])
 					value = append(value, rune(codeNum))
-					idx += 3
-					continue
-				case 'u':
-					if idx+5 >= size {
-						// TODO: need to return error
-						//err = xerrors.New("invalid escape character \\u")
-						return
-					}
-					codeNum := hexRunesToInt(src[idx+2 : idx+6])
-					value = append(value, rune(codeNum))
-					idx += 5
-					continue
-				case 'U':
-					if idx+9 >= size {
-						// TODO: need to return error
-						//err = xerrors.New("invalid escape character \\U")
-						return
-					}
-					codeNum := hexRunesToInt(src[idx+2 : idx+10])
+				}
+			case 'u':
+				if idx+5 >= size {
+					progress = 1
+					ctx.addOriginBuf(nextChar)
+					value = append(value, nextChar)
+				} else {
+					progress = 5
+					codeNum := hexRunesToInt(src[idx+2 : idx+progress+1])
 					value = append(value, rune(codeNum))
-					idx += 9
-					continue
-				case '\\':
+				}
+			case 'U':
+				if idx+9 >= size {
+					progress = 1
 					ctx.addOriginBuf(nextChar)
-					idx++
+					value = append(value, nextChar)
+				} else {
+					progress = 9
+					codeNum := hexRunesToInt(src[idx+2 : idx+progress+1])
+					value = append(value, rune(codeNum))
 				}
+			case '\\':
+				progress = 1
+				ctx.addOriginBuf(nextChar)
+				value = append(value, c)
+			default:
+				value = append(value, c)
 			}
-			value = append(value, c)
+			idx += progress
+			s.progressColumn(ctx, progress)
 			continue
 		} else if c != '"' {
 			value = append(value, c)
@@ -417,18 +401,53 @@ func (s *Scanner) scanDoubleQuote(ctx *Context) (tk *token.Token, pos int) {
 			continue
 		}
 		s.progressColumn(ctx, 1)
-		tk = token.DoubleQuote(string(value), string(ctx.obuf), srcpos)
-		pos = idx - startIndex + 1
-		return
+		return token.DoubleQuote(string(value), string(ctx.obuf), srcpos), nil
 	}
-	return
+	s.progressColumn(ctx, 1)
+	return nil, ErrInvalidToken(
+		"could not find end character of double-quotated text",
+		token.Invalid(string(ctx.obuf), srcpos),
+	)
 }
 
-func (s *Scanner) scanQuote(ctx *Context, ch rune) (tk *token.Token, pos int) {
+func (s *Scanner) scanQuote(ctx *Context, ch rune) (bool, error) {
+	if ctx.existsBuffer() {
+		return false, nil
+	}
 	if ch == '\'' {
-		return s.scanSingleQuote(ctx)
+		tk, err := s.scanSingleQuote(ctx)
+		if err != nil {
+			return false, err
+		}
+		ctx.addToken(tk)
+	} else {
+		tk, err := s.scanDoubleQuote(ctx)
+		if err != nil {
+			return false, err
+		}
+		ctx.addToken(tk)
+	}
+	ctx.clear()
+	return true, nil
+}
+
+func (s *Scanner) scanWhiteSpace(ctx *Context) bool {
+	if ctx.isDocument() {
+		return false
+	}
+	if !s.isAnchor && !s.isFirstCharAtLine {
+		return false
+	}
+
+	if s.isFirstCharAtLine {
+		s.progressColumn(ctx, 1)
+		ctx.addOriginBuf(' ')
+		return true
 	}
-	return s.scanDoubleQuote(ctx)
+
+	s.addBufferedTokenIfExists(ctx)
+	s.isAnchor = false
+	return true
 }
 
 func (s *Scanner) isMergeKey(ctx *Context) bool {
@@ -455,28 +474,42 @@ func (s *Scanner) isMergeKey(ctx *Context) bool {
 	return false
 }
 
-func (s *Scanner) scanTag(ctx *Context) (tk *token.Token, pos int) {
+func (s *Scanner) scanTag(ctx *Context) bool {
+	if ctx.existsBuffer() {
+		return false
+	}
+
 	ctx.addOriginBuf('!')
-	ctx.progress(1) // skip '!' character
+	s.progress(ctx, 1) // skip '!' character
+
+	var progress int
 	for idx, c := range ctx.src[ctx.idx:] {
-		pos = idx + 1
+		progress = idx + 1
 		ctx.addOriginBuf(c)
 		switch c {
 		case ' ', '\n', '\r':
 			value := ctx.source(ctx.idx-1, ctx.idx+idx)
-			tk = token.Tag(value, string(ctx.obuf), s.pos())
-			pos = len([]rune(value))
-			return
+			ctx.addToken(token.Tag(value, string(ctx.obuf), s.pos()))
+			progress = len([]rune(value))
+			goto END
 		}
 	}
-	return
+END:
+	s.progressColumn(ctx, progress)
+	ctx.clear()
+	return true
 }
 
-func (s *Scanner) scanComment(ctx *Context) (tk *token.Token, pos int) {
+func (s *Scanner) scanComment(ctx *Context) bool {
+	if ctx.existsBuffer() && ctx.previousChar() != ' ' {
+		return false
+	}
+
+	s.addBufferedTokenIfExists(ctx)
 	ctx.addOriginBuf('#')
-	ctx.progress(1) // skip '#' character
+	s.progress(ctx, 1) // skip '#' character
+
 	for idx, c := range ctx.src[ctx.idx:] {
-		pos = idx + 1
 		ctx.addOriginBuf(c)
 		switch c {
 		case '\n', '\r':
@@ -484,25 +517,34 @@ func (s *Scanner) scanComment(ctx *Context) (tk *token.Token, pos int) {
 				continue
 			}
 			value := ctx.source(ctx.idx, ctx.idx+idx)
-			tk = token.Comment(value, string(ctx.obuf), s.pos())
-			pos = len([]rune(value)) + 1
-			return
+			progress := len([]rune(value))
+			ctx.addToken(token.Comment(value, string(ctx.obuf), s.pos()))
+			s.progressColumn(ctx, progress)
+			s.progressLine(ctx)
+			ctx.clear()
+			return true
 		}
 	}
 	// document ends with comment.
 	value := string(ctx.src[ctx.idx:])
-	tk = token.Comment(value, string(ctx.obuf), s.pos())
-	pos = len([]rune(value)) + 1
-	return
+	ctx.addToken(token.Comment(value, string(ctx.obuf), s.pos()))
+	progress := len([]rune(value))
+	s.progressColumn(ctx, progress)
+	s.progressLine(ctx)
+	ctx.clear()
+	return true
 }
 
-func trimCommentFromLiteralOpt(text string) (string, error) {
+func (s *Scanner) trimCommentFromLiteralOpt(text string, header rune) (string, error) {
 	idx := strings.Index(text, "#")
 	if idx < 0 {
 		return text, nil
 	}
 	if idx == 0 {
-		return "", xerrors.New("invalid literal header")
+		return "", ErrInvalidToken(
+			fmt.Sprintf("invalid literal header %s", text),
+			token.Invalid(string(header)+text, s.pos()),
+		)
 	}
 	return text[:idx-1], nil
 }
@@ -538,21 +580,258 @@ func (s *Scanner) scanLiteral(ctx *Context, c rune) {
 	}
 }
 
-func (s *Scanner) scanLiteralHeader(ctx *Context) (pos int, err error) {
+func (s *Scanner) scanNewLine(ctx *Context, c rune) {
+	if len(ctx.buf) > 0 && s.savedPos == nil {
+		s.savedPos = s.pos()
+		s.savedPos.Column -= len(ctx.bufferedSrc())
+	}
+
+	// if the following case, origin buffer has unnecessary two spaces.
+	// So, `removeRightSpaceFromOriginBuf` remove them, also fix column number too.
+	// ---
+	// a:[space][space]
+	//   b: c
+	removedNum := ctx.removeRightSpaceFromBuf()
+	if removedNum > 0 {
+		s.column -= removedNum
+		s.offset -= removedNum
+		if s.savedPos != nil {
+			s.savedPos.Column -= removedNum
+		}
+	}
+
+	// There is no problem that we ignore CR which followed by LF and normalize it to LF, because of following YAML1.2 spec.
+	// > Line breaks inside scalar content must be normalized by the YAML processor. Each such line break must be parsed into a single line feed character.
+	// > Outside scalar content, YAML allows any line break to be used to terminate lines.
+	// > -- https://yaml.org/spec/1.2/spec.html
+	if c == '\r' && ctx.nextChar() == '\n' {
+		ctx.addOriginBuf('\r')
+		s.progress(ctx, 1)
+		c = '\n'
+	}
+
+	if ctx.isEOS() {
+		s.addBufferedTokenIfExists(ctx)
+	} else if s.isAnchor {
+		s.addBufferedTokenIfExists(ctx)
+	}
+	ctx.addBuf(' ')
+	ctx.addOriginBuf(c)
+	s.progressLine(ctx)
+}
+
+func (s *Scanner) isFlowMode() bool {
+	if s.startedFlowSequenceNum > 0 {
+		return true
+	}
+	if s.startedFlowMapNum > 0 {
+		return true
+	}
+	return false
+}
+
+func (s *Scanner) scanFlowMapStart(ctx *Context) bool {
+	if ctx.existsBuffer() && !s.isFlowMode() {
+		return false
+	}
+
+	s.addBufferedTokenIfExists(ctx)
+	ctx.addOriginBuf('{')
+	ctx.addToken(token.MappingStart(string(ctx.obuf), s.pos()))
+	s.startedFlowMapNum++
+	s.progressColumn(ctx, 1)
+	ctx.clear()
+	return true
+}
+
+func (s *Scanner) scanFlowMapEnd(ctx *Context) bool {
+	if s.startedFlowMapNum <= 0 {
+		return false
+	}
+
+	s.addBufferedTokenIfExists(ctx)
+	ctx.addOriginBuf('}')
+	ctx.addToken(token.MappingEnd(string(ctx.obuf), s.pos()))
+	s.startedFlowMapNum--
+	s.progressColumn(ctx, 1)
+	ctx.clear()
+	return true
+}
+
+func (s *Scanner) scanFlowArrayStart(ctx *Context) bool {
+	if ctx.existsBuffer() && !s.isFlowMode() {
+		return false
+	}
+
+	s.addBufferedTokenIfExists(ctx)
+	ctx.addOriginBuf('[')
+	ctx.addToken(token.SequenceStart(string(ctx.obuf), s.pos()))
+	s.startedFlowSequenceNum++
+	s.progressColumn(ctx, 1)
+	ctx.clear()
+	return true
+}
+
+func (s *Scanner) scanFlowArrayEnd(ctx *Context) bool {
+	if ctx.existsBuffer() && s.startedFlowSequenceNum <= 0 {
+		return false
+	}
+
+	s.addBufferedTokenIfExists(ctx)
+	ctx.addOriginBuf(']')
+	ctx.addToken(token.SequenceEnd(string(ctx.obuf), s.pos()))
+	s.startedFlowSequenceNum--
+	s.progressColumn(ctx, 1)
+	ctx.clear()
+	return true
+}
+
+func (s *Scanner) scanFlowEntry(ctx *Context, c rune) bool {
+	if s.startedFlowSequenceNum <= 0 && s.startedFlowMapNum <= 0 {
+		return false
+	}
+
+	s.addBufferedTokenIfExists(ctx)
+	ctx.addOriginBuf(c)
+	ctx.addToken(token.CollectEntry(string(ctx.obuf), s.pos()))
+	s.progressColumn(ctx, 1)
+	ctx.clear()
+	return true
+}
+
+func (s *Scanner) scanMapDelim(ctx *Context) bool {
+	nc := ctx.nextChar()
+	if s.startedFlowMapNum <= 0 && nc != ' ' && !s.isNewLineChar(nc) && !ctx.isNextEOS() {
+		return false
+	}
+
+	// mapping value
+	tk := s.bufferedToken(ctx)
+	if tk != nil {
+		s.lastDelimColumn = tk.Position.Column
+		ctx.addToken(tk)
+	} else if tk := ctx.lastToken(); tk != nil {
+		// If the map key is quote, the buffer does not exist because it has already been cut into tokens.
+		// Therefore, we need to check the last token.
+		if tk.Indicator == token.QuotedScalarIndicator {
+			s.lastDelimColumn = tk.Position.Column
+		}
+	}
+	ctx.addToken(token.MappingValue(s.pos()))
+	s.progressColumn(ctx, 1)
+	ctx.clear()
+	return true
+}
+
+func (s *Scanner) scanDocumentStart(ctx *Context) bool {
+	if s.indentNum != 0 {
+		return false
+	}
+	if s.column != 1 {
+		return false
+	}
+	if ctx.repeatNum('-') != 3 {
+		return false
+	}
+
+	s.addBufferedTokenIfExists(ctx)
+	ctx.addToken(token.DocumentHeader(string(ctx.obuf)+"---", s.pos()))
+	s.progressColumn(ctx, 3)
+	ctx.clear()
+	return true
+}
+
+func (s *Scanner) scanDocumentEnd(ctx *Context) bool {
+	if s.indentNum != 0 {
+		return false
+	}
+	if s.column != 1 {
+		return false
+	}
+	if ctx.repeatNum('.') != 3 {
+		return false
+	}
+
+	ctx.addToken(token.DocumentEnd(string(ctx.obuf)+"...", s.pos()))
+	s.progressColumn(ctx, 3)
+	ctx.clear()
+	return true
+}
+
+func (s *Scanner) scanMergeKey(ctx *Context) bool {
+	if !s.isMergeKey(ctx) {
+		return false
+	}
+
+	s.lastDelimColumn = s.column
+	ctx.addToken(token.MergeKey(string(ctx.obuf)+"<<", s.pos()))
+	s.progressColumn(ctx, 2)
+	ctx.clear()
+	return true
+}
+
+func (s *Scanner) scanRawFoldedChar(ctx *Context) bool {
+	if !ctx.existsBuffer() {
+		return false
+	}
+	if !s.isChangedToIndentStateUp() {
+		return false
+	}
+
+	ctx.isRawFolded = true
+	ctx.addBuf('-')
+	ctx.addOriginBuf('-')
+	s.progressColumn(ctx, 1)
+	return true
+}
+
+func (s *Scanner) scanSequence(ctx *Context) bool {
+	if ctx.existsBuffer() {
+		return false
+	}
+
+	nc := ctx.nextChar()
+	if nc != ' ' && !s.isNewLineChar(nc) {
+		return false
+	}
+
+	s.addBufferedTokenIfExists(ctx)
+	ctx.addOriginBuf('-')
+	tk := token.SequenceEntry(string(ctx.obuf), s.pos())
+	s.lastDelimColumn = tk.Position.Column
+	ctx.addToken(tk)
+	s.progressColumn(ctx, 1)
+	ctx.clear()
+	return true
+}
+
+func (s *Scanner) scanLiteralHeader(ctx *Context) (bool, error) {
+	if ctx.existsBuffer() {
+		return false, nil
+	}
+
+	if err := s.scanLiteralHeaderOption(ctx); err != nil {
+		return false, err
+	}
+	s.progressLine(ctx)
+	return true, nil
+}
+
+func (s *Scanner) scanLiteralHeaderOption(ctx *Context) error {
 	header := ctx.currentChar()
 	ctx.addOriginBuf(header)
-	ctx.progress(1) // skip '|' or '>' character
+	s.progress(ctx, 1) // skip '|' or '>' character
 	for idx, c := range ctx.src[ctx.idx:] {
-		pos = idx
+		progress := idx
 		ctx.addOriginBuf(c)
 		switch c {
 		case '\n', '\r':
 			value := ctx.source(ctx.idx, ctx.idx+idx)
 			opt := strings.TrimRight(value, " ")
 			orgOptLen := len(opt)
-			opt, err = trimCommentFromLiteralOpt(opt)
+			opt, err := s.trimCommentFromLiteralOpt(opt, header)
 			if err != nil {
-				return
+				return err
 			}
 			switch opt {
 			case "", "+", "-",
@@ -592,288 +871,203 @@ func (s *Scanner) scanLiteralHeader(ctx *Context) (pos int, err error) {
 				s.indentState = IndentStateKeep
 				ctx.resetBuffer()
 				ctx.literalOpt = opt
-				return
+				s.progressColumn(ctx, progress)
+				return nil
+			default:
+				invalidTk := token.Invalid(string(ctx.obuf), s.pos())
+				s.progressColumn(ctx, progress)
+				return ErrInvalidToken(fmt.Sprintf("invalid literal header: %q", opt), invalidTk)
 			}
-			break
 		}
 	}
-	err = xerrors.New("invalid literal header")
-	return
+	text := string(ctx.src[ctx.idx:])
+	invalidTk := token.Invalid(string(ctx.obuf), s.pos())
+	s.progressColumn(ctx, len(text))
+	return ErrInvalidToken(fmt.Sprintf("invalid literal header: %q", text), invalidTk)
 }
 
-func (s *Scanner) scanNewLine(ctx *Context, c rune) {
-	if len(ctx.buf) > 0 && s.savedPos == nil {
-		s.savedPos = s.pos()
-		s.savedPos.Column -= len(ctx.bufferedSrc())
+func (s *Scanner) scanMapKey(ctx *Context) bool {
+	if ctx.existsBuffer() {
+		return false
 	}
 
-	// if the following case, origin buffer has unnecessary two spaces.
-	// So, `removeRightSpaceFromOriginBuf` remove them, also fix column number too.
-	// ---
-	// a:[space][space]
-	//   b: c
-	removedNum := ctx.removeRightSpaceFromBuf()
-	if removedNum > 0 {
-		s.column -= removedNum
-		s.offset -= removedNum
-		if s.savedPos != nil {
-			s.savedPos.Column -= removedNum
-		}
+	nc := ctx.nextChar()
+	if nc != ' ' {
+		return false
 	}
 
-	if ctx.isEOS() {
-		s.addBufferedTokenIfExists(ctx)
-	} else if s.isAnchor {
-		s.addBufferedTokenIfExists(ctx)
+	ctx.addToken(token.MappingKey(s.pos()))
+	s.progressColumn(ctx, 1)
+	ctx.clear()
+	return true
+}
+
+func (s *Scanner) scanDirective(ctx *Context) bool {
+	if ctx.existsBuffer() {
+		return false
 	}
-	ctx.addBuf(' ')
-	ctx.addOriginBuf(c)
-	ctx.isSingleLine = false
-	s.progressLine(ctx)
+	if s.indentNum != 0 {
+		return false
+	}
+
+	ctx.addToken(token.Directive(string(ctx.obuf)+"%", s.pos()))
+	s.progressColumn(ctx, 1)
+	ctx.clear()
+	return true
+}
+
+func (s *Scanner) scanAnchor(ctx *Context) bool {
+	if ctx.existsBuffer() {
+		return false
+	}
+
+	s.addBufferedTokenIfExists(ctx)
+	ctx.addOriginBuf('&')
+	ctx.addToken(token.Anchor(string(ctx.obuf), s.pos()))
+	s.progressColumn(ctx, 1)
+	s.isAnchor = true
+	ctx.clear()
+	return true
+}
+
+func (s *Scanner) scanAlias(ctx *Context) bool {
+	if ctx.existsBuffer() {
+		return false
+	}
+
+	s.addBufferedTokenIfExists(ctx)
+	ctx.addOriginBuf('*')
+	ctx.addToken(token.Alias(string(ctx.obuf), s.pos()))
+	s.progressColumn(ctx, 1)
+	ctx.clear()
+	return true
 }
 
-func (s *Scanner) scan(ctx *Context) (pos int) {
+func (s *Scanner) scan(ctx *Context) error {
 	for ctx.next() {
-		pos = ctx.nextPos()
 		c := ctx.currentChar()
+
+		// First, change the IndentState.
+		// If the target character is the first character in a line, IndentState is Up/Down/Equal state.
+		// The second and subsequent letters are Keep.
 		s.updateIndent(ctx, c)
+
+		// If IndentState is down, tokens are split, so the buffer accumulated until that point needs to be cutted as a token.
+		if s.isChangedToIndentStateDown() {
+			s.addBufferedTokenIfExists(ctx)
+		}
 		if ctx.isDocument() {
-			if s.isChangedToIndentStateEqual() ||
-				s.isChangedToIndentStateDown() {
-				s.addBufferedTokenIfExists(ctx)
+			if s.isChangedToIndentStateDown() {
+				if tk := ctx.lastToken(); tk != nil {
+					// If literal/folded content is empty, no string token is added.
+					// Therefore, add an empty string token.
+					if tk.Type != token.StringType {
+						ctx.addToken(token.String("", "", s.pos()))
+					}
+				}
 				s.breakLiteral(ctx)
 			} else {
 				s.scanLiteral(ctx, c)
 				continue
 			}
-		} else if s.isChangedToIndentStateDown() {
-			s.addBufferedTokenIfExists(ctx)
-		} else if s.isChangedToIndentStateEqual() {
-			// if first character is new line character, buffer expect to raw folded literal
-			if len(ctx.obuf) > 0 && s.newLineCount(ctx.obuf) <= 1 {
-				// doesn't raw folded literal
-				s.addBufferedTokenIfExists(ctx)
-			}
 		}
 		switch c {
 		case '{':
-			if !ctx.existsBuffer() {
-				ctx.addOriginBuf(c)
-				ctx.addToken(token.MappingStart(string(ctx.obuf), s.pos()))
-				s.startedFlowMapNum++
-				s.progressColumn(ctx, 1)
-				return
+			if s.scanFlowMapStart(ctx) {
+				continue
 			}
 		case '}':
-			if !ctx.existsBuffer() || s.startedFlowMapNum > 0 {
-				ctx.addToken(s.bufferedToken(ctx))
-				ctx.addOriginBuf(c)
-				ctx.addToken(token.MappingEnd(string(ctx.obuf), s.pos()))
-				s.startedFlowMapNum--
-				s.progressColumn(ctx, 1)
-				return
+			if s.scanFlowMapEnd(ctx) {
+				continue
 			}
 		case '.':
-			if s.indentNum == 0 && s.column == 1 && ctx.repeatNum('.') == 3 {
-				ctx.addToken(token.DocumentEnd(string(ctx.obuf)+"...", s.pos()))
-				s.progressColumn(ctx, 3)
-				pos += 2
-				return
+			if s.scanDocumentEnd(ctx) {
+				continue
 			}
 		case '<':
-			if s.isMergeKey(ctx) {
-				s.prevIndentColumn = s.column
-				ctx.addToken(token.MergeKey(string(ctx.obuf)+"<<", s.pos()))
-				s.progressColumn(ctx, 1)
-				pos++
-				return
+			if s.scanMergeKey(ctx) {
+				continue
 			}
 		case '-':
-			if s.indentNum == 0 && s.column == 1 && ctx.repeatNum('-') == 3 {
-				s.addBufferedTokenIfExists(ctx)
-				ctx.addToken(token.DocumentHeader(string(ctx.obuf)+"---", s.pos()))
-				s.progressColumn(ctx, 3)
-				pos += 2
-				return
-			}
-			if ctx.existsBuffer() && s.isChangedToIndentStateUp() {
-				// raw folded
-				ctx.isRawFolded = true
-				ctx.addBuf(c)
-				ctx.addOriginBuf(c)
-				s.progressColumn(ctx, 1)
+			if s.scanDocumentStart(ctx) {
 				continue
 			}
-			if ctx.existsBuffer() {
-				// '-' is literal
-				ctx.addBuf(c)
-				ctx.addOriginBuf(c)
-				s.progressColumn(ctx, 1)
+			if s.scanRawFoldedChar(ctx) {
 				continue
 			}
-			nc := ctx.nextChar()
-			if nc == ' ' || s.isNewLineChar(nc) {
-				s.addBufferedTokenIfExists(ctx)
-				ctx.addOriginBuf(c)
-				tk := token.SequenceEntry(string(ctx.obuf), s.pos())
-				s.prevIndentColumn = tk.Position.Column
-				ctx.addToken(tk)
-				s.progressColumn(ctx, 1)
-				return
+			if s.scanSequence(ctx) {
+				continue
 			}
 		case '[':
-			if !ctx.existsBuffer() {
-				ctx.addOriginBuf(c)
-				ctx.addToken(token.SequenceStart(string(ctx.obuf), s.pos()))
-				s.startedFlowSequenceNum++
-				s.progressColumn(ctx, 1)
-				return
+			if s.scanFlowArrayStart(ctx) {
+				continue
 			}
 		case ']':
-			if !ctx.existsBuffer() || s.startedFlowSequenceNum > 0 {
-				s.addBufferedTokenIfExists(ctx)
-				ctx.addOriginBuf(c)
-				ctx.addToken(token.SequenceEnd(string(ctx.obuf), s.pos()))
-				s.startedFlowSequenceNum--
-				s.progressColumn(ctx, 1)
-				return
+			if s.scanFlowArrayEnd(ctx) {
+				continue
 			}
 		case ',':
-			if s.startedFlowSequenceNum > 0 || s.startedFlowMapNum > 0 {
-				s.addBufferedTokenIfExists(ctx)
-				ctx.addOriginBuf(c)
-				ctx.addToken(token.CollectEntry(string(ctx.obuf), s.pos()))
-				s.progressColumn(ctx, 1)
-				return
+			if s.scanFlowEntry(ctx, c) {
+				continue
 			}
 		case ':':
-			nc := ctx.nextChar()
-			if s.startedFlowMapNum > 0 || nc == ' ' || s.isNewLineChar(nc) || ctx.isNextEOS() {
-				// mapping value
-				tk := s.bufferedToken(ctx)
-				if tk != nil {
-					s.prevIndentColumn = tk.Position.Column
-					ctx.addToken(tk)
-				} else if tk := ctx.lastToken(); tk != nil {
-					// If the map key is quote, the buffer does not exist because it has already been cut into tokens.
-					// Therefore, we need to check the last token.
-					if tk.Indicator == token.QuotedScalarIndicator {
-						s.prevIndentColumn = tk.Position.Column
-					}
-				}
-				ctx.addToken(token.MappingValue(s.pos()))
-				s.progressColumn(ctx, 1)
-				return
+			if s.scanMapDelim(ctx) {
+				continue
 			}
 		case '|', '>':
-			if !ctx.existsBuffer() {
-				progress, err := s.scanLiteralHeader(ctx)
-				if err != nil {
-					// TODO: returns syntax error object
-					return
-				}
-				s.progressColumn(ctx, progress)
-				s.progressLine(ctx)
+			scanned, err := s.scanLiteralHeader(ctx)
+			if err != nil {
+				return err
+			}
+			if scanned {
 				continue
 			}
 		case '!':
-			if !ctx.existsBuffer() {
-				token, progress := s.scanTag(ctx)
-				ctx.addToken(token)
-				s.progressColumn(ctx, progress)
-				if c := ctx.previousChar(); s.isNewLineChar(c) {
-					s.progressLine(ctx)
-				}
-				pos += progress
-				return
+			if s.scanTag(ctx) {
+				continue
 			}
 		case '%':
-			if !ctx.existsBuffer() && s.indentNum == 0 {
-				ctx.addToken(token.Directive(string(ctx.obuf)+"%", s.pos()))
-				s.progressColumn(ctx, 1)
-				return
+			if s.scanDirective(ctx) {
+				continue
 			}
 		case '?':
-			nc := ctx.nextChar()
-			if !ctx.existsBuffer() && nc == ' ' {
-				ctx.addToken(token.MappingKey(s.pos()))
-				s.progressColumn(ctx, 1)
-				return
+			if s.scanMapKey(ctx) {
+				continue
 			}
 		case '&':
-			if !ctx.existsBuffer() {
-				s.addBufferedTokenIfExists(ctx)
-				ctx.addOriginBuf(c)
-				ctx.addToken(token.Anchor(string(ctx.obuf), s.pos()))
-				s.progressColumn(ctx, 1)
-				s.isAnchor = true
-				return
+			if s.scanAnchor(ctx) {
+				continue
 			}
 		case '*':
-			if !ctx.existsBuffer() {
-				s.addBufferedTokenIfExists(ctx)
-				ctx.addOriginBuf(c)
-				ctx.addToken(token.Alias(string(ctx.obuf), s.pos()))
-				s.progressColumn(ctx, 1)
-				return
+			if s.scanAlias(ctx) {
+				continue
 			}
 		case '#':
-			if !ctx.existsBuffer() || ctx.previousChar() == ' ' {
-				s.addBufferedTokenIfExists(ctx)
-				token, progress := s.scanComment(ctx)
-				ctx.addToken(token)
-				s.progressColumn(ctx, progress)
-				s.progressLine(ctx)
-				pos += progress
-				return
+			if s.scanComment(ctx) {
+				continue
 			}
 		case '\'', '"':
-			if !ctx.existsBuffer() {
-				token, progress := s.scanQuote(ctx, c)
-				ctx.addToken(token)
-				pos += progress
-				// If the non-whitespace character immediately following the quote is ':', the quote should be treated as a map key.
-				// Therefore, do not return and continue processing as a normal map key.
-				if ctx.currentCharWithSkipWhitespace() == ':' {
-					continue
-				}
-				return
+			scanned, err := s.scanQuote(ctx, c)
+			if err != nil {
+				return err
 			}
-		case '\r', '\n':
-			// There is no problem that we ignore CR which followed by LF and normalize it to LF, because of following YAML1.2 spec.
-			// > Line breaks inside scalar content must be normalized by the YAML processor. Each such line break must be parsed into a single line feed character.
-			// > Outside scalar content, YAML allows any line break to be used to terminate lines.
-			// > -- https://yaml.org/spec/1.2/spec.html
-			if c == '\r' && ctx.nextChar() == '\n' {
-				ctx.addOriginBuf('\r')
-				ctx.progress(1)
-				c = '\n'
+			if scanned {
+				continue
 			}
+		case '\r', '\n':
 			s.scanNewLine(ctx, c)
 			continue
 		case ' ':
-			if ctx.isSaveIndentMode() || (!s.isAnchor && !s.isFirstCharAtLine) {
-				ctx.addBuf(c)
-				ctx.addOriginBuf(c)
-				s.progressColumn(ctx, 1)
+			if s.scanWhiteSpace(ctx) {
 				continue
 			}
-			if s.isFirstCharAtLine {
-				s.progressColumn(ctx, 1)
-				ctx.addOriginBuf(c)
-				continue
-			}
-			s.addBufferedTokenIfExists(ctx)
-			pos-- // to rescan white space at next scanning for adding white space to next buffer.
-			s.isAnchor = false
-			return
 		}
 		ctx.addBuf(c)
 		ctx.addOriginBuf(c)
 		s.progressColumn(ctx, 1)
 	}
 	s.addBufferedTokenIfExists(ctx)
-	return
+	return nil
 }
 
 // Init prepares the scanner s to tokenize the text src by setting the scanner at the beginning of src.
@@ -885,9 +1079,8 @@ func (s *Scanner) Init(text string) {
 	s.line = 1
 	s.column = 1
 	s.offset = 1
-	s.prevIndentLevel = 0
-	s.prevIndentNum = 0
-	s.prevIndentColumn = 0
+	s.prevLineIndentNum = 0
+	s.lastDelimColumn = 0
 	s.indentLevel = 0
 	s.indentNum = 0
 	s.isFirstCharAtLine = true
@@ -900,9 +1093,17 @@ func (s *Scanner) Scan() (token.Tokens, error) {
 	}
 	ctx := newContext(s.source[s.sourcePos:])
 	defer ctx.release()
-	progress := s.scan(ctx)
-	s.sourcePos += progress
+
 	var tokens token.Tokens
+	err := s.scan(ctx)
 	tokens = append(tokens, ctx.tokens...)
+
+	if err != nil {
+		var invalidTokenErr *InvalidTokenError
+		if errors.As(err, &invalidTokenErr) {
+			tokens = append(tokens, invalidTokenErr.Token)
+		}
+		return tokens, err
+	}
 	return tokens, nil
 }
diff --git a/struct.go b/struct.go
index a3da8dd..dae4d65 100644
--- a/struct.go
+++ b/struct.go
@@ -1,10 +1,9 @@
 package yaml
 
 import (
+	"fmt"
 	"reflect"
 	"strings"
-
-	"golang.org/x/xerrors"
 )
 
 const (
@@ -84,11 +83,7 @@ func isIgnoredStructField(field reflect.StructField) bool {
 		// private field
 		return true
 	}
-	tag := getTag(field)
-	if tag == "-" {
-		return true
-	}
-	return false
+	return getTag(field) == "-"
 }
 
 type StructFieldMap map[string]*StructField
@@ -121,7 +116,7 @@ func structFieldMap(structType reflect.Type) (StructFieldMap, error) {
 		}
 		structField := structField(field)
 		if _, exists := renderNameMap[structField.RenderName]; exists {
-			return nil, xerrors.Errorf("duplicated struct field name %s", structField.RenderName)
+			return nil, fmt.Errorf("duplicated struct field name %s", structField.RenderName)
 		}
 		structFieldMap[structField.FieldName] = structField
 		renderNameMap[structField.RenderName] = struct{}{}
diff --git a/token/token.go b/token/token.go
index c86caab..c2d9a4b 100644
--- a/token/token.go
+++ b/token/token.go
@@ -117,6 +117,8 @@ const (
 	StringType
 	// BoolType type for Bool token
 	BoolType
+	// InvalidType type for invalid token
+	InvalidType
 )
 
 // String type identifier to text
@@ -186,6 +188,8 @@ func (t Type) String() string {
 		return "Infinity"
 	case NanType:
 		return "Nan"
+	case InvalidType:
+		return "Invalid"
 	}
 	return ""
 }
@@ -202,6 +206,8 @@ const (
 	CharacterTypeMiscellaneous
 	// CharacterTypeEscaped type of escaped character
 	CharacterTypeEscaped
+	// CharacterTypeInvalid type for a invalid token.
+	CharacterTypeInvalid
 )
 
 // String character type identifier to text
@@ -339,9 +345,12 @@ func reservedKeywordToken(typ Type, value, org string, pos *Position) *Token {
 
 func init() {
 	for _, keyword := range reservedNullKeywords {
-		reservedKeywordMap[keyword] = func(value, org string, pos *Position) *Token {
+		f := func(value, org string, pos *Position) *Token {
 			return reservedKeywordToken(NullType, value, org, pos)
 		}
+
+		reservedKeywordMap[keyword] = f
+		reservedEncKeywordMap[keyword] = f
 	}
 	for _, keyword := range reservedBoolKeywords {
 		f := func(value, org string, pos *Position) *Token {
@@ -623,7 +632,7 @@ func IsNeedQuoted(value string) bool {
 	}
 	first := value[0]
 	switch first {
-	case '*', '&', '[', '{', '}', ']', ',', '!', '|', '>', '%', '\'', '"', '@', ' ':
+	case '*', '&', '[', '{', '}', ']', ',', '!', '|', '>', '%', '\'', '"', '@', ' ', '`':
 		return true
 	}
 	last := value[len(value)-1]
@@ -756,9 +765,26 @@ func (t *Token) Clone() *Token {
 	return &copied
 }
 
+// Dump outputs token information to stdout for debugging.
+func (t *Token) Dump() {
+	fmt.Printf(
+		"[TYPE]:%q [CHARTYPE]:%q [INDICATOR]:%q [VALUE]:%q [ORG]:%q [POS(line:column:level)]: %d:%d:%d\n",
+		t.Type, t.CharacterType, t.Indicator, t.Value, t.Origin, t.Position.Line, t.Position.Column, t.Position.IndentLevel,
+	)
+}
+
 // Tokens type of token collection
 type Tokens []*Token
 
+func (t Tokens) InvalidToken() *Token {
+	for _, tt := range t {
+		if tt.Type == InvalidType {
+			return tt
+		}
+	}
+	return nil
+}
+
 func (t *Tokens) add(tk *Token) {
 	tokens := *t
 	if len(tokens) == 0 {
@@ -782,7 +808,8 @@ func (t *Tokens) Add(tks ...*Token) {
 // Dump dump all token structures for debugging
 func (t Tokens) Dump() {
 	for _, tk := range t {
-		fmt.Printf("- %+v\n", tk)
+		fmt.Print("- ")
+		tk.Dump()
 	}
 }
 
@@ -1054,6 +1081,17 @@ func DocumentEnd(org string, pos *Position) *Token {
 	}
 }
 
+func Invalid(org string, pos *Position) *Token {
+	return &Token{
+		Type:          InvalidType,
+		CharacterType: CharacterTypeInvalid,
+		Indicator:     NotIndicator,
+		Value:         org,
+		Origin:        org,
+		Position:      pos,
+	}
+}
+
 // DetectLineBreakCharacter detect line break character in only one inside scalar content scope.
 func DetectLineBreakCharacter(src string) string {
 	nc := strings.Count(src, "\n")
diff --git a/yaml.go b/yaml.go
index 25b1056..a90560e 100644
--- a/yaml.go
+++ b/yaml.go
@@ -9,7 +9,6 @@ import (
 
 	"github.com/goccy/go-yaml/ast"
 	"github.com/goccy/go-yaml/internal/errors"
-	"golang.org/x/xerrors"
 )
 
 // BytesMarshaler interface may be implemented by types to customize their
@@ -80,11 +79,11 @@ func (s MapSlice) ToMap() map[interface{}]interface{} {
 // of the generated document will reflect the structure of the value itself.
 // Maps and pointers (to struct, string, int, etc) are accepted as the in value.
 //
-// Struct fields are only marshalled if they are exported (have an upper case
-// first letter), and are marshalled using the field name lowercased as the
+// Struct fields are only marshaled if they are exported (have an upper case
+// first letter), and are marshaled using the field name lowercased as the
 // default key. Custom keys may be defined via the "yaml" name in the field
 // tag: the content preceding the first comma is used as the key, and the
-// following comma-separated options are used to tweak the marshalling process.
+// following comma-separated options are used to tweak the marshaling process.
 // Conflicting names result in a runtime error.
 //
 // The field tag format accepted is:
@@ -138,7 +137,7 @@ func MarshalWithOptions(v interface{}, opts ...EncodeOption) ([]byte, error) {
 func MarshalContext(ctx context.Context, v interface{}, opts ...EncodeOption) ([]byte, error) {
 	var buf bytes.Buffer
 	if err := NewEncoder(&buf, opts...).EncodeContext(ctx, v); err != nil {
-		return nil, errors.Wrapf(err, "failed to marshal")
+		return nil, err
 	}
 	return buf.Bytes(), nil
 }
@@ -148,7 +147,7 @@ func ValueToNode(v interface{}, opts ...EncodeOption) (ast.Node, error) {
 	var buf bytes.Buffer
 	node, err := NewEncoder(&buf, opts...).EncodeToNode(v)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to convert value to node")
+		return nil, err
 	}
 	return node, nil
 }
@@ -161,7 +160,7 @@ func ValueToNode(v interface{}, opts ...EncodeOption) (ast.Node, error) {
 // lowercased as the default key. Custom keys may be defined via the
 // "yaml" name in the field tag: the content preceding the first comma
 // is used as the key, and the following comma-separated options are
-// used to tweak the marshalling process (see Marshal).
+// used to tweak the marshaling process (see Marshal).
 // Conflicting names result in a runtime error.
 //
 // For example:
@@ -192,7 +191,7 @@ func UnmarshalContext(ctx context.Context, data []byte, v interface{}, opts ...D
 		if err == io.EOF {
 			return nil
 		}
-		return errors.Wrapf(err, "failed to unmarshal")
+		return err
 	}
 	return nil
 }
@@ -201,7 +200,7 @@ func UnmarshalContext(ctx context.Context, data []byte, v interface{}, opts ...D
 func NodeToValue(node ast.Node, v interface{}, opts ...DecodeOption) error {
 	var buf bytes.Buffer
 	if err := NewDecoder(&buf, opts...).DecodeFromNode(node, v); err != nil {
-		return errors.Wrapf(err, "failed to convert node to value")
+		return err
 	}
 	return nil
 }
@@ -214,9 +213,9 @@ func NodeToValue(node ast.Node, v interface{}, opts ...DecodeOption) error {
 // contain snippets of the YAML source that was used.
 func FormatError(e error, colored, inclSource bool) string {
 	var pp errors.PrettyPrinter
-	if xerrors.As(e, &pp) {
+	if errors.As(e, &pp) {
 		var buf bytes.Buffer
-		pp.PrettyPrint(&errors.Sink{&buf}, colored, inclSource)
+		pp.PrettyPrint(&errors.Sink{Buffer: &buf}, colored, inclSource)
 		return buf.String()
 	}
 
@@ -227,11 +226,11 @@ func FormatError(e error, colored, inclSource bool) string {
 func YAMLToJSON(bytes []byte) ([]byte, error) {
 	var v interface{}
 	if err := UnmarshalWithOptions(bytes, &v, UseOrderedMap()); err != nil {
-		return nil, errors.Wrapf(err, "failed to unmarshal")
+		return nil, err
 	}
 	out, err := MarshalWithOptions(v, JSON())
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to marshal with json option")
+		return nil, err
 	}
 	return out, nil
 }
@@ -240,11 +239,11 @@ func YAMLToJSON(bytes []byte) ([]byte, error) {
 func JSONToYAML(bytes []byte) ([]byte, error) {
 	var v interface{}
 	if err := UnmarshalWithOptions(bytes, &v, UseOrderedMap()); err != nil {
-		return nil, errors.Wrapf(err, "failed to unmarshal from json bytes")
+		return nil, err
 	}
 	out, err := Marshal(v)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to marshal")
+		return nil, err
 	}
 	return out, nil
 }


Test patch:
diff --git a/decode_test.go b/decode_test.go
index 2373804..3e26f24 100644
--- a/decode_test.go
+++ b/decode_test.go
@@ -18,7 +18,6 @@ import (
 	"github.com/goccy/go-yaml/ast"
 	"github.com/goccy/go-yaml/internal/errors"
 	"github.com/goccy/go-yaml/parser"
-	"golang.org/x/xerrors"
 )
 
 type Child struct {
@@ -252,6 +251,10 @@ func TestDecoder(t *testing.T) {
 			"v: 4294967295",
 			map[string]uint{"v": math.MaxUint32},
 		},
+		{
+			"v: 1e3",
+			map[string]uint{"v": 1000},
+		},
 
 		// uint64
 		{
@@ -270,6 +273,10 @@ func TestDecoder(t *testing.T) {
 			"v: 9223372036854775807",
 			map[string]uint64{"v": math.MaxInt64},
 		},
+		{
+			"v: 1e3",
+			map[string]uint64{"v": 1000},
+		},
 
 		// float32
 		{
@@ -288,6 +295,10 @@ func TestDecoder(t *testing.T) {
 			"v: 18446744073709551616",
 			map[string]float32{"v": float32(math.MaxUint64 + 1)},
 		},
+		{
+			"v: 1e-06",
+			map[string]float32{"v": 1e-6},
+		},
 
 		// float64
 		{
@@ -306,6 +317,10 @@ func TestDecoder(t *testing.T) {
 			"v: 18446744073709551616",
 			map[string]float64{"v": float64(math.MaxUint64 + 1)},
 		},
+		{
+			"v: 1e-06",
+			map[string]float64{"v": 1e-06},
+		},
 
 		// Timestamps
 		{
@@ -575,11 +590,11 @@ func TestDecoder(t *testing.T) {
 		},
 		{
 			"v: [A,B,C,]",
-			map[string][]string{"v": []string{"A", "B", "C"}},
+			map[string][]string{"v": {"A", "B", "C"}},
 		},
 		{
 			"v: [A,1,C]",
-			map[string][]string{"v": []string{"A", "1", "C"}},
+			map[string][]string{"v": {"A", "1", "C"}},
 		},
 		{
 			"v: [A,1,C]",
@@ -593,11 +608,11 @@ func TestDecoder(t *testing.T) {
 		},
 		{
 			"v:\n - A\n - B\n - C",
-			map[string][]string{"v": []string{"A", "B", "C"}},
+			map[string][]string{"v": {"A", "B", "C"}},
 		},
 		{
 			"v:\n - A\n - 1\n - C",
-			map[string][]string{"v": []string{"A", "1", "C"}},
+			map[string][]string{"v": {"A", "1", "C"}},
 		},
 		{
 			"v:\n - A\n - 1\n - C",
@@ -860,6 +875,14 @@ func TestDecoder(t *testing.T) {
 				},
 			},
 		},
+		{
+			"v:\n- A\n- |-\n  B\n  C\n\n\n",
+			map[string][]string{
+				"v": {
+					"A", "B\nC",
+				},
+			},
+		},
 		{
 			"v:\n- A\n- >-\n  B\n  C\n",
 			map[string][]string{
@@ -868,6 +891,14 @@ func TestDecoder(t *testing.T) {
 				},
 			},
 		},
+		{
+			"v:\n- A\n- >-\n  B\n  C\n\n\n",
+			map[string][]string{
+				"v": {
+					"A", "B C",
+				},
+			},
+		},
 		{
 			"a: b\nc: d\n",
 			struct {
@@ -917,7 +948,21 @@ func TestDecoder(t *testing.T) {
 			"a: &a [1, 2]\nb: *a\n",
 			struct{ B []int }{[]int{1, 2}},
 		},
-
+		{
+			"&0: *0\n*0:\n*0:",
+			map[string]any{"null": nil},
+		},
+		{
+			"key1: &anchor\n  subkey: *anchor\nkey2: *anchor\n",
+			map[string]any{
+				"key1": map[string]any{
+					"subkey": nil,
+				},
+				"key2": map[string]any{
+					"subkey": nil,
+				},
+			},
+		},
 		{
 			"tags:\n- hello-world\na: foo",
 			struct {
@@ -932,6 +977,10 @@ func TestDecoder(t *testing.T) {
 		{
 			"{}", struct{}{},
 		},
+		{
+			"{a: , b: c}",
+			map[string]any{"a": nil, "b": "c"},
+		},
 		{
 			"v: /a/{b}",
 			map[string]string{"v": "/a/{b}"},
@@ -1076,6 +1125,73 @@ c:
 	}
 }
 
+func TestDecoder_ScientificNotation(t *testing.T) {
+	tests := []struct {
+		source string
+		value  interface{}
+	}{
+		{
+			"v: 1e3",
+			map[string]uint{"v": 1000},
+		},
+		{
+			"v: 1e-3",
+			map[string]uint{"v": 0},
+		},
+		{
+			"v: 1e3",
+			map[string]int{"v": 1000},
+		},
+		{
+			"v: 1e-3",
+			map[string]int{"v": 0},
+		},
+		{
+			"v: 1e3",
+			map[string]float32{"v": 1000},
+		},
+		{
+			"v: 1.0e3",
+			map[string]float64{"v": 1000},
+		},
+		{
+			"v: 1e-3",
+			map[string]float64{"v": 0.001},
+		},
+		{
+			"v: 1.0e-3",
+			map[string]float64{"v": 0.001},
+		},
+		{
+			"v: 1.0e+3",
+			map[string]float64{"v": 1000},
+		},
+		{
+			"v: 1.0e+3",
+			map[string]float64{"v": 1000},
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.source, func(t *testing.T) {
+			buf := bytes.NewBufferString(test.source)
+			dec := yaml.NewDecoder(buf)
+			typ := reflect.ValueOf(test.value).Type()
+			value := reflect.New(typ)
+			if err := dec.Decode(value.Interface()); err != nil {
+				if err == io.EOF {
+					return
+				}
+				t.Fatalf("%s: %+v", test.source, err)
+			}
+			actual := fmt.Sprintf("%+v", value.Elem().Interface())
+			expect := fmt.Sprintf("%+v", test.value)
+			if actual != expect {
+				t.Fatalf("failed to test [%s], actual=[%s], expect=[%s]", test.source, actual, expect)
+			}
+		})
+	}
+}
+
 func TestDecoder_TypeConversionError(t *testing.T) {
 	t.Run("type conversion for struct", func(t *testing.T) {
 		type T struct {
@@ -1098,6 +1214,17 @@ func TestDecoder_TypeConversionError(t *testing.T) {
 				t.Fatalf("expected error message: %s to contain: %s", err.Error(), msg)
 			}
 		})
+		t.Run("string to uint", func(t *testing.T) {
+			var v T
+			err := yaml.Unmarshal([]byte(`b: str`), &v)
+			if err == nil {
+				t.Fatal("expected to error")
+			}
+			msg := "cannot unmarshal string into Go struct field T.B of type uint"
+			if !strings.Contains(err.Error(), msg) {
+				t.Fatalf("expected error message: %s to contain: %s", err.Error(), msg)
+			}
+		})
 		t.Run("string to bool", func(t *testing.T) {
 			var v T
 			err := yaml.Unmarshal([]byte(`d: str`), &v)
@@ -1359,7 +1486,7 @@ items:
 		if err := dec.Decode(&v); err != nil {
 			t.Fatalf("%+v", err)
 		}
-		items := v.(map[string]interface{})["items"].([]interface{})
+		items, _ := v.(map[string]interface{})["items"].([]interface{})
 		if len(items) != 2 {
 			t.Fatal("failed to decode with merge key")
 		}
@@ -2008,7 +2135,7 @@ map: &map
 		var buf bytes.Buffer
 		var v bool
 		err := yaml.NewDecoder(&buf).DecodeFromNode(nil, v)
-		if !xerrors.Is(err, errors.ErrDecodeRequiredPointerType) {
+		if !errors.Is(err, yaml.ErrDecodeRequiredPointerType) {
 			t.Fatalf("unexpected error: %s", err)
 		}
 	})
@@ -2041,17 +2168,17 @@ func Example_DisallowUnknownField() {
 
 	const src = `---
 simple: string
-complecated: string
+unknown: string
 `
 	err := yaml.NewDecoder(strings.NewReader(src), yaml.DisallowUnknownField()).Decode(&v)
 	fmt.Printf("%v\n", err)
 
 	// OUTPUT:
-	// [3:1] unknown field "complecated"
-	//        1 | ---
-	//        2 | simple: string
-	//     >  3 | complecated: string
-	//            ^
+	// [3:1] unknown field "unknown"
+	//    1 | ---
+	//    2 | simple: string
+	// >  3 | unknown: string
+	//        ^
 }
 
 func Example_Unmarshal_Node() {
@@ -2557,7 +2684,7 @@ func (u *unmarshalList) UnmarshalYAML(b []byte) error {
  - h: i`
 	actual := "\n" + string(b)
 	if expected != actual {
-		return xerrors.Errorf("unexpected bytes: expected [%q] but got [%q]", expected, actual)
+		return fmt.Errorf("unexpected bytes: expected [%q] but got [%q]", expected, actual)
 	}
 	var v []map[string]unmarshalString
 	if err := yaml.Unmarshal(b, &v); err != nil {
@@ -2601,22 +2728,22 @@ func TestDecoder_LiteralWithNewLine(t *testing.T) {
 		LastNode string `yaml:"last"`
 	}
 	tests := []A{
-		A{
+		{
 			Node: "hello\nworld",
 		},
-		A{
+		{
 			Node: "hello\nworld\n",
 		},
-		A{
+		{
 			Node: "hello\nworld\n\n",
 		},
-		A{
+		{
 			LastNode: "hello\nworld",
 		},
-		A{
+		{
 			LastNode: "hello\nworld\n",
 		},
-		A{
+		{
 			LastNode: "hello\nworld\n\n",
 		},
 	}
@@ -2890,3 +3017,54 @@ func TestSameNameInineStruct(t *testing.T) {
 		t.Fatalf("failed to decode")
 	}
 }
+
+type unmarshableMapKey struct {
+	Key string
+}
+
+func (mk *unmarshableMapKey) UnmarshalYAML(b []byte) error {
+	mk.Key = string(b)
+	return nil
+}
+
+func TestMapKeyCustomUnmarshaler(t *testing.T) {
+	var m map[unmarshableMapKey]string
+	if err := yaml.Unmarshal([]byte(`key: value`), &m); err != nil {
+		t.Fatalf("failed to unmarshal %v", err)
+	}
+	if len(m) != 1 {
+		t.Fatalf("expected 1 element in map, but got %d", len(m))
+	}
+	val, ok := m[unmarshableMapKey{Key: "key"}]
+	if !ok {
+		t.Fatal("expected to have element 'key' in map")
+	}
+	if val != "value" {
+		t.Fatalf("expected to have value \"value\", but got %q", val)
+	}
+}
+
+func TestDecoderPreservesDefaultValues(t *testing.T) {
+	type nested struct {
+		Val string `yaml:"val"`
+	}
+
+	type test struct {
+		First   string `yaml:"first"`
+		Default nested `yaml:"nested"`
+	}
+
+	yml := `
+first: "Test"
+nested:
+  # Just some comment here
+#  val: "default"
+`
+	v := test{Default: nested{Val: "default"}}
+	if err := yaml.Unmarshal([]byte(yml), &v); err != nil {
+		t.Fatal(err)
+	}
+	if v.Default.Val != "default" {
+		t.Fatal("decoder doesn't preserve struct defaults")
+	}
+}
diff --git a/encode_test.go b/encode_test.go
index 3ff6f1c..7c55269 100644
--- a/encode_test.go
+++ b/encode_test.go
@@ -10,10 +10,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/goccy/go-yaml/parser"
-
 	"github.com/goccy/go-yaml"
 	"github.com/goccy/go-yaml/ast"
+	"github.com/goccy/go-yaml/parser"
 )
 
 var zero = 0
@@ -80,6 +79,16 @@ func TestEncoder(t *testing.T) {
 			map[string]float32{"v": 0.99},
 			nil,
 		},
+		{
+			"v: 1e-06\n",
+			map[string]float32{"v": 1e-06},
+			nil,
+		},
+		{
+			"v: 1e-06\n",
+			map[string]float64{"v": 0.000001},
+			nil,
+		},
 		{
 			"v: 0.123456789\n",
 			map[string]float64{"v": 0.123456789},
@@ -100,6 +109,16 @@ func TestEncoder(t *testing.T) {
 			map[string]float64{"v": 1000000},
 			nil,
 		},
+		{
+			"v: 1e-06\n",
+			map[string]float64{"v": 0.000001},
+			nil,
+		},
+		{
+			"v: 1e-06\n",
+			map[string]float64{"v": 1e-06},
+			nil,
+		},
 		{
 			"v: .inf\n",
 			map[string]interface{}{"v": math.Inf(0)},
@@ -318,6 +337,11 @@ func TestEncoder(t *testing.T) {
 			map[string]string{"a": " b "},
 			nil,
 		},
+		{
+			"a: \"`b` c\"\n",
+			map[string]string{"a": "`b` c"},
+			nil,
+		},
 		{
 			"a: 100.5\n",
 			map[string]interface{}{
@@ -658,12 +682,12 @@ func TestEncoder(t *testing.T) {
 		// time value
 		{
 			"v: 0001-01-01T00:00:00Z\n",
-			map[string]time.Time{"v": time.Time{}},
+			map[string]time.Time{"v": {}},
 			nil,
 		},
 		{
 			"v: 0001-01-01T00:00:00Z\n",
-			map[string]*time.Time{"v": &time.Time{}},
+			map[string]*time.Time{"v": {}},
 			nil,
 		},
 		{
@@ -1053,7 +1077,7 @@ func TestEncoder_FlowRecursive(t *testing.T) {
 		M map[string][]int `yaml:",flow"`
 	}
 	v.M = map[string][]int{
-		"test": []int{1, 2, 3},
+		"test": {1, 2, 3},
 	}
 	var buf bytes.Buffer
 	if err := yaml.NewEncoder(&buf).Encode(v); err != nil {
@@ -1163,7 +1187,7 @@ func TestEncoder_MarshalAnchor(t *testing.T) {
 	hostIdx := 1
 	opt := yaml.MarshalAnchor(func(anchor *ast.AnchorNode, value interface{}) error {
 		if _, ok := value.(*Host); ok {
-			nameNode := anchor.Name.(*ast.StringNode)
+			nameNode, _ := anchor.Name.(*ast.StringNode)
 			nameNode.Value = fmt.Sprintf("host%d", hostIdx)
 			hostIdx++
 		}
diff --git a/lexer/lexer_test.go b/lexer/lexer_test.go
index 0d8f648..2a49239 100644
--- a/lexer/lexer_test.go
+++ b/lexer/lexer_test.go
@@ -2,7 +2,6 @@ package lexer_test
 
 import (
 	"sort"
-	"strings"
 	"testing"
 
 	"github.com/goccy/go-yaml/lexer"
@@ -10,59 +9,1825 @@ import (
 )
 
 func TestTokenize(t *testing.T) {
-	sources := []string{
-		"null\n",
-		"{}\n",
-		"v: hi\n",
-		"v: \"true\"\n",
-		"v: \"false\"\n",
-		"v: true\n",
-		"v: false\n",
-		"v: 10\n",
-		"v: -10\n",
-		"v: 42\n",
-		"v: 4294967296\n",
-		"v: \"10\"\n",
-		"v: 0.1\n",
-		"v: 0.99\n",
-		"v: -0.1\n",
-		"v: .inf\n",
-		"v: -.inf\n",
-		"v: .nan\n",
-		"v: null\n",
-		"v: \"\"\n",
-		"v:\n- A\n- B\n",
-		"v:\n- A\n- |-\n  B\n  C\n",
-		"v:\n- A\n- 1\n- B:\n  - 2\n  - 3\n",
-		"a:\n  b: c\n",
-		"a: '-'\n",
-		"123\n",
-		"hello: world\n",
-		"a: null\n",
-		"a: {x: 1}\n",
-		"a: [1, 2]\n",
-		"t2: 2018-01-09T10:40:47Z\nt4: 2098-01-09T10:40:47Z\n",
-		"a: {b: c, d: e}\n",
-		"a: 3s\n",
-		"a: <foo>\n",
-		"a: \"1:1\"\n",
-		"a: \"\\0\"\n",
-		"a: !!binary gIGC\n",
-		"a: !!binary |\n  " + strings.Repeat("kJCQ", 17) + "kJ\n  CQ\n",
-		"b: 2\na: 1\nd: 4\nc: 3\nsub:\n  e: 5\n",
-		"a: 1.2.3.4\n",
-		"a: \"2015-02-24T18:19:39Z\"\n",
-		"a: 'b: c'\n",
-		"a: 'Hello #comment'\n",
-		"a: 100.5\n",
-		"a: bogus\n",
-		"\"a\": double quoted map key",
-		"'a': single quoted map key",
-		"a: \"double quoted\"\nb: \"value map\"",
-		"a: 'single quoted'\nb: 'value map'",
+	tests := []struct {
+		YAML   string
+		Tokens token.Tokens
+	}{
+		{
+			YAML: `null
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.NullType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "null",
+					Origin:        "null\n\t\t",
+				},
+			},
+		},
+		{
+			YAML: `{}
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.MappingStartType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.FlowCollectionIndicator,
+					Value:         "{",
+					Origin:        "{",
+				},
+				{
+					Type:          token.MappingEndType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.FlowCollectionIndicator,
+					Value:         "}",
+					Origin:        "}",
+				},
+			},
+		},
+		{
+			YAML: `v: hi
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "hi",
+					Origin:        " hi\n",
+				},
+			},
+		},
+		{
+			YAML: `v: "true"
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.DoubleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "true",
+					Origin:        " \"true\"",
+				},
+			},
+		},
+		{
+			YAML: `v: "false"
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.DoubleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "false",
+					Origin:        " \"false\"",
+				},
+			},
+		},
+		{
+			YAML: `v: true
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.BoolType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "true",
+					Origin:        " true\n",
+				},
+			},
+		},
+		{
+			YAML: `v: false
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.BoolType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "false",
+					Origin:        " false\n",
+				},
+			},
+		},
+		{
+			YAML: `v: 10
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "10",
+					Origin:        " 10\n",
+				},
+			},
+		},
+		{
+			YAML: `v: -10
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "-10",
+					Origin:        " -10\n",
+				},
+			},
+		},
+		{
+			YAML: `v: 42
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "42",
+					Origin:        " 42\n",
+				},
+			},
+		},
+		{
+			YAML: `v: 4294967296
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "4294967296",
+					Origin:        " 4294967296\n",
+				},
+			},
+		},
+		{
+			YAML: `v: "10"
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.DoubleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "10",
+					Origin:        " \"10\"",
+				},
+			},
+		},
+		{
+			YAML: `v: 0.1
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.FloatType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "0.1",
+					Origin:        " 0.1\n",
+				},
+			},
+		},
+		{
+			YAML: `v: 0.99
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.FloatType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "0.99",
+					Origin:        " 0.99\n",
+				},
+			},
+		},
+		{
+			YAML: `v: -0.1
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.FloatType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "-0.1",
+					Origin:        " -0.1\n",
+				},
+			},
+		},
+		{
+			YAML: `v: .inf
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.InfinityType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         ".inf",
+					Origin:        " .inf\n",
+				},
+			},
+		},
+		{
+			YAML: `v: -.inf
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.InfinityType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "-.inf",
+					Origin:        " -.inf\n",
+				},
+			},
+		},
+		{
+			YAML: `v: .nan
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.NanType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         ".nan",
+					Origin:        " .nan\n",
+				},
+			},
+		},
+		{
+			YAML: `v: null
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.NullType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "null",
+					Origin:        " null\n",
+				},
+			},
+		},
+		{
+			YAML: `v: ""
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "v",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.DoubleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "",
+					Origin:        " \"\"",
+				},
+			},
+		},
+		{
+			YAML: `
+v:
+- A
+- B
+`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "\nv",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.SequenceEntryType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         "-",
+					Origin:        "\n-",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "A",
+					Origin:        " A\n",
+				},
+				{
+					Type:          token.SequenceEntryType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         "-",
+					Origin:        "-",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "B",
+					Origin:        " B",
+				},
+			},
+		},
+		{
+			YAML: `
+v:
+- A
+- |-
+ B
+ C
+`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "\nv",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.SequenceEntryType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         "-",
+					Origin:        "\n-",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "A",
+					Origin:        " A\n",
+				},
+				{
+					Type:          token.SequenceEntryType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         "-",
+					Origin:        "-",
+				},
+				{
+					Type:          token.LiteralType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockScalarIndicator,
+					Value:         "|-",
+					Origin:        " |-\n",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "B\nC",
+					Origin:        " B\n C\n",
+				},
+			},
+		},
+		{
+			YAML: `
+v:
+- A
+- 1
+- B:
+ - 2
+ - 3
+`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "v",
+					Origin:        "\nv",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.SequenceEntryType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         "-",
+					Origin:        "\n-",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "A",
+					Origin:        " A\n",
+				},
+				{
+					Type:          token.SequenceEntryType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         "-",
+					Origin:        "-",
+				},
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "1",
+					Origin:        " 1\n",
+				},
+				{
+					Type:          token.SequenceEntryType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         "-",
+					Origin:        "-",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "B",
+					Origin:        " B",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.SequenceEntryType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         "-",
+					Origin:        "\n -",
+				},
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "2",
+					Origin:        " 2\n ",
+				},
+				{
+					Type:          token.SequenceEntryType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         "-",
+					Origin:        "-",
+				},
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "3",
+					Origin:        " 3",
+				},
+			},
+		},
+		{
+			YAML: `
+a:
+ b: c
+`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "\na",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "b",
+					Origin:        "\n b",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "c",
+					Origin:        " c",
+				},
+			},
+		},
+		{
+			YAML: `a: '-'
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.SingleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "-",
+					Origin:        " '-'",
+				},
+			},
+		},
+		{
+			YAML: `123
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "123",
+					Origin:        "123\n\t\t",
+				},
+			},
+		},
+		{
+			YAML: `hello: world
+`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "hello",
+					Origin:        "hello",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "world",
+					Origin:        " world",
+				},
+			},
+		},
+		{
+			YAML: `a: null
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.NullType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "null",
+					Origin:        " null\n",
+				},
+			},
+		},
+		{
+			YAML: `a: {x: 1}
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.MappingStartType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.FlowCollectionIndicator,
+					Value:         "{",
+					Origin:        " {",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "x",
+					Origin:        "x",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "1",
+					Origin:        " 1",
+				},
+				{
+					Type:          token.MappingEndType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.FlowCollectionIndicator,
+					Value:         "}",
+					Origin:        "}",
+				},
+			},
+		},
+		{
+			YAML: `a: [1, 2]
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.SequenceStartType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.FlowCollectionIndicator,
+					Value:         "[",
+					Origin:        " [",
+				},
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "1",
+					Origin:        "1",
+				},
+				{
+					Type:          token.CollectEntryType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.FlowCollectionIndicator,
+					Value:         ",",
+					Origin:        ",",
+				},
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "2",
+					Origin:        " 2",
+				},
+				{
+					Type:          token.SequenceEndType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.FlowCollectionIndicator,
+					Value:         "]",
+					Origin:        "]",
+				},
+			},
+		},
+		{
+			YAML: `t2: 2018-01-09T10:40:47Z
+		t4: 2098-01-09T10:40:47Z
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "t2",
+					Origin:        "t2",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "2018-01-09T10:40:47Z",
+					Origin:        " 2018-01-09T10:40:47Z\n",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "\t\tt4",
+					Origin:        "\t\tt4",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "2098-01-09T10:40:47Z",
+					Origin:        " 2098-01-09T10:40:47Z\n",
+				},
+			},
+		},
+		{
+			YAML: `a: {b: c, d: e}
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.MappingStartType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.FlowCollectionIndicator,
+					Value:         "{",
+					Origin:        " {",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "b",
+					Origin:        "b",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "c",
+					Origin:        " c",
+				},
+				{
+					Type:          token.CollectEntryType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.FlowCollectionIndicator,
+					Value:         ",",
+					Origin:        ",",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "d",
+					Origin:        " d",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "e",
+					Origin:        " e",
+				},
+				{
+					Type:          token.MappingEndType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.FlowCollectionIndicator,
+					Value:         "}",
+					Origin:        "}",
+				},
+			},
+		},
+		{
+			YAML: `a: 3s
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "3s",
+					Origin:        " 3s\n",
+				},
+			},
+		},
+		{
+			YAML: `a: <foo>
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "<foo>",
+					Origin:        " <foo>\n",
+				},
+			},
+		},
+		{
+			YAML: `a: "1:1"
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.DoubleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "1:1",
+					Origin:        " \"1:1\"",
+				},
+			},
+		},
+		{
+			YAML: `a: "\0"
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.DoubleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "\\0",
+					Origin:        " \"\\0\"",
+				},
+			},
+		},
+		{
+			YAML: `a: !!binary gIGC
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.TagType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.NodePropertyIndicator,
+					Value:         "!!binary",
+					Origin:        " !!binary ",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "gIGC",
+					Origin:        "gIGC\n",
+				},
+			},
+		},
+		{
+			YAML: `
+a: !!binary |
+ kJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJ
+ CQ
+`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "\na",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.TagType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.NodePropertyIndicator,
+					Value:         "!!binary",
+					Origin:        " !!binary ",
+				},
+				{
+					Type:          token.LiteralType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockScalarIndicator,
+					Value:         "|",
+					Origin:        "|\n",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "kJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJ\nCQ\n",
+					Origin:        " kJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJ\n CQ\n",
+				},
+			},
+		},
+		{
+			YAML: `b: 2
+		a: 1
+		d: 4
+		c: 3
+		sub:
+		 e: 5
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "b",
+					Origin:        "b",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "2",
+					Origin:        " 2\n",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "\t\ta",
+					Origin:        "\t\ta",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "1",
+					Origin:        " 1\n",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "\t\td",
+					Origin:        "\t\td",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "4",
+					Origin:        " 4\n",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "\t\tc",
+					Origin:        "\t\tc",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "3",
+					Origin:        " 3\n",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "\t\tsub",
+					Origin:        "\t\tsub",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "\t\t e",
+					Origin:        "\n\t\t e",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.IntegerType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "5",
+					Origin:        " 5\n",
+				},
+			},
+		},
+		{
+			YAML: `a: 1.2.3.4
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "1.2.3.4",
+					Origin:        " 1.2.3.4\n",
+				},
+			},
+		},
+		{
+			YAML: `a: "2015-02-24T18:19:39Z"
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.DoubleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "2015-02-24T18:19:39Z",
+					Origin:        " \"2015-02-24T18:19:39Z\"",
+				},
+			},
+		},
+		{
+			YAML: `a: 'b: c'
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.SingleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "b: c",
+					Origin:        " 'b: c'",
+				},
+			},
+		},
+		{
+			YAML: `a: 'Hello #comment'
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.SingleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "Hello #comment",
+					Origin:        " 'Hello #comment'",
+				},
+			},
+		},
+		{
+			YAML: `a: 100.5
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.FloatType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "100.5",
+					Origin:        " 100.5\n",
+				},
+			},
+		},
+		{
+			YAML: `a: bogus
+		`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "bogus",
+					Origin:        " bogus\n",
+				},
+			},
+		},
+		{
+			YAML: `"a": double quoted map key`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.DoubleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "a",
+					Origin:        "\"a\"",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "double quoted map key",
+					Origin:        " double quoted map key",
+				},
+			},
+		},
+		{
+			YAML: `'a': single quoted map key`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.SingleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "a",
+					Origin:        "'a'",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "single quoted map key",
+					Origin:        " single quoted map key",
+				},
+			},
+		},
+		{
+			YAML: `a: "double quoted"
+		b: "value map"`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.DoubleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "double quoted",
+					Origin:        " \"double quoted\"",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "\t\tb",
+					Origin:        "\n\t\tb",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.DoubleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "value map",
+					Origin:        " \"value map\"",
+				},
+			},
+		},
+		{
+			YAML: `a: 'single quoted'
+		b: 'value map'`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "a",
+					Origin:        "a",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.SingleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "single quoted",
+					Origin:        " 'single quoted'",
+				},
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "\t\tb",
+					Origin:        "\n\t\tb",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.SingleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "value map",
+					Origin:        " 'value map'",
+				},
+			},
+		},
+		{
+			YAML: `json: '\"expression\": \"thi:\"'`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "json",
+					Origin:        "json",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.SingleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "\\\"expression\\\": \\\"thi:\\\"",
+					Origin:        " '\\\"expression\\\": \\\"thi:\\\"'",
+				},
+			},
+		},
+		{
+			YAML: `json: "\"expression\": \"thi:\""`,
+			Tokens: token.Tokens{
+				{
+					Type:          token.StringType,
+					CharacterType: token.CharacterTypeMiscellaneous,
+					Indicator:     token.NotIndicator,
+					Value:         "json",
+					Origin:        "json",
+				},
+				{
+					Type:          token.MappingValueType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.BlockStructureIndicator,
+					Value:         ":",
+					Origin:        ":",
+				},
+				{
+					Type:          token.DoubleQuoteType,
+					CharacterType: token.CharacterTypeIndicator,
+					Indicator:     token.QuotedScalarIndicator,
+					Value:         "\"expression\": \"thi:\"",
+					Origin:        " \"\\\"expression\\\": \\\"thi:\\\"\"",
+				},
+			},
+		},
 	}
-	for _, src := range sources {
-		lexer.Tokenize(src).Dump()
+	for _, test := range tests {
+		t.Run(test.YAML, func(t *testing.T) {
+			tokens := lexer.Tokenize(test.YAML)
+			if len(tokens) != len(test.Tokens) {
+				t.Fatalf("Tokenize(%q) token count mismatch, expected: %d got: %d", test.YAML, len(test.Tokens), len(tokens))
+			}
+			for i := range test.Tokens {
+				if tokens[i].Type != test.Tokens[i].Type {
+					t.Errorf("Tokenize(%q)[%d] token.Type mismatch, expected: %s got: %s", test.YAML, i, test.Tokens[i].Type, tokens[i].Type)
+				}
+				if tokens[i].CharacterType != test.Tokens[i].CharacterType {
+					t.Errorf("Tokenize(%q)[%d] token.CharacterType mismatch, expected: %s got: %s", test.YAML, i, test.Tokens[i].CharacterType, tokens[i].CharacterType)
+				}
+				if tokens[i].Indicator != test.Tokens[i].Indicator {
+					t.Errorf("Tokenize(%q)[%d] token.Indicator mismatch, expected: %s got: %s", test.YAML, i, test.Tokens[i].Indicator, tokens[i].Indicator)
+				}
+				if tokens[i].Value != test.Tokens[i].Value {
+					t.Errorf("Tokenize(%q)[%d] token.Value mismatch, expected: %q got: %q", test.YAML, i, test.Tokens[i].Value, tokens[i].Value)
+				}
+				if tokens[i].Origin != test.Tokens[i].Origin {
+					t.Errorf("Tokenize(%q)[%d] token.Origin mismatch, expected: %q got: %q", test.YAML, i, test.Tokens[i].Origin, tokens[i].Origin)
+				}
+			}
+		})
 	}
 }
 
@@ -619,3 +2384,38 @@ b: 1`,
 		})
 	}
 }
+
+func TestInvalid(t *testing.T) {
+	tests := []struct {
+		name string
+		src  string
+	}{
+		{
+			name: "literal opt with content",
+			src: `
+a: |invalid
+  foo`,
+		},
+		{
+			name: "literal opt",
+			src: `
+a: |invalid`,
+		},
+		{
+			name: "invalid single-quoted",
+			src:  `a: 'foobarbaz`,
+		},
+		{
+			name: "invalid double-quoted",
+			src:  `a: "\"key\": \"value:\"`,
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			got := lexer.Tokenize(test.src)
+			if got.InvalidToken() == nil {
+				t.Fatal("expected contains invalid token")
+			}
+		})
+	}
+}
diff --git a/parser/parser_test.go b/parser/parser_test.go
index 8d697e8..09bf8cb 100644
--- a/parser/parser_test.go
+++ b/parser/parser_test.go
@@ -83,6 +83,15 @@ func TestParser(t *testing.T) {
 }`,
 		"\"a\": a\n\"b\": b",
 		"'a': a\n'b': b",
+		"a: \r\n  b: 1\r\n",
+		"a_ok: \r  bc: 2\r",
+		"a_mk: \n  bd: 3\n",
+		"a: :a",
+		"{a: , b: c}",
+		"value: >\n",
+		"value: >\n\n",
+		"value: >\nother:",
+		"value: >\n\nother:",
 	}
 	for _, src := range sources {
 		if _, err := parser.Parse(lexer.Tokenize(src), 0); err != nil {
@@ -436,6 +445,20 @@ a:
     piyo
 `,
 		},
+		{
+			`
+v: |
+ a
+ b
+ c`,
+			`
+v: |
+ a
+ b
+ c
+`,
+		},
+
 		{
 			`
 a: |
@@ -592,6 +615,10 @@ i: 'j'
 			if err != nil {
 				t.Fatalf("%+v", err)
 			}
+			got := f.String()
+			if got != strings.TrimPrefix(test.expect, "\n") {
+				t.Fatalf("failed to parse comment:\nexpected:\n%s\ngot:\n%s", strings.TrimPrefix(test.expect, "\n"), got)
+			}
 			var v Visitor
 			for _, doc := range f.Docs {
 				ast.Walk(&v, doc.Body)
@@ -605,6 +632,268 @@ i: 'j'
 	}
 }
 
+func TestParseWhitespace(t *testing.T) {
+	tests := []struct {
+		source string
+		expect string
+	}{
+		{
+			`
+a: b
+
+c: d
+
+
+e: f
+g: h
+`,
+			`
+a: b
+
+c: d
+
+e: f
+g: h
+`,
+		},
+		{
+			`
+a:
+  - b: c
+    d: e
+
+  - f: g
+    h: i
+`,
+			`
+a:
+  - b: c
+    d: e
+
+  - f: g
+    h: i
+`,
+		},
+		{
+			`
+a:
+  - b: c
+    d: e
+
+  - f: g
+    h: i
+`,
+			`
+a:
+  - b: c
+    d: e
+
+  - f: g
+    h: i
+`,
+		},
+		{
+			`
+a:
+- b: c
+  d: e
+
+- f: g
+  h: i
+`,
+			`
+a:
+- b: c
+  d: e
+
+- f: g
+  h: i
+`,
+		},
+		{
+			`
+a:
+# comment 1
+- b: c
+  d: e
+
+# comment 2
+- f: g
+  h: i
+`,
+			`
+a:
+# comment 1
+- b: c
+  d: e
+
+# comment 2
+- f: g
+  h: i
+`,
+		},
+		{
+			`
+a:
+  # comment 1
+  - b: c
+    # comment 2
+    d: e
+
+  # comment 3
+  # comment 4
+  - f: g
+    h: i # comment 5
+`,
+			`
+a:
+  # comment 1
+  - b: c
+    # comment 2
+    d: e
+
+  # comment 3
+  # comment 4
+  - f: g
+    h: i # comment 5
+`,
+		},
+		{
+			`
+a:
+  # comment 1
+  - b: c
+    # comment 2
+    d: e
+
+  # comment 3
+  # comment 4
+  - f: |
+      g
+      g
+    h: i # comment 5
+`,
+			`
+a:
+  # comment 1
+  - b: c
+    # comment 2
+    d: e
+
+  # comment 3
+  # comment 4
+  - f: |
+      g
+      g
+    h: i # comment 5
+`,
+		},
+		{
+			`
+a:
+  # comment 1
+  - b: c
+    # comment 2
+    d: e
+
+  # comment 3
+  # comment 4
+  - f: |
+      asd
+      def
+
+    h: i # comment 5
+`,
+			`
+a:
+  # comment 1
+  - b: c
+    # comment 2
+    d: e
+
+  # comment 3
+  # comment 4
+  - f: |
+      asd
+      def
+
+    h: i # comment 5
+`,
+		},
+		{
+			`
+- b: c
+  d: e
+
+- f: g
+  h: i # comment 4
+		`,
+			`
+- b: c
+  d: e
+
+- f: g
+  h: i # comment 4
+`,
+		},
+		{
+			`
+a: null
+b: null
+
+d: e
+`,
+			`
+a: null
+b: null
+
+d: e
+`,
+		},
+		{
+			`
+foo:
+  bar: null # comment
+
+  baz: 1
+`,
+			`
+foo:
+  bar: null # comment
+
+  baz: 1
+`,
+		},
+		{
+			`
+foo:
+  bar: null # comment
+
+baz: 1
+`,
+			`
+foo:
+  bar: null # comment
+
+baz: 1
+`,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.source, func(t *testing.T) {
+			f, err := parser.ParseBytes([]byte(test.source), parser.ParseComments)
+			if err != nil {
+				t.Fatal(err)
+			}
+			got := f.String()
+			if got != strings.TrimPrefix(test.expect, "\n") {
+				t.Fatalf("failed to parse comment:\nexpected:\n%s\ngot:\n%s", strings.TrimPrefix(test.expect, "\n"), got)
+			}
+		})
+	}
+}
+
 func TestNewLineChar(t *testing.T) {
 	for _, f := range []string{
 		"lf.yml",
@@ -617,10 +906,11 @@ func TestNewLineChar(t *testing.T) {
 		}
 		actual := fmt.Sprintf("%v", ast)
 		expect := `a: "a"
+
 b: 1
 `
 		if expect != actual {
-			t.Fatal("unexpected result")
+			t.Fatalf("unexpected result\nexpected:\n%s\ngot:\n%s", expect, actual)
 		}
 	}
 }
@@ -687,11 +977,127 @@ a:
 - b: c
 - `,
 			`
-[4:1] empty sequence entry
+[4:1] empty sequence value
    2 | a:
    3 | - b: c
 >  4 | -
        ^
+`,
+		},
+		{
+			`
+a: |invalidopt
+  foo
+`,
+			`
+[2:4] found invalid token
+>  2 | a: |invalidopt
+          ^
+   3 |   foo`,
+		},
+		{
+			`
+a: 1
+b
+`,
+			`
+[3:1] required ':' and map value
+   2 | a: 1
+>  3 | b
+       ^
+`,
+		},
+		{
+			`
+a: 1
+b
+- c
+`,
+			`
+[4:1] required ':' and map value
+   2 | a: 1
+   3 | b
+>  4 | - c
+       ^
+`,
+		},
+		{
+			`a: [`,
+			`
+[1:4] sequence end token ']' not found
+>  1 | a: [
+          ^
+`,
+		},
+		{
+			`a: ]`,
+			`
+[1:4] could not find '[' character corresponding to ']'
+>  1 | a: ]
+          ^
+`,
+		},
+		{
+			`a: [ [1] [2] [3] ]`,
+			`
+[1:10] ',' or ']' must be specified
+>  1 | a: [ [1] [2] [3] ]
+                ^
+`,
+		},
+		{
+			`
+a: -
+b: -
+`,
+			`
+[3:4] empty sequence value
+   2 | a: -
+>  3 | b: -
+          ^
+`,
+		},
+		{
+			`
+a: - 1
+b: - 2
+`,
+			`
+[2:4] block sequence entries are not allowed in this context
+>  2 | a: - 1
+          ^
+   3 | b: - 2`,
+		},
+		{
+			`a: 'foobarbaz`,
+			`
+[1:4] found invalid token
+>  1 | a: 'foobarbaz
+          ^
+`,
+		},
+		{
+			`a: "\"key\": \"value:\"`,
+			`
+[1:4] found invalid token
+>  1 | a: "\"key\": \"value:\"
+          ^
+`,
+		},
+		{
+			`foo: [${should not be allowed}]`,
+			`
+[1:8] ',' or ']' must be specified
+>  1 | foo: [${should not be allowed}]
+              ^
+`,
+		},
+		{
+			`foo: [$[should not be allowed]]`,
+			`
+[1:8] ',' or ']' must be specified
+>  1 | foo: [$[should not be allowed]]
+              ^
 `,
 		},
 	}
@@ -827,8 +1233,9 @@ foo:
 		if len(f.Docs) != 1 {
 			t.Fatal("failed to parse content with same line comment")
 		}
-		if f.Docs[0].String() != strings.TrimPrefix(expected, "\n") {
-			t.Fatal("failed to parse comment")
+		got := f.Docs[0].String()
+		if got != strings.TrimPrefix(expected, "\n") {
+			t.Fatalf("failed to parse comment:\nexpected:\n%s\ngot:\n%s", strings.TrimPrefix(expected, "\n"), got)
 		}
 	})
 	t.Run("next line", func(t *testing.T) {
@@ -849,8 +1256,9 @@ foo:
 		if len(f.Docs) != 1 {
 			t.Fatal("failed to parse content with next line comment")
 		}
-		if f.Docs[0].String() != strings.TrimPrefix(expected, "\n") {
-			t.Fatal("failed to parse comment")
+		got := f.Docs[0].String()
+		if got != strings.TrimPrefix(expected, "\n") {
+			t.Fatalf("failed to parse comment:\nexpected:\n%s\ngot:\n%s", strings.TrimPrefix(expected, "\n"), got)
 		}
 	})
 	t.Run("next line and different indent", func(t *testing.T) {
@@ -870,8 +1278,9 @@ baz: 1`
 foo:
   bar: null # comment
 baz: 1`
-		if f.Docs[0].String() != strings.TrimPrefix(expected, "\n") {
-			t.Fatal("failed to parse comment")
+		got := f.Docs[0].String()
+		if got != strings.TrimPrefix(expected, "\n") {
+			t.Fatalf("failed to parse comment:\nexpected:\n%s\ngot:\n%s", strings.TrimPrefix(expected, "\n"), got)
 		}
 	})
 }
@@ -897,8 +1306,9 @@ foo:
   - bar: 1
 baz:
   - xxx`
-	if f.Docs[0].String() != strings.TrimPrefix(expected, "\n") {
-		t.Fatal("failed to parse comment")
+	got := f.Docs[0].String()
+	if got != strings.TrimPrefix(expected, "\n") {
+		t.Fatalf("failed to parse comment:\nexpected:\n%s\ngot:\n%s", strings.TrimPrefix(expected, "\n"), got)
 	}
 	t.Run("foo[0].bar", func(t *testing.T) {
 		path, err := yaml.PathString("$.foo[0].bar")
@@ -999,8 +1409,7 @@ func (c *pathCapturer) Visit(node ast.Node) ast.Visitor {
 	return c
 }
 
-type Visitor struct {
-}
+type Visitor struct{}
 
 func (v *Visitor) Visit(node ast.Node) ast.Visitor {
 	tk := node.GetToken()
diff --git a/path_test.go b/path_test.go
index c0073ce..8a4d6b5 100644
--- a/path_test.go
+++ b/path_test.go
@@ -104,6 +104,31 @@ store:
 			path:     builder().Root().Child("store").Child(`bicycle*unicycle`).Child("price").Build(),
 			expected: float64(20.25),
 		},
+		{
+			name: "$",
+			path: builder().Root().Build(),
+			expected: map[string]interface{}{
+				"store": map[string]interface{}{
+					"book": []interface{}{
+						map[string]interface{}{
+							"author": "john",
+							"price":  uint64(10),
+						},
+						map[string]interface{}{
+							"author": "ken",
+							"price":  uint64(12),
+						},
+					},
+					"bicycle": map[string]interface{}{
+						"color": "red",
+						"price": 19.95,
+					},
+					"bicycle*unicycle": map[string]interface{}{
+						"price": 20.25,
+					},
+				},
+			},
+		},
 	}
 	t.Run("PathString", func(t *testing.T) {
 		for _, test := range tests {
diff --git a/token/token_test.go b/token/token_test.go
index dc1b4df..27565fb 100644
--- a/token/token_test.go
+++ b/token/token_test.go
@@ -121,6 +121,10 @@ func TestIsNeedQuoted(t *testing.T) {
 		" a",
 		" a ",
 		"a ",
+		"null",
+		"Null",
+		"NULL",
+		"~",
 	}
 	for i, test := range needQuotedTests {
 		if !token.IsNeedQuoted(test) {
diff --git a/validate_test.go b/validate_test.go
index 265deb8..d73ee3a 100644
--- a/validate_test.go
+++ b/validate_test.go
@@ -5,6 +5,7 @@ import (
 	"testing"
 
 	"github.com/go-playground/validator/v10"
+
 	"github.com/goccy/go-yaml"
 )
 
diff --git a/yaml_test.go b/yaml_test.go
index 4446d31..c2dd670 100644
--- a/yaml_test.go
+++ b/yaml_test.go
@@ -2,11 +2,11 @@ package yaml_test
 
 import (
 	"bytes"
+	"errors"
 	"strings"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
-	"golang.org/x/xerrors"
 
 	"github.com/goccy/go-yaml"
 	"github.com/goccy/go-yaml/ast"
@@ -116,13 +116,13 @@ type unmarshalTest struct {
 
 func (t *unmarshalTest) UnmarshalYAML(b []byte) error {
 	if t.a != 0 {
-		return xerrors.New("unexpected field value to a")
+		return errors.New("unexpected field value to a")
 	}
 	if t.b != "" {
-		return xerrors.New("unexpected field value to b")
+		return errors.New("unexpected field value to b")
 	}
 	if t.c {
-		return xerrors.New("unexpected field value to c")
+		return errors.New("unexpected field value to c")
 	}
 	var v struct {
 		A int
@@ -151,13 +151,13 @@ func (t *unmarshalTest2) UnmarshalYAML(unmarshal func(interface{}) error) error
 		C bool
 	}
 	if t.a != 0 {
-		return xerrors.New("unexpected field value to a")
+		return errors.New("unexpected field value to a")
 	}
 	if t.b != "" {
-		return xerrors.New("unexpected field value to b")
+		return errors.New("unexpected field value to b")
 	}
 	if t.c {
-		return xerrors.New("unexpected field value to c")
+		return errors.New("unexpected field value to c")
 	}
 	if err := unmarshal(&v); err != nil {
 		return err
@@ -325,7 +325,7 @@ b: *a
 	if len(anchors) != 1 {
 		t.Fatal("failed to filter node")
 	}
-	anchor := anchors[0].(*ast.AnchorNode)
+	anchor, _ := anchors[0].(*ast.AnchorNode)
 	if err := anchor.SetName("b"); err != nil {
 		t.Fatal(err)
 	}
@@ -333,7 +333,7 @@ b: *a
 	if len(anchors) != 1 {
 		t.Fatal("failed to filter node")
 	}
-	alias := aliases[0].(*ast.AliasNode)
+	alias, _ := aliases[0].(*ast.AliasNode)
 	if err := alias.SetName("b"); err != nil {
 		t.Fatal(err)
 	}