Repository: intlify/vue-i18n-next
Pull request #1814 (2024-04-20 16:18:46)

breaking: drop modulo syntax
## breaking change
Named interpolation using modulo `%` is no longer supported in v10.
https://vue-i18n.intlify.dev/guide/essentials/syntax#rails-i18n-format

This PR modulo syntax is drop it.

PR #1795 has already announced a drop in v10 with a warning.

## migration plan
You can use eslint-plugin-vue-i18n.
eslint-plugin-vue-i18n has `@intlify/vue-i18n/no-deprecated-modulo-syntax` rule.
https://eslint-plugin-vue-i18n.intlify.dev/rules/no-deprecated-modulo-syntax.html
You can fixed with using `eslint --fix`
You must have migrated with eslint before upgrading to vue-i18n v10



Patch:
diff --git a/examples/composition/formatting/ruby.html b/examples/composition/formatting/ruby.html
deleted file mode 100644
index f6b0da9e..00000000
--- a/examples/composition/formatting/ruby.html
+++ /dev/null
@@ -1,57 +0,0 @@
-<!doctype html>
-<html>
-  <head>
-    <meta charset="utf-8" />
-    <title>Ruby style formatting example</title>
-    <script src="../../../node_modules/vue/dist/vue.global.js"></script>
-    <script src="../../../packages/vue-i18n/dist/vue-i18n.global.js"></script>
-  </head>
-  <body>
-    <div id="app">
-      <form>
-        <label for="locale-select">{{ t('message.language') }}</label>
-        <select id="locale-select" v-model="locale">
-          <option value="en">en</option>
-          <option value="ja">ja</option>
-        </select>
-      </form>
-      <p>{{ t('message.greeting', { name: 'kazupon' }) }}</p>
-    </div>
-    <script>
-      const { createApp } = Vue
-      const { createI18n, useI18n } = VueI18n
-
-      const i18n = createI18n({
-        legacy: false,
-        locale: 'ja',
-        messages: {
-          en: {
-            message: {
-              language: 'Language',
-              greeting: 'Hello, %{name}!'
-            }
-          },
-          ja: {
-            message: {
-              language: '言語',
-              greeting: 'こんにちは、%{name}！'
-            }
-          }
-        }
-      })
-
-      const app = createApp({
-        setup() {
-          const { t, locale } = useI18n()
-
-          // Something to do ...
-          //
-
-          return { t, locale }
-        }
-      })
-      app.use(i18n)
-      app.mount('#app')
-    </script>
-  </body>
-</html>
diff --git a/examples/legacy/formatting/ruby.html b/examples/legacy/formatting/ruby.html
deleted file mode 100644
index 5dd69295..00000000
--- a/examples/legacy/formatting/ruby.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<!doctype html>
-<html>
-  <head>
-    <meta charset="utf-8" />
-    <title>Ruby style formatting example</title>
-    <script src="../../../node_modules/vue/dist/vue.global.js"></script>
-    <script src="../../../packages/vue-i18n/dist/vue-i18n.global.js"></script>
-  </head>
-  <body>
-    <div id="app">
-      <form>
-        <label for="locale-select">{{ $t('message.language') }}</label>
-        <select id="locale-select" v-model="$i18n.locale">
-          <option value="en">en</option>
-          <option value="ja">ja</option>
-        </select>
-      </form>
-      <p>{{ $t('message.greeting', { name: 'kazupon' }) }}</p>
-    </div>
-    <script>
-      const { createApp } = Vue
-      const { createI18n } = VueI18n
-
-      const i18n = createI18n({
-        locale: 'ja',
-        messages: {
-          en: {
-            message: {
-              language: 'Language',
-              greeting: 'Hello, %{name}!'
-            }
-          },
-          ja: {
-            message: {
-              language: '言語',
-              greeting: 'こんにちは、%{name}！'
-            }
-          }
-        }
-      })
-
-      const app = createApp({})
-      app.use(i18n)
-      app.mount('#app')
-    </script>
-  </body>
-</html>
diff --git a/examples/petite/formatting/ruby.html b/examples/petite/formatting/ruby.html
deleted file mode 100644
index 708a9119..00000000
--- a/examples/petite/formatting/ruby.html
+++ /dev/null
@@ -1,52 +0,0 @@
-<!doctype html>
-<html>
-  <head>
-    <meta charset="utf-8" />
-    <title>Ruby style formatting example</title>
-    <script src="../../../node_modules/vue/dist/vue.global.js"></script>
-    <script src="../../../packages/petite-vue-i18n/dist/petite-vue-i18n.global.js"></script>
-  </head>
-  <body>
-    <div id="app">
-      <form>
-        <label for="locale-select">{{ t('message.language') }}</label>
-        <select id="locale-select" v-model="locale">
-          <option value="en">en</option>
-          <option value="ja">ja</option>
-        </select>
-      </form>
-      <p>{{ t('message.greeting', { name: 'kazupon' }) }}</p>
-    </div>
-    <script>
-      const { createApp } = Vue
-      const { createI18n, useI18n } = PetiteVueI18n
-
-      const i18n = createI18n({
-        locale: 'ja',
-        messages: {
-          en: {
-            'message.language': 'Language',
-            'message.greeting': 'Hello, %{name}!'
-          },
-          ja: {
-            'message.language': '言語',
-            'message.greeting': 'こんにちは、%{name}！'
-          }
-        }
-      })
-
-      const app = createApp({
-        setup() {
-          const { t, locale } = useI18n()
-
-          // Something to do ...
-          //
-
-          return { t, locale }
-        }
-      })
-      app.use(i18n)
-      app.mount('#app')
-    </script>
-  </body>
-</html>
diff --git a/packages/core-base/src/compilation.ts b/packages/core-base/src/compilation.ts
index 66ca10a4..79e4b135 100644
--- a/packages/core-base/src/compilation.ts
+++ b/packages/core-base/src/compilation.ts
@@ -1,7 +1,6 @@
 import { warn, format, isObject, isBoolean, isString } from '@intlify/shared'
 import {
   baseCompile as baseCompileCore,
-  CompileWarnCodes,
   defaultOnError,
   detectHtmlTag
 } from '@intlify/message-compiler'
@@ -12,8 +11,7 @@ import type {
   CompileOptions,
   CompileError,
   CompilerResult,
-  ResourceNode,
-  CompileWarn
+  ResourceNode
 } from '@intlify/message-compiler'
 import type { MessageFunction, MessageFunctions } from './runtime'
 import type { MessageCompilerContext } from './context'
@@ -29,17 +27,6 @@ function checkHtmlMessage(source: string, warnHtmlMessage?: boolean): void {
 const defaultOnCacheKey = (message: string): string => message
 let compileCache: unknown = Object.create(null)
 
-function onCompileWarn(_warn: CompileWarn): void {
-  if (_warn.code === CompileWarnCodes.USE_MODULO_SYNTAX) {
-    warn(
-      `The use of named interpolation with modulo syntax is deprecated. ` +
-        `It will be removed in v10.\n` +
-        `reference: https://vue-i18n.intlify.dev/guide/essentials/syntax#rails-i18n-format \n` +
-        `(message compiler warning message: ${_warn.message})`
-    )
-  }
-}
-
 export function clearCompileCache(): void {
   compileCache = Object.create(null)
 }
@@ -77,11 +64,6 @@ export const compileToFunction = <
     throw createCoreError(CoreErrorCodes.NOT_SUPPORT_NON_STRING_MESSAGE)
   }
 
-  // set onWarn
-  if (__DEV__) {
-    context.onWarn = onCompileWarn
-  }
-
   if (__RUNTIME__) {
     __DEV__ &&
       warn(
@@ -125,11 +107,6 @@ export function compile<
   message: MessageSource,
   context: MessageCompilerContext
 ): MessageFunction<Message> {
-  // set onWarn
-  if (__DEV__) {
-    context.onWarn = onCompileWarn
-  }
-
   if (
     (__ESM_BROWSER__ ||
       __NODE_JS__ ||
diff --git a/packages/core-base/src/context.ts b/packages/core-base/src/context.ts
index ee590f27..df939c3a 100644
--- a/packages/core-base/src/context.ts
+++ b/packages/core-base/src/context.ts
@@ -145,7 +145,7 @@ export type PostTranslationHandler<Message = string> = (
  */
 export type MessageCompilerContext = Pick<
   CompileOptions,
-  'onError' | 'onCacheKey' | 'onWarn'
+  'onError' | 'onCacheKey'
 > & {
   /**
    * Whether to allow the use locale messages of HTML formatting.
diff --git a/packages/core-base/src/warnings.ts b/packages/core-base/src/warnings.ts
index db6e0b29..152cf3d2 100644
--- a/packages/core-base/src/warnings.ts
+++ b/packages/core-base/src/warnings.ts
@@ -1,18 +1,17 @@
 import { format, incrementer } from '@intlify/shared'
-import { CompileWarnCodes } from '@intlify/message-compiler'
 
-const code = CompileWarnCodes.__EXTEND_POINT__
+const code = 1
 const inc = incrementer(code)
 
 export const CoreWarnCodes = {
-  NOT_FOUND_KEY: code, // 2
-  FALLBACK_TO_TRANSLATE: inc(), // 3
-  CANNOT_FORMAT_NUMBER: inc(), // 4
-  FALLBACK_TO_NUMBER_FORMAT: inc(), // 5
-  CANNOT_FORMAT_DATE: inc(), // 6
-  FALLBACK_TO_DATE_FORMAT: inc(), // 7
-  EXPERIMENTAL_CUSTOM_MESSAGE_COMPILER: inc(), // 8
-  __EXTEND_POINT__: inc() // 9
+  NOT_FOUND_KEY: code, // 1
+  FALLBACK_TO_TRANSLATE: inc(), // 2
+  CANNOT_FORMAT_NUMBER: inc(), // 3
+  FALLBACK_TO_NUMBER_FORMAT: inc(), // 4
+  CANNOT_FORMAT_DATE: inc(), // 5
+  FALLBACK_TO_DATE_FORMAT: inc(), // 6
+  EXPERIMENTAL_CUSTOM_MESSAGE_COMPILER: inc(), // 7
+  __EXTEND_POINT__: inc() // 8
 } as const
 
 export type CoreWarnCodes = (typeof CoreWarnCodes)[keyof typeof CoreWarnCodes]
diff --git a/packages/message-compiler/src/index.ts b/packages/message-compiler/src/index.ts
index 9f129cf6..f4fa8bf8 100644
--- a/packages/message-compiler/src/index.ts
+++ b/packages/message-compiler/src/index.ts
@@ -1,7 +1,6 @@
 export * from './location'
 export * from './nodes'
 export * from './options'
-export * from './warnings'
 export * from './errors'
 export * from './helpers'
 export * from './parser'
diff --git a/packages/message-compiler/src/options.ts b/packages/message-compiler/src/options.ts
index f9597065..46401056 100644
--- a/packages/message-compiler/src/options.ts
+++ b/packages/message-compiler/src/options.ts
@@ -1,7 +1,5 @@
 import type { CompileError } from './errors'
-import type { CompileWarn } from './warnings'
 
-export type CompileWarnHandler = (warn: CompileWarn) => void
 export type CompileErrorHandler = (error: CompileError) => void
 export type CacheKeyHandler = (source: string) => string
 
@@ -13,12 +11,10 @@ export interface TokenizeOptions {
 export interface ParserOptions {
   location?: boolean // default true
   onCacheKey?: (source: string) => string
-  onWarn?: CompileWarnHandler
   onError?: CompileErrorHandler
 }
 
 export interface TransformOptions {
-  onWarn?: CompileWarnHandler
   onError?: CompileErrorHandler
 }
 
@@ -27,7 +23,6 @@ export interface CodeGenOptions {
   mode?: 'normal' | 'arrow' // default normal
   breakLineCode?: '\n' | ';' // default newline
   needIndent?: boolean // default true
-  onWarn?: CompileWarnHandler
   onError?: CompileErrorHandler
   // Generate source map?
   // - Default: false
diff --git a/packages/message-compiler/src/parser.ts b/packages/message-compiler/src/parser.ts
index a4619f72..5b960802 100644
--- a/packages/message-compiler/src/parser.ts
+++ b/packages/message-compiler/src/parser.ts
@@ -1,6 +1,5 @@
 import { createLocation } from './location'
 import { createCompileError, CompileErrorCodes } from './errors'
-import { createCompileWarn, CompileWarnCodes } from './warnings'
 import { createTokenizer, TokenTypes } from './tokenizer'
 import { NodeTypes } from './nodes'
 import { assign } from '@intlify/shared'
@@ -58,7 +57,7 @@ function fromEscapeSequence(
 export function createParser(options: ParserOptions = {}): Parser {
   const location = options.location !== false
 
-  const { onError, onWarn } = options
+  const { onError } = options
   function emitError(
     tokenzer: Tokenizer,
     code: CompileErrorCodes,
@@ -78,21 +77,6 @@ export function createParser(options: ParserOptions = {}): Parser {
       onError(err)
     }
   }
-  function emitWarn(
-    tokenzer: Tokenizer,
-    code: CompileWarnCodes,
-    start: Position,
-    offset: number,
-    ...args: unknown[]
-  ): void {
-    const end = tokenzer.currentPosition()
-    end.offset += offset
-    end.column += offset
-    if (onWarn) {
-      const loc = location ? createLocation(start, end) : null
-      onWarn(createCompileWarn(code, loc, args))
-    }
-  }
 
   function startNode(type: NodeTypes, offset: number, loc: Position): Node {
     const node = { type } as Node
@@ -146,18 +130,11 @@ export function createParser(options: ParserOptions = {}): Parser {
     return node
   }
 
-  function parseNamed(
-    tokenizer: Tokenizer,
-    key: string,
-    modulo?: boolean
-  ): NamedNode {
+  function parseNamed(tokenizer: Tokenizer, key: string): NamedNode {
     const context = tokenizer.context()
     const { lastOffset: offset, lastStartLoc: loc } = context // get brace left loc
     const node = startNode(NodeTypes.Named, offset, loc) as NamedNode
     node.key = key
-    if (modulo === true) {
-      node.modulo = true
-    }
     tokenizer.nextToken() // skip brach right
     endNode(node, tokenizer.currentOffset(), tokenizer.currentPosition())
     return node
@@ -362,7 +339,6 @@ export function createParser(options: ParserOptions = {}): Parser {
     node.items = []
 
     let nextToken: Token | null = null
-    let modulo: boolean | null = null
     do {
       const token = nextToken || tokenizer.nextToken()
       nextToken = null
@@ -391,9 +367,6 @@ export function createParser(options: ParserOptions = {}): Parser {
           }
           node.items.push(parseList(tokenizer, token.value || ''))
           break
-        case TokenTypes.Modulo:
-          modulo = true
-          break
         case TokenTypes.Named:
           if (token.value == null) {
             emitError(
@@ -404,17 +377,7 @@ export function createParser(options: ParserOptions = {}): Parser {
               getTokenCaption(token)
             )
           }
-          node.items.push(parseNamed(tokenizer, token.value || '', !!modulo))
-          if (modulo) {
-            emitWarn(
-              tokenizer,
-              CompileWarnCodes.USE_MODULO_SYNTAX,
-              context.lastStartLoc,
-              0,
-              getTokenCaption(token)
-            )
-            modulo = null
-          }
+          node.items.push(parseNamed(tokenizer, token.value || ''))
           break
         case TokenTypes.Literal:
           if (token.value == null) {
diff --git a/packages/message-compiler/src/tokenizer.ts b/packages/message-compiler/src/tokenizer.ts
index cae30a85..fab00985 100644
--- a/packages/message-compiler/src/tokenizer.ts
+++ b/packages/message-compiler/src/tokenizer.ts
@@ -11,14 +11,13 @@ export const enum TokenTypes {
   Pipe,
   BraceLeft,
   BraceRight,
-  Modulo,
-  Named, // 5
-  List,
+  Named,
+  List, // 5
   Literal,
   LinkedAlias,
   LinkedDot,
-  LinkedDelimiter, // 10
-  LinkedKey,
+  LinkedDelimiter,
+  LinkedKey, // 10
   LinkedModifier,
   InvalidPlace,
   EOF
@@ -30,7 +29,6 @@ const enum TokenChars {
   BraceRight = '}',
   ParenLeft = '(',
   ParenRight = ')',
-  Modulo = '%',
   LinkedAlias = '@',
   LinkedDot = '.',
   LinkedDelimiter = ':'
@@ -308,7 +306,6 @@ export function createTokenizer(
         return isIdentifierStart(scnr.peek())
       } else if (
         ch === TokenChars.LinkedAlias ||
-        ch === TokenChars.Modulo ||
         ch === TokenChars.Pipe ||
         ch === TokenChars.LinkedDelimiter ||
         ch === TokenChars.LinkedDot ||
@@ -340,43 +337,21 @@ export function createTokenizer(
     return ret
   }
 
-  function detectModuloStart(scnr: Scanner): {
-    isModulo: boolean
-    hasSpace: boolean
-  } {
-    const spaces = peekSpaces(scnr)
-
-    const ret =
-      scnr.currentPeek() === TokenChars.Modulo &&
-      scnr.peek() === TokenChars.BraceLeft
-    scnr.resetPeek()
-
-    return {
-      isModulo: ret,
-      hasSpace: spaces.length > 0
-    }
-  }
-
   function isTextStart(scnr: Scanner, reset = true): boolean {
-    const fn = (hasSpace = false, prev = '', detectModulo = false): boolean => {
+    const fn = (hasSpace = false, prev = ''): boolean => {
       const ch = scnr.currentPeek()
       if (ch === TokenChars.BraceLeft) {
-        return prev === TokenChars.Modulo ? false : hasSpace
+        return hasSpace
       } else if (ch === TokenChars.LinkedAlias || !ch) {
-        return prev === TokenChars.Modulo ? true : hasSpace
-      } else if (ch === TokenChars.Modulo) {
-        scnr.peek()
-        return fn(hasSpace, TokenChars.Modulo, true)
+        return hasSpace
       } else if (ch === TokenChars.Pipe) {
-        return prev === TokenChars.Modulo || detectModulo
-          ? true
-          : !(prev === SPACE || prev === NEW_LINE)
+        return !(prev === SPACE || prev === NEW_LINE)
       } else if (ch === SPACE) {
         scnr.peek()
-        return fn(true, SPACE, detectModulo)
+        return fn(true, SPACE)
       } else if (ch === NEW_LINE) {
         scnr.peek()
-        return fn(true, NEW_LINE, detectModulo)
+        return fn(true, NEW_LINE)
       } else {
         return true
       }
@@ -469,16 +444,6 @@ export function createTokenizer(
     return num
   }
 
-  function readModulo(scnr: Scanner): string {
-    skipSpaces(scnr)
-    const ch = scnr.currentChar()
-    if (ch !== TokenChars.Modulo) {
-      emitError(CompileErrorCodes.EXPECTED_TOKEN, currentPosition(), 0, ch)
-    }
-    scnr.next()
-    return TokenChars.Modulo
-  }
-
   function readText(scnr: Scanner): string {
     let buf = ''
 
@@ -492,13 +457,6 @@ export function createTokenizer(
         !ch
       ) {
         break
-      } else if (ch === TokenChars.Modulo) {
-        if (isTextStart(scnr)) {
-          buf += ch
-          scnr.next()
-        } else {
-          break
-        }
       } else if (ch === SPACE || ch === NEW_LINE) {
         if (isTextStart(scnr)) {
           buf += ch
@@ -684,7 +642,6 @@ export function createTokenizer(
       const ch = scnr.currentChar()
       if (
         ch === TokenChars.BraceLeft ||
-        ch === TokenChars.Modulo ||
         ch === TokenChars.LinkedAlias ||
         ch === TokenChars.Pipe ||
         ch === TokenChars.ParenLeft ||
@@ -997,13 +954,6 @@ export function createTokenizer(
           return token
         }
 
-        const { isModulo, hasSpace } = detectModuloStart(scnr)
-        if (isModulo) {
-          return hasSpace
-            ? getToken(context, TokenTypes.Text, readText(scnr))
-            : getToken(context, TokenTypes.Modulo, readModulo(scnr))
-        }
-
         if (isTextStart(scnr)) {
           return getToken(context, TokenTypes.Text, readText(scnr))
         }
diff --git a/packages/message-compiler/src/warnings.ts b/packages/message-compiler/src/warnings.ts
deleted file mode 100644
index 0bf66ec6..00000000
--- a/packages/message-compiler/src/warnings.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { format } from '@intlify/shared'
-
-import type { SourceLocation } from './location'
-
-export const CompileWarnCodes = {
-  USE_MODULO_SYNTAX: 1,
-  __EXTEND_POINT__: 2
-} as const
-
-export interface CompileWarn {
-  message: string
-  code: number
-  location?: SourceLocation
-}
-
-export type CompileWarnCodes =
-  (typeof CompileWarnCodes)[keyof typeof CompileWarnCodes]
-
-/** @internal */
-export const warnMessages: { [code: number]: string } = {
-  [CompileWarnCodes.USE_MODULO_SYNTAX]: `Use modulo before '{{0}}'.`
-}
-
-export function createCompileWarn<T extends number>(
-  code: T,
-  loc: SourceLocation | null,
-  ...args: unknown[]
-): CompileWarn {
-  const msg = __DEV__ ? format(warnMessages[code] || '', ...(args || [])) : code
-  const message: CompileWarn = { message: String(msg), code }
-  if (loc) {
-    message.location = loc
-  }
-  return message
-}
diff --git a/packages/vue-i18n-core/src/warnings.ts b/packages/vue-i18n-core/src/warnings.ts
index a9a954ad..d698ed90 100644
--- a/packages/vue-i18n-core/src/warnings.ts
+++ b/packages/vue-i18n-core/src/warnings.ts
@@ -5,16 +5,16 @@ const code = CoreWarnCodes.__EXTEND_POINT__
 const inc = incrementer(code)
 
 export const I18nWarnCodes = {
-  FALLBACK_TO_ROOT: code, // 9
-  NOT_SUPPORTED_PRESERVE: inc(), // 10
-  NOT_SUPPORTED_FORMATTER: inc(), // 11
-  NOT_SUPPORTED_PRESERVE_DIRECTIVE: inc(), // 12
-  NOT_SUPPORTED_GET_CHOICE_INDEX: inc(), // 13
-  COMPONENT_NAME_LEGACY_COMPATIBLE: inc(), // 14
-  NOT_FOUND_PARENT_SCOPE: inc(), // 15
-  IGNORE_OBJ_FLATTEN: inc(), // 16
-  NOTICE_DROP_ALLOW_COMPOSITION: inc(), // 17
-  NOTICE_DROP_TRANSLATE_EXIST_COMPATIBLE_FLAG: inc() // 18
+  FALLBACK_TO_ROOT: code, // 8
+  NOT_SUPPORTED_PRESERVE: inc(), // 9
+  NOT_SUPPORTED_FORMATTER: inc(), // 10
+  NOT_SUPPORTED_PRESERVE_DIRECTIVE: inc(), // 11
+  NOT_SUPPORTED_GET_CHOICE_INDEX: inc(), // 12
+  COMPONENT_NAME_LEGACY_COMPATIBLE: inc(), // 13
+  NOT_FOUND_PARENT_SCOPE: inc(), // 14
+  IGNORE_OBJ_FLATTEN: inc(), // 15
+  NOTICE_DROP_ALLOW_COMPOSITION: inc(), // 16
+  NOTICE_DROP_TRANSLATE_EXIST_COMPATIBLE_FLAG: inc() // 17
 } as const
 
 type I18nWarnCodes = (typeof I18nWarnCodes)[keyof typeof I18nWarnCodes]
diff --git a/rollup.config.mjs b/rollup.config.mjs
index 3f46124e..fee0f19b 100644
--- a/rollup.config.mjs
+++ b/rollup.config.mjs
@@ -380,8 +380,6 @@ function createReplacePlugin(
       ? {
           'emitError(': `/*#__PURE__*/ emitError(`,
           'createCompileError(': `/*#__PURE__*/ createCompileError(`,
-          'emitWarn(': `/*#__PURE__*/ emitWarn(`,
-          'createCompileWarn(': `/*#__PURE__*/ createCompileWarn(`,
           'function createCoreError(': `/*#__PURE__*/ function createCoreError(`,
           'throw createCoreError(': `throw Error(`,
           'function createI18nError(': `/*#__PURE__*/ function createI18nError(`,
diff --git a/spec/syntax.ebnf b/spec/syntax.ebnf
index f09313a3..02360494 100644
--- a/spec/syntax.ebnf
+++ b/spec/syntax.ebnf
@@ -1,5 +1,5 @@
 (*
- * Inltify message syntax v0.4.0
+ * Inltify message syntax v0.5.0
  * (vue-i18n compatible)
  *)
 
@@ -13,8 +13,7 @@ Message ::= (Text? (Placeholder | Linked)? Text?)+;
 (* primitives *)
 Text ::= TextChar+;
 Placeholder ::= Named | List | StringLiteral;
-Modulo ::= "%";
-Named ::= Modulo? "{" Space? (NamedIdentifier) Space? "}";
+Named ::= "{" Space? (NamedIdentifier) Space? "}";
 List ::= "{" Space? (NumberLiteral) Space? "}";
 Linked ::= "@" (LinkedModifier)? LinkedDelimiter LinkedRefer;
 LinkedRefer ::= LinkedKey | Placeholder;


Test patch:
diff --git a/e2e/formatting/ruby.spec.ts b/e2e/formatting/ruby.spec.ts
deleted file mode 100644
index 14697e37..00000000
--- a/e2e/formatting/ruby.spec.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { getText } from '../helper'
-;['composition', 'petite', 'legacy'].forEach(pattern => {
-  describe(`${pattern}`, () => {
-    beforeAll(async () => {
-      await page.goto(
-        `http://localhost:8080/examples/${pattern}/formatting/ruby.html`
-      )
-    })
-
-    test('initial rendering', async () => {
-      expect(await getText(page, '#app p')).toMatch('こんにちは、kazupon！')
-    })
-
-    test('change locale', async () => {
-      await page.selectOption('#app select', 'en')
-      expect(await getText(page, '#app p')).toMatch('Hello, kazupon!')
-    })
-  })
-})
diff --git a/packages/core-base/test/compilation.test.ts b/packages/core-base/test/compilation.test.ts
index 235f6ea6..c104835e 100644
--- a/packages/core-base/test/compilation.test.ts
+++ b/packages/core-base/test/compilation.test.ts
@@ -60,19 +60,6 @@ describe('compileToFunction', () => {
     })
     expect(occured).toBe(true)
   })
-
-  test('modulo syntax warning', () => {
-    const mockWarn = vi.spyOn(shared, 'warn')
-    mockWarn.mockImplementation(() => {})
-
-    compileToFunction('hello %{name}!', {
-      ...DEFAULT_CONTEXT
-    })
-    expect(mockWarn).toHaveBeenCalledTimes(1)
-    expect(mockWarn.mock.calls[0][0]).includes(
-      `The use of named interpolation with modulo syntax is deprecated. It will be removed in v10.`
-    )
-  })
 })
 
 describe('compile', () => {
@@ -132,15 +119,4 @@ describe('compile', () => {
     })
     expect(occured).toBe(true)
   })
-
-  test('modulo syntax warning', () => {
-    const mockWarn = vi.spyOn(shared, 'warn')
-    mockWarn.mockImplementation(() => {})
-
-    compile('%{msg} world!', DEFAULT_CONTEXT)
-    expect(mockWarn).toHaveBeenCalledTimes(1)
-    expect(mockWarn.mock.calls[0][0]).includes(
-      `The use of named interpolation with modulo syntax is deprecated. It will be removed in v10.`
-    )
-  })
 })
diff --git a/packages/core-base/test/warnings.test.ts b/packages/core-base/test/warnings.test.ts
index 211460d4..6a33eecb 100644
--- a/packages/core-base/test/warnings.test.ts
+++ b/packages/core-base/test/warnings.test.ts
@@ -1,5 +1,5 @@
 import { CoreWarnCodes } from '../src/warnings'
 
 test('CoreWarnCodes', () => {
-  expect(CoreWarnCodes.NOT_FOUND_KEY).toBe(2)
+  expect(CoreWarnCodes.NOT_FOUND_KEY).toBe(1)
 })
diff --git a/packages/message-compiler/test/__snapshots__/compiler.test.ts.snap b/packages/message-compiler/test/__snapshots__/compiler.test.ts.snap
index d458a7b7..76abaa3a 100644
--- a/packages/message-compiler/test/__snapshots__/compiler.test.ts.snap
+++ b/packages/message-compiler/test/__snapshots__/compiler.test.ts.snap
@@ -317,83 +317,6 @@ exports[`compiler options > optimize: false > ast 1`] = `
 }
 `;
 
-exports[`compiler options > warning > ast 1`] = `
-{
-  "body": {
-    "end": 12,
-    "items": [
-      {
-        "end": 6,
-        "key": "msg",
-        "loc": {
-          "end": {
-            "column": 7,
-            "line": 1,
-            "offset": 6,
-          },
-          "start": {
-            "column": 2,
-            "line": 1,
-            "offset": 1,
-          },
-        },
-        "modulo": true,
-        "start": 1,
-        "type": 4,
-      },
-      {
-        "end": 12,
-        "loc": {
-          "end": {
-            "column": 13,
-            "line": 1,
-            "offset": 12,
-          },
-          "start": {
-            "column": 7,
-            "line": 1,
-            "offset": 6,
-          },
-        },
-        "start": 6,
-        "type": 3,
-        "value": " world",
-      },
-    ],
-    "loc": {
-      "end": {
-        "column": 13,
-        "line": 1,
-        "offset": 12,
-      },
-      "start": {
-        "column": 1,
-        "line": 1,
-        "offset": 0,
-      },
-    },
-    "start": 0,
-    "type": 2,
-  },
-  "end": 12,
-  "loc": {
-    "end": {
-      "column": 13,
-      "line": 1,
-      "offset": 12,
-    },
-    "source": "%{msg} world",
-    "start": {
-      "column": 1,
-      "line": 1,
-      "offset": 0,
-    },
-  },
-  "start": 0,
-  "type": 0,
-}
-`;
-
 exports[`edge cases >  | | |  > code 1`] = `
 "function __msg__ (ctx) {
   const { normalize: _normalize, plural: _plural } = ctx
@@ -444,7 +367,7 @@ exports[`edge cases > %{nickname} %{action} issue %{code} > code 1`] = `
 "function __msg__ (ctx) {
   const { normalize: _normalize, interpolate: _interpolate, named: _named } = ctx
   return _normalize([
-    _interpolate(_named("nickname")), " ", _interpolate(_named("action")), " issue ", _interpolate(_named("code"))
+    "%", _interpolate(_named("nickname")), " %", _interpolate(_named("action")), " issue %", _interpolate(_named("code"))
   ])
 }"
 `;
diff --git a/packages/message-compiler/test/__snapshots__/tokenizer.test.ts.snap b/packages/message-compiler/test/__snapshots__/tokenizer.test.ts.snap
index 94eb379b..43eca717 100644
--- a/packages/message-compiler/test/__snapshots__/tokenizer.test.ts.snap
+++ b/packages/message-compiler/test/__snapshots__/tokenizer.test.ts.snap
@@ -63,7 +63,7 @@ exports[`token analysis > " | | |" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -147,7 +147,7 @@ exports[`token analysis > " foo | | bar" tokens 1`] = `
         "offset": 12,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -183,7 +183,7 @@ exports[`token analysis > " hello world " tokens 1`] = `
         "offset": 13,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -203,7 +203,7 @@ exports[`token analysis > "" tokens 1`] = `
         "offset": 0,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -239,7 +239,7 @@ exports[`token analysis > "'single-quote'" tokens 1`] = `
         "offset": 14,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -275,7 +275,7 @@ exports[`token analysis > "..." tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -351,7 +351,7 @@ exports[`token analysis > "@.lower: {'no apples'} | {1 apple | @:{count　apples
         "offset": 0,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -367,7 +367,7 @@ exports[`token analysis > "@.lower: {'no apples'} | {1 apple | @:{count　apples
         "offset": 1,
       },
     },
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
@@ -383,7 +383,7 @@ exports[`token analysis > "@.lower: {'no apples'} | {1 apple | @:{count　apples
         "offset": 2,
       },
     },
-    "type": 12,
+    "type": 11,
     "value": "lower",
   },
   {
@@ -399,7 +399,7 @@ exports[`token analysis > "@.lower: {'no apples'} | {1 apple | @:{count　apples
         "offset": 7,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -447,7 +447,7 @@ exports[`token analysis > "@.lower: {'no apples'} | {1 apple | @:{count　apples
         "offset": 10,
       },
     },
-    "type": 7,
+    "type": 6,
     "value": "no apples",
   },
   {
@@ -511,7 +511,7 @@ exports[`token analysis > "@.lower: {'no apples'} | {1 apple | @:{count　apples
         "offset": 26,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "1",
   },
   {
@@ -559,7 +559,7 @@ exports[`token analysis > "@.lower: {'no apples'} | {1 apple | @:{count　apples
         "offset": 36,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -575,7 +575,7 @@ exports[`token analysis > "@.lower: {'no apples'} | {1 apple | @:{count　apples
         "offset": 37,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -607,7 +607,7 @@ exports[`token analysis > "@.lower: {'no apples'} | {1 apple | @:{count　apples
         "offset": 39,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "count",
   },
   {
@@ -639,7 +639,7 @@ exports[`token analysis > "@.lower: {'no apples'} | {1 apple | @:{count　apples
         "offset": 51,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -659,7 +659,7 @@ exports[`token analysis > "@.lower:{'no apples'} | {1} apple | {count}　apples"
         "offset": 0,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -675,7 +675,7 @@ exports[`token analysis > "@.lower:{'no apples'} | {1} apple | {count}　apples"
         "offset": 1,
       },
     },
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
@@ -691,7 +691,7 @@ exports[`token analysis > "@.lower:{'no apples'} | {1} apple | {count}　apples"
         "offset": 2,
       },
     },
-    "type": 12,
+    "type": 11,
     "value": "lower",
   },
   {
@@ -707,7 +707,7 @@ exports[`token analysis > "@.lower:{'no apples'} | {1} apple | {count}　apples"
         "offset": 7,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -739,7 +739,7 @@ exports[`token analysis > "@.lower:{'no apples'} | {1} apple | {count}　apples"
         "offset": 9,
       },
     },
-    "type": 7,
+    "type": 6,
     "value": "no apples",
   },
   {
@@ -803,7 +803,7 @@ exports[`token analysis > "@.lower:{'no apples'} | {1} apple | {count}　apples"
         "offset": 25,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "1",
   },
   {
@@ -883,7 +883,7 @@ exports[`token analysis > "@.lower:{'no apples'} | {1} apple | {count}　apples"
         "offset": 37,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "count",
   },
   {
@@ -931,7 +931,7 @@ exports[`token analysis > "@.lower:{'no apples'} | {1} apple | {count}　apples"
         "offset": 50,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -967,7 +967,7 @@ exports[`token analysis > "\\"double-qoute\\"" tokens 1`] = `
         "offset": 14,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -1003,7 +1003,7 @@ exports[`token analysis > "{0} {1}　{2}" tokens 1`] = `
         "offset": 1,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -1067,7 +1067,7 @@ exports[`token analysis > "{0} {1}　{2}" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "1",
   },
   {
@@ -1131,7 +1131,7 @@ exports[`token analysis > "{0} {1}　{2}" tokens 1`] = `
         "offset": 9,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "2",
   },
   {
@@ -1163,7 +1163,7 @@ exports[`token analysis > "{0} {1}　{2}" tokens 1`] = `
         "offset": 11,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -1199,7 +1199,7 @@ exports[`token analysis > "{0}\\n{1}\\r\\n{2}" tokens 1`] = `
         "offset": 1,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -1264,7 +1264,7 @@ exports[`token analysis > "{0}\\n{1}\\r\\n{2}" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "1",
   },
   {
@@ -1329,7 +1329,7 @@ exports[`token analysis > "{0}\\n{1}\\r\\n{2}" tokens 1`] = `
         "offset": 10,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "2",
   },
   {
@@ -1361,7 +1361,7 @@ exports[`token analysis > "{0}\\n{1}\\r\\n{2}" tokens 1`] = `
         "offset": 12,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -1397,7 +1397,7 @@ exports[`token analysis > "{first} {middle}　{last}" tokens 1`] = `
         "offset": 1,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "first",
   },
   {
@@ -1461,7 +1461,7 @@ exports[`token analysis > "{first} {middle}　{last}" tokens 1`] = `
         "offset": 9,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "middle",
   },
   {
@@ -1525,7 +1525,7 @@ exports[`token analysis > "{first} {middle}　{last}" tokens 1`] = `
         "offset": 18,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "last",
   },
   {
@@ -1557,7 +1557,7 @@ exports[`token analysis > "{first} {middle}　{last}" tokens 1`] = `
         "offset": 23,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -1593,7 +1593,7 @@ exports[`token analysis > "{first}\\n{middle}\\r\\n{last}" tokens 1`] = `
         "offset": 1,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "first",
   },
   {
@@ -1658,7 +1658,7 @@ exports[`token analysis > "{first}\\n{middle}\\r\\n{last}" tokens 1`] = `
         "offset": 9,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "middle",
   },
   {
@@ -1723,7 +1723,7 @@ exports[`token analysis > "{first}\\n{middle}\\r\\n{last}" tokens 1`] = `
         "offset": 19,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "last",
   },
   {
@@ -1755,7 +1755,7 @@ exports[`token analysis > "{first}\\n{middle}\\r\\n{last}" tokens 1`] = `
         "offset": 24,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -1791,7 +1791,7 @@ exports[`token analysis > "1 + 1" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -1849,7 +1849,7 @@ exports[`token analysis > "foo@bar.com" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -1881,7 +1881,7 @@ exports[`token analysis > "foo@bar.com" tokens 1`] = `
         "offset": 11,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -1917,7 +1917,7 @@ exports[`token analysis > "hello world" tokens 1`] = `
         "offset": 11,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -1953,7 +1953,7 @@ exports[`token analysis > "hello:" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -1989,7 +1989,7 @@ exports[`token analysis > "hello\\\\nworld" tokens 1`] = `
         "offset": 12,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -2026,7 +2026,7 @@ world",
         "offset": 11,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -2062,7 +2062,7 @@ exports[`token analysis > "hi %name" tokens 1`] = `
         "offset": 8,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -2120,7 +2120,7 @@ exports[`token analysis > "hi @ :name !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -2136,7 +2136,7 @@ exports[`token analysis > "hi @ :name !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -2152,7 +2152,7 @@ exports[`token analysis > "hi @ :name !" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -2184,7 +2184,7 @@ exports[`token analysis > "hi @ :name !" tokens 1`] = `
         "offset": 12,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -2242,7 +2242,7 @@ exports[`token analysis > "hi @. {name} !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -2258,7 +2258,7 @@ exports[`token analysis > "hi @. {name} !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
@@ -2306,7 +2306,7 @@ exports[`token analysis > "hi @. {name} !" tokens 1`] = `
         "offset": 7,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -2354,7 +2354,7 @@ exports[`token analysis > "hi @. {name} !" tokens 1`] = `
         "offset": 14,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -2412,7 +2412,7 @@ exports[`token analysis > "hi @.\\n{name} !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -2428,7 +2428,7 @@ exports[`token analysis > "hi @.\\n{name} !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
@@ -2477,7 +2477,7 @@ exports[`token analysis > "hi @.\\n{name} !" tokens 1`] = `
         "offset": 7,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -2525,7 +2525,7 @@ exports[`token analysis > "hi @.\\n{name} !" tokens 1`] = `
         "offset": 14,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -2583,7 +2583,7 @@ exports[`token analysis > "hi @.upper {name} !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -2599,7 +2599,7 @@ exports[`token analysis > "hi @.upper {name} !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
@@ -2615,7 +2615,7 @@ exports[`token analysis > "hi @.upper {name} !" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 12,
+    "type": 11,
     "value": "upper",
   },
   {
@@ -2663,7 +2663,7 @@ exports[`token analysis > "hi @.upper {name} !" tokens 1`] = `
         "offset": 12,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -2711,7 +2711,7 @@ exports[`token analysis > "hi @.upper {name} !" tokens 1`] = `
         "offset": 19,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -2747,7 +2747,7 @@ exports[`token analysis > "hi @.upper:name !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -2763,7 +2763,7 @@ exports[`token analysis > "hi @.upper:name !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
@@ -2779,7 +2779,7 @@ exports[`token analysis > "hi @.upper:name !" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 12,
+    "type": 11,
     "value": "upper",
   },
   {
@@ -2795,7 +2795,7 @@ exports[`token analysis > "hi @.upper:name !" tokens 1`] = `
         "offset": 10,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -2811,7 +2811,7 @@ exports[`token analysis > "hi @.upper:name !" tokens 1`] = `
         "offset": 11,
       },
     },
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -2843,7 +2843,7 @@ exports[`token analysis > "hi @.upper:name !" tokens 1`] = `
         "offset": 17,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -2901,7 +2901,7 @@ exports[`token analysis > "hi @.upper\\n{name} !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -2917,7 +2917,7 @@ exports[`token analysis > "hi @.upper\\n{name} !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
@@ -2933,7 +2933,7 @@ exports[`token analysis > "hi @.upper\\n{name} !" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 12,
+    "type": 11,
     "value": "upper",
   },
   {
@@ -2982,7 +2982,7 @@ exports[`token analysis > "hi @.upper\\n{name} !" tokens 1`] = `
         "offset": 12,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -3030,7 +3030,7 @@ exports[`token analysis > "hi @.upper\\n{name} !" tokens 1`] = `
         "offset": 19,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -3088,7 +3088,7 @@ exports[`token analysis > "hi @: {'name'} !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -3104,7 +3104,7 @@ exports[`token analysis > "hi @: {'name'} !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -3152,7 +3152,7 @@ exports[`token analysis > "hi @: {'name'} !" tokens 1`] = `
         "offset": 7,
       },
     },
-    "type": 7,
+    "type": 6,
     "value": "name",
   },
   {
@@ -3200,7 +3200,7 @@ exports[`token analysis > "hi @: {'name'} !" tokens 1`] = `
         "offset": 16,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -3258,7 +3258,7 @@ exports[`token analysis > "hi @:\\nname !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -3274,7 +3274,7 @@ exports[`token analysis > "hi @:\\nname !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -3290,7 +3290,7 @@ exports[`token analysis > "hi @:\\nname !" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -3322,7 +3322,7 @@ exports[`token analysis > "hi @:\\nname !" tokens 1`] = `
         "offset": 12,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -3358,7 +3358,7 @@ exports[`token analysis > "hi @:{ 'name' } !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -3374,7 +3374,7 @@ exports[`token analysis > "hi @:{ 'name' } !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -3406,7 +3406,7 @@ exports[`token analysis > "hi @:{ 'name' } !" tokens 1`] = `
         "offset": 7,
       },
     },
-    "type": 7,
+    "type": 6,
     "value": "name",
   },
   {
@@ -3454,7 +3454,7 @@ exports[`token analysis > "hi @:{ 'name' } !" tokens 1`] = `
         "offset": 17,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -3512,7 +3512,7 @@ exports[`token analysis > "hi @:{ {name} } !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -3528,7 +3528,7 @@ exports[`token analysis > "hi @:{ {name} } !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -3576,7 +3576,7 @@ exports[`token analysis > "hi @:{ {name} } !" tokens 1`] = `
         "offset": 8,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -3640,7 +3640,7 @@ exports[`token analysis > "hi @:{ {name} } !" tokens 1`] = `
         "offset": 17,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -3676,7 +3676,7 @@ exports[`token analysis > "hi @:{ name } !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -3692,7 +3692,7 @@ exports[`token analysis > "hi @:{ name } !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -3724,7 +3724,7 @@ exports[`token analysis > "hi @:{ name } !" tokens 1`] = `
         "offset": 7,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -3772,7 +3772,7 @@ exports[`token analysis > "hi @:{ name } !" tokens 1`] = `
         "offset": 15,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -3808,7 +3808,7 @@ exports[`token analysis > "hi @:{'hello world'} !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -3824,7 +3824,7 @@ exports[`token analysis > "hi @:{'hello world'} !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -3856,7 +3856,7 @@ exports[`token analysis > "hi @:{'hello world'} !" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 7,
+    "type": 6,
     "value": "hello world",
   },
   {
@@ -3904,7 +3904,7 @@ exports[`token analysis > "hi @:{'hello world'} !" tokens 1`] = `
         "offset": 22,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -3940,7 +3940,7 @@ exports[`token analysis > "hi @:{name} @:{0}!" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -3956,7 +3956,7 @@ exports[`token analysis > "hi @:{name} @:{0}!" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -3988,7 +3988,7 @@ exports[`token analysis > "hi @:{name} @:{0}!" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -4036,7 +4036,7 @@ exports[`token analysis > "hi @:{name} @:{0}!" tokens 1`] = `
         "offset": 12,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -4052,7 +4052,7 @@ exports[`token analysis > "hi @:{name} @:{0}!" tokens 1`] = `
         "offset": 13,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -4084,7 +4084,7 @@ exports[`token analysis > "hi @:{name} @:{0}!" tokens 1`] = `
         "offset": 15,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -4132,7 +4132,7 @@ exports[`token analysis > "hi @:{name} @:{0}!" tokens 1`] = `
         "offset": 18,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -4168,7 +4168,7 @@ exports[`token analysis > "hi @:{name}\\n !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -4184,7 +4184,7 @@ exports[`token analysis > "hi @:{name}\\n !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -4216,7 +4216,7 @@ exports[`token analysis > "hi @:{name}\\n !" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -4265,7 +4265,7 @@ exports[`token analysis > "hi @:{name}\\n !" tokens 1`] = `
         "offset": 14,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -4301,7 +4301,7 @@ exports[`token analysis > "hi @:name !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -4317,7 +4317,7 @@ exports[`token analysis > "hi @:name !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -4333,7 +4333,7 @@ exports[`token analysis > "hi @:name !" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -4365,7 +4365,7 @@ exports[`token analysis > "hi @:name !" tokens 1`] = `
         "offset": 11,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -4401,7 +4401,7 @@ exports[`token analysis > "hi @:名前" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -4417,7 +4417,7 @@ exports[`token analysis > "hi @:名前" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -4433,7 +4433,7 @@ exports[`token analysis > "hi @:名前" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 11,
+    "type": 10,
     "value": "名前",
   },
   {
@@ -4449,7 +4449,7 @@ exports[`token analysis > "hi @:名前" tokens 1`] = `
         "offset": 7,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -4558,7 +4558,7 @@ exports[`token analysis > "hi @\\n. upper\\n:  {'name'}\\n !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -4574,7 +4574,7 @@ exports[`token analysis > "hi @\\n. upper\\n:  {'name'}\\n !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
@@ -4590,7 +4590,7 @@ exports[`token analysis > "hi @\\n. upper\\n:  {'name'}\\n !" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 12,
+    "type": 11,
     "value": "upper",
   },
   {
@@ -4606,7 +4606,7 @@ exports[`token analysis > "hi @\\n. upper\\n:  {'name'}\\n !" tokens 1`] = `
         "offset": 12,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -4654,7 +4654,7 @@ exports[`token analysis > "hi @\\n. upper\\n:  {'name'}\\n !" tokens 1`] = `
         "offset": 17,
       },
     },
-    "type": 7,
+    "type": 6,
     "value": "name",
   },
   {
@@ -4703,7 +4703,7 @@ exports[`token analysis > "hi @\\n. upper\\n:  {'name'}\\n !" tokens 1`] = `
         "offset": 27,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -4761,7 +4761,7 @@ exports[`token analysis > "hi @\\n:name !" tokens 1`] = `
         "offset": 3,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -4777,7 +4777,7 @@ exports[`token analysis > "hi @\\n:name !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -4793,7 +4793,7 @@ exports[`token analysis > "hi @\\n:name !" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -4825,7 +4825,7 @@ exports[`token analysis > "hi @\\n:name !" tokens 1`] = `
         "offset": 12,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -4947,7 +4947,7 @@ exports[`token analysis > "hi {  | hello {name} !" tokens 1`] = `
         "offset": 15,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -4995,7 +4995,7 @@ exports[`token analysis > "hi {  | hello {name} !" tokens 1`] = `
         "offset": 22,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -5101,7 +5101,7 @@ exports[`token analysis > "hi {  } !" tokens 1`] = `
         "offset": 9,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -5153,7 +5153,7 @@ exports[`token analysis > "hi {  -1 } !" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "-1",
   },
   {
@@ -5201,7 +5201,7 @@ exports[`token analysis > "hi {  -1 } !" tokens 1`] = `
         "offset": 12,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -5275,7 +5275,7 @@ exports[`token analysis > "hi {  0 !" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -5307,7 +5307,7 @@ exports[`token analysis > "hi {  0 !" tokens 1`] = `
         "offset": 9,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -5381,7 +5381,7 @@ exports[`token analysis > "hi {  name !" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -5413,7 +5413,7 @@ exports[`token analysis > "hi {  name !" tokens 1`] = `
         "offset": 12,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -5465,7 +5465,7 @@ exports[`token analysis > "hi {  name } !" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -5513,7 +5513,7 @@ exports[`token analysis > "hi {  name } !" tokens 1`] = `
         "offset": 14,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -5587,7 +5587,7 @@ exports[`token analysis > "hi { '\\\\uw' }" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 7,
+    "type": 6,
     "value": "\\uw",
   },
   {
@@ -5619,7 +5619,7 @@ exports[`token analysis > "hi { '\\\\uw' }" tokens 1`] = `
         "offset": 12,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -5693,7 +5693,7 @@ exports[`token analysis > "hi { '\\\\x41' }" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 7,
+    "type": 6,
     "value": "x41",
   },
   {
@@ -5725,7 +5725,7 @@ exports[`token analysis > "hi { '\\\\x41' }" tokens 1`] = `
         "offset": 13,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -5799,7 +5799,7 @@ exports[`token analysis > "hi { 'foo }" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 7,
+    "type": 6,
     "value": "foo }",
   },
   {
@@ -5815,7 +5815,7 @@ exports[`token analysis > "hi { 'foo }" tokens 1`] = `
         "offset": 11,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -5889,7 +5889,7 @@ exports[`token analysis > "hi { 'foo" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 7,
+    "type": 6,
     "value": "foo",
   },
   {
@@ -5905,7 +5905,7 @@ exports[`token analysis > "hi { 'foo" tokens 1`] = `
         "offset": 9,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -5979,7 +5979,7 @@ exports[`token analysis > "hi { 'foo\\n' }" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 7,
+    "type": 6,
     "value": "foo",
   },
   {
@@ -6011,7 +6011,7 @@ exports[`token analysis > "hi { 'foo\\n' }" tokens 1`] = `
         "offset": 13,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -6085,7 +6085,7 @@ exports[`token analysis > "hi { @:name  | hello {name} !" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -6101,7 +6101,7 @@ exports[`token analysis > "hi { @:name  | hello {name} !" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -6117,7 +6117,7 @@ exports[`token analysis > "hi { @:name  | hello {name} !" tokens 1`] = `
         "offset": 7,
       },
     },
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -6181,7 +6181,7 @@ exports[`token analysis > "hi { @:name  | hello {name} !" tokens 1`] = `
         "offset": 22,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -6229,7 +6229,7 @@ exports[`token analysis > "hi { @:name  | hello {name} !" tokens 1`] = `
         "offset": 29,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -6303,7 +6303,7 @@ exports[`token analysis > "hi { @:name !" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -6319,7 +6319,7 @@ exports[`token analysis > "hi { @:name !" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -6335,7 +6335,7 @@ exports[`token analysis > "hi { @:name !" tokens 1`] = `
         "offset": 7,
       },
     },
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -6367,7 +6367,7 @@ exports[`token analysis > "hi { @:name !" tokens 1`] = `
         "offset": 13,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -6457,7 +6457,7 @@ exports[`token analysis > "hi { { 0 } } !" tokens 1`] = `
         "offset": 7,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -6521,7 +6521,7 @@ exports[`token analysis > "hi { { 0 } } !" tokens 1`] = `
         "offset": 14,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -6611,7 +6611,7 @@ exports[`token analysis > "hi { { name } } !" tokens 1`] = `
         "offset": 7,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -6675,7 +6675,7 @@ exports[`token analysis > "hi { { name } } !" tokens 1`] = `
         "offset": 17,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -6749,7 +6749,7 @@ exports[`token analysis > "hi { name !" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -6781,7 +6781,7 @@ exports[`token analysis > "hi { name !" tokens 1`] = `
         "offset": 11,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -6855,7 +6855,7 @@ exports[`token analysis > "hi {$} !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 13,
+    "type": 12,
     "value": "$",
   },
   {
@@ -6903,7 +6903,7 @@ exports[`token analysis > "hi {$} !" tokens 1`] = `
         "offset": 8,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -6955,7 +6955,7 @@ exports[`token analysis > "hi {'kazupon'} !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 7,
+    "type": 6,
     "value": "kazupon",
   },
   {
@@ -7003,7 +7003,7 @@ exports[`token analysis > "hi {'kazupon'} !" tokens 1`] = `
         "offset": 16,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -7077,7 +7077,7 @@ exports[`token analysis > "hi {@.lower:name !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -7093,7 +7093,7 @@ exports[`token analysis > "hi {@.lower:name !" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
@@ -7109,7 +7109,7 @@ exports[`token analysis > "hi {@.lower:name !" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 12,
+    "type": 11,
     "value": "lower",
   },
   {
@@ -7125,7 +7125,7 @@ exports[`token analysis > "hi {@.lower:name !" tokens 1`] = `
         "offset": 11,
       },
     },
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -7141,7 +7141,7 @@ exports[`token analysis > "hi {@.lower:name !" tokens 1`] = `
         "offset": 12,
       },
     },
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -7173,7 +7173,7 @@ exports[`token analysis > "hi {@.lower:name !" tokens 1`] = `
         "offset": 18,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -7225,7 +7225,7 @@ exports[`token analysis > "hi {\\nname\\n} !" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -7273,7 +7273,7 @@ exports[`token analysis > "hi {\\nname\\n} !" tokens 1`] = `
         "offset": 13,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -7380,7 +7380,7 @@ exports[`token analysis > "hi {{ !" tokens 1`] = `
         "offset": 6,
       },
     },
-    "type": 13,
+    "type": 12,
     "value": "!",
   },
   {
@@ -7396,7 +7396,7 @@ exports[`token analysis > "hi {{ !" tokens 1`] = `
         "offset": 7,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -7551,7 +7551,7 @@ exports[`token analysis > "hi {{}} !" tokens 1`] = `
         "offset": 9,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -7641,7 +7641,7 @@ exports[`token analysis > "hi {{0}} !" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -7705,7 +7705,7 @@ exports[`token analysis > "hi {{0}} !" tokens 1`] = `
         "offset": 10,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -7795,7 +7795,7 @@ exports[`token analysis > "hi {{name}} !" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -7859,7 +7859,7 @@ exports[`token analysis > "hi {{name}} !" tokens 1`] = `
         "offset": 13,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -7965,7 +7965,7 @@ exports[`token analysis > "hi {} !" tokens 1`] = `
         "offset": 7,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -8039,7 +8039,7 @@ exports[`token analysis > "hi {-} !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 13,
+    "type": 12,
     "value": "-",
   },
   {
@@ -8087,7 +8087,7 @@ exports[`token analysis > "hi {-} !" tokens 1`] = `
         "offset": 8,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -8161,7 +8161,7 @@ exports[`token analysis > "hi {0 !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -8193,7 +8193,7 @@ exports[`token analysis > "hi {0 !" tokens 1`] = `
         "offset": 7,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -8267,7 +8267,7 @@ exports[`token analysis > "hi {0" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -8283,7 +8283,7 @@ exports[`token analysis > "hi {0" tokens 1`] = `
         "offset": 5,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -8335,7 +8335,7 @@ exports[`token analysis > "hi {0} !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -8383,7 +8383,7 @@ exports[`token analysis > "hi {0} !" tokens 1`] = `
         "offset": 8,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -8457,7 +8457,7 @@ exports[`token analysis > "hi {name !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -8489,7 +8489,7 @@ exports[`token analysis > "hi {name !" tokens 1`] = `
         "offset": 10,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -8563,7 +8563,7 @@ exports[`token analysis > "hi {name" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -8579,7 +8579,7 @@ exports[`token analysis > "hi {name" tokens 1`] = `
         "offset": 8,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -8631,7 +8631,7 @@ exports[`token analysis > "hi {name$} !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name$",
   },
   {
@@ -8679,7 +8679,7 @@ exports[`token analysis > "hi {name$} !" tokens 1`] = `
         "offset": 12,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -8731,7 +8731,7 @@ exports[`token analysis > "hi {name} !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -8779,7 +8779,7 @@ exports[`token analysis > "hi {name} !" tokens 1`] = `
         "offset": 11,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -8831,7 +8831,7 @@ exports[`token analysis > "hi {snake_case} !" tokens 1`] = `
         "offset": 4,
       },
     },
-    "type": 5,
+    "type": 4,
     "value": "snake_case",
   },
   {
@@ -8879,7 +8879,7 @@ exports[`token analysis > "hi {snake_case} !" tokens 1`] = `
         "offset": 17,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -8915,7 +8915,7 @@ exports[`token analysis > "hi, :-) !" tokens 1`] = `
         "offset": 9,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9005,7 +9005,7 @@ exports[`token analysis > "hi, :-} !" tokens 1`] = `
         "offset": 9,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9041,7 +9041,7 @@ exports[`token analysis > "hypen-nate" tokens 1`] = `
         "offset": 10,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9077,7 +9077,7 @@ exports[`token analysis > "name = foo" tokens 1`] = `
         "offset": 10,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9177,7 +9177,7 @@ exports[`token analysis > "no apples | one apple  |  too much apples " tokens 1`
         "offset": 42,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9277,7 +9277,7 @@ exports[`token analysis > "no apples |\\n one apple  |\\n  too much apples  " to
         "offset": 45,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9313,7 +9313,7 @@ exports[`token analysis > "こんにちは、世界" tokens 1`] = `
         "offset": 8,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9349,7 +9349,7 @@ exports[`token analysis > "😺" tokens 1`] = `
         "offset": 2,
       },
     },
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9369,7 +9369,7 @@ exports[`tokenize options: location disable > " | | |" tokens 1`] = `
     "value": "|",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9393,7 +9393,7 @@ exports[`tokenize options: location disable > " foo | | bar" tokens 1`] = `
     "value": "bar",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9405,7 +9405,7 @@ exports[`tokenize options: location disable > " hello world " tokens 1`] = `
     "value": " hello world ",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9413,7 +9413,7 @@ exports[`tokenize options: location disable > " hello world " tokens 1`] = `
 exports[`tokenize options: location disable > "" tokens 1`] = `
 [
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9425,7 +9425,7 @@ exports[`tokenize options: location disable > "'single-quote'" tokens 1`] = `
     "value": "'single-quote'",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9437,7 +9437,7 @@ exports[`tokenize options: location disable > "..." tokens 1`] = `
     "value": "...",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9465,19 +9465,19 @@ exports[`tokenize options: location disable > "@.lower: {'no apples'} | {1 apple
 exports[`tokenize options: location disable > "@.lower: {'no apples'} | {1 apple | @:{count　apples" tokens 1`] = `
 [
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
-    "type": 12,
+    "type": 11,
     "value": "lower",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -9489,7 +9489,7 @@ exports[`tokenize options: location disable > "@.lower: {'no apples'} | {1 apple
     "value": "{",
   },
   {
-    "type": 7,
+    "type": 6,
     "value": "no apples",
   },
   {
@@ -9505,7 +9505,7 @@ exports[`tokenize options: location disable > "@.lower: {'no apples'} | {1 apple
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "1",
   },
   {
@@ -9517,11 +9517,11 @@ exports[`tokenize options: location disable > "@.lower: {'no apples'} | {1 apple
     "value": "|",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -9529,7 +9529,7 @@ exports[`tokenize options: location disable > "@.lower: {'no apples'} | {1 apple
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "count",
   },
   {
@@ -9537,7 +9537,7 @@ exports[`tokenize options: location disable > "@.lower: {'no apples'} | {1 apple
     "value": "　apples",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9545,19 +9545,19 @@ exports[`tokenize options: location disable > "@.lower: {'no apples'} | {1 apple
 exports[`tokenize options: location disable > "@.lower:{'no apples'} | {1} apple | {count}　apples" tokens 1`] = `
 [
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
-    "type": 12,
+    "type": 11,
     "value": "lower",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -9565,7 +9565,7 @@ exports[`tokenize options: location disable > "@.lower:{'no apples'} | {1} apple
     "value": "{",
   },
   {
-    "type": 7,
+    "type": 6,
     "value": "no apples",
   },
   {
@@ -9581,7 +9581,7 @@ exports[`tokenize options: location disable > "@.lower:{'no apples'} | {1} apple
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "1",
   },
   {
@@ -9601,7 +9601,7 @@ exports[`tokenize options: location disable > "@.lower:{'no apples'} | {1} apple
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "count",
   },
   {
@@ -9613,7 +9613,7 @@ exports[`tokenize options: location disable > "@.lower:{'no apples'} | {1} apple
     "value": "　apples",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9625,7 +9625,7 @@ exports[`tokenize options: location disable > "\\"double-qoute\\"" tokens 1`] =
     "value": ""double-qoute"",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9637,7 +9637,7 @@ exports[`tokenize options: location disable > "{0} {1}　{2}" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -9653,7 +9653,7 @@ exports[`tokenize options: location disable > "{0} {1}　{2}" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "1",
   },
   {
@@ -9669,7 +9669,7 @@ exports[`tokenize options: location disable > "{0} {1}　{2}" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "2",
   },
   {
@@ -9677,7 +9677,7 @@ exports[`tokenize options: location disable > "{0} {1}　{2}" tokens 1`] = `
     "value": "}",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9689,7 +9689,7 @@ exports[`tokenize options: location disable > "{0}\\n{1}\\r\\n{2}" tokens 1`] =
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -9706,7 +9706,7 @@ exports[`tokenize options: location disable > "{0}\\n{1}\\r\\n{2}" tokens 1`] =
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "1",
   },
   {
@@ -9723,7 +9723,7 @@ exports[`tokenize options: location disable > "{0}\\n{1}\\r\\n{2}" tokens 1`] =
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "2",
   },
   {
@@ -9731,7 +9731,7 @@ exports[`tokenize options: location disable > "{0}\\n{1}\\r\\n{2}" tokens 1`] =
     "value": "}",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9743,7 +9743,7 @@ exports[`tokenize options: location disable > "{first} {middle}　{last}" tokens
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "first",
   },
   {
@@ -9759,7 +9759,7 @@ exports[`tokenize options: location disable > "{first} {middle}　{last}" tokens
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "middle",
   },
   {
@@ -9775,7 +9775,7 @@ exports[`tokenize options: location disable > "{first} {middle}　{last}" tokens
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "last",
   },
   {
@@ -9783,7 +9783,7 @@ exports[`tokenize options: location disable > "{first} {middle}　{last}" tokens
     "value": "}",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9795,7 +9795,7 @@ exports[`tokenize options: location disable > "{first}\\n{middle}\\r\\n{last}" t
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "first",
   },
   {
@@ -9812,7 +9812,7 @@ exports[`tokenize options: location disable > "{first}\\n{middle}\\r\\n{last}" t
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "middle",
   },
   {
@@ -9829,7 +9829,7 @@ exports[`tokenize options: location disable > "{first}\\n{middle}\\r\\n{last}" t
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "last",
   },
   {
@@ -9837,7 +9837,7 @@ exports[`tokenize options: location disable > "{first}\\n{middle}\\r\\n{last}" t
     "value": "}",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9849,7 +9849,7 @@ exports[`tokenize options: location disable > "1 + 1" tokens 1`] = `
     "value": "1 + 1",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9871,7 +9871,7 @@ exports[`tokenize options: location disable > "foo@bar.com" tokens 1`] = `
     "value": "foo",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
@@ -9879,7 +9879,7 @@ exports[`tokenize options: location disable > "foo@bar.com" tokens 1`] = `
     "value": "bar.com",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9891,7 +9891,7 @@ exports[`tokenize options: location disable > "hello world" tokens 1`] = `
     "value": "hello world",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9903,7 +9903,7 @@ exports[`tokenize options: location disable > "hello:" tokens 1`] = `
     "value": "hello:",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9915,7 +9915,7 @@ exports[`tokenize options: location disable > "hello\\\\nworld" tokens 1`] = `
     "value": "hello\\nworld",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9928,7 +9928,7 @@ exports[`tokenize options: location disable > "hello\\nworld" tokens 1`] = `
 world",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9940,7 +9940,7 @@ exports[`tokenize options: location disable > "hi %name" tokens 1`] = `
     "value": "hi %name",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -9962,15 +9962,15 @@ exports[`tokenize options: location disable > "hi @ :name !" tokens 1`] = `
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -9978,7 +9978,7 @@ exports[`tokenize options: location disable > "hi @ :name !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10000,11 +10000,11 @@ exports[`tokenize options: location disable > "hi @. {name} !" tokens 1`] = `
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
@@ -10016,7 +10016,7 @@ exports[`tokenize options: location disable > "hi @. {name} !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -10028,7 +10028,7 @@ exports[`tokenize options: location disable > "hi @. {name} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10050,11 +10050,11 @@ exports[`tokenize options: location disable > "hi @.\\n{name} !" tokens 1`] = `
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
@@ -10067,7 +10067,7 @@ exports[`tokenize options: location disable > "hi @.\\n{name} !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -10079,7 +10079,7 @@ exports[`tokenize options: location disable > "hi @.\\n{name} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10101,15 +10101,15 @@ exports[`tokenize options: location disable > "hi @.upper {name} !" tokens 1`] =
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
-    "type": 12,
+    "type": 11,
     "value": "upper",
   },
   {
@@ -10121,7 +10121,7 @@ exports[`tokenize options: location disable > "hi @.upper {name} !" tokens 1`] =
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -10133,7 +10133,7 @@ exports[`tokenize options: location disable > "hi @.upper {name} !" tokens 1`] =
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10145,23 +10145,23 @@ exports[`tokenize options: location disable > "hi @.upper:name !" tokens 1`] = `
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
-    "type": 12,
+    "type": 11,
     "value": "upper",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -10169,7 +10169,7 @@ exports[`tokenize options: location disable > "hi @.upper:name !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10191,15 +10191,15 @@ exports[`tokenize options: location disable > "hi @.upper\\n{name} !" tokens 1`]
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
-    "type": 12,
+    "type": 11,
     "value": "upper",
   },
   {
@@ -10212,7 +10212,7 @@ exports[`tokenize options: location disable > "hi @.upper\\n{name} !" tokens 1`]
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -10224,7 +10224,7 @@ exports[`tokenize options: location disable > "hi @.upper\\n{name} !" tokens 1`]
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10246,11 +10246,11 @@ exports[`tokenize options: location disable > "hi @: {'name'} !" tokens 1`] = `
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -10262,7 +10262,7 @@ exports[`tokenize options: location disable > "hi @: {'name'} !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 7,
+    "type": 6,
     "value": "name",
   },
   {
@@ -10274,7 +10274,7 @@ exports[`tokenize options: location disable > "hi @: {'name'} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10296,15 +10296,15 @@ exports[`tokenize options: location disable > "hi @:\\nname !" tokens 1`] = `
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -10312,7 +10312,7 @@ exports[`tokenize options: location disable > "hi @:\\nname !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10324,11 +10324,11 @@ exports[`tokenize options: location disable > "hi @:{ 'name' } !" tokens 1`] = `
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -10336,7 +10336,7 @@ exports[`tokenize options: location disable > "hi @:{ 'name' } !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 7,
+    "type": 6,
     "value": "name",
   },
   {
@@ -10348,7 +10348,7 @@ exports[`tokenize options: location disable > "hi @:{ 'name' } !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10370,11 +10370,11 @@ exports[`tokenize options: location disable > "hi @:{ {name} } !" tokens 1`] = `
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -10386,7 +10386,7 @@ exports[`tokenize options: location disable > "hi @:{ {name} } !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -10402,7 +10402,7 @@ exports[`tokenize options: location disable > "hi @:{ {name} } !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10414,11 +10414,11 @@ exports[`tokenize options: location disable > "hi @:{ name } !" tokens 1`] = `
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -10426,7 +10426,7 @@ exports[`tokenize options: location disable > "hi @:{ name } !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -10438,7 +10438,7 @@ exports[`tokenize options: location disable > "hi @:{ name } !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10450,11 +10450,11 @@ exports[`tokenize options: location disable > "hi @:{'hello world'} !" tokens 1`
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -10462,7 +10462,7 @@ exports[`tokenize options: location disable > "hi @:{'hello world'} !" tokens 1`
     "value": "{",
   },
   {
-    "type": 7,
+    "type": 6,
     "value": "hello world",
   },
   {
@@ -10474,7 +10474,7 @@ exports[`tokenize options: location disable > "hi @:{'hello world'} !" tokens 1`
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10486,11 +10486,11 @@ exports[`tokenize options: location disable > "hi @:{name} @:{0}!" tokens 1`] =
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -10498,7 +10498,7 @@ exports[`tokenize options: location disable > "hi @:{name} @:{0}!" tokens 1`] =
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -10510,11 +10510,11 @@ exports[`tokenize options: location disable > "hi @:{name} @:{0}!" tokens 1`] =
     "value": " ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -10522,7 +10522,7 @@ exports[`tokenize options: location disable > "hi @:{name} @:{0}!" tokens 1`] =
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -10534,7 +10534,7 @@ exports[`tokenize options: location disable > "hi @:{name} @:{0}!" tokens 1`] =
     "value": "!",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10546,11 +10546,11 @@ exports[`tokenize options: location disable > "hi @:{name}\\n !" tokens 1`] = `
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -10558,7 +10558,7 @@ exports[`tokenize options: location disable > "hi @:{name}\\n !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -10571,7 +10571,7 @@ exports[`tokenize options: location disable > "hi @:{name}\\n !" tokens 1`] = `
  !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10583,15 +10583,15 @@ exports[`tokenize options: location disable > "hi @:name !" tokens 1`] = `
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -10599,7 +10599,7 @@ exports[`tokenize options: location disable > "hi @:name !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10611,19 +10611,19 @@ exports[`tokenize options: location disable > "hi @:名前" tokens 1`] = `
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
-    "type": 11,
+    "type": 10,
     "value": "名前",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10660,19 +10660,19 @@ exports[`tokenize options: location disable > "hi @\\n. upper\\n:  {'name'}\\n !
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
-    "type": 12,
+    "type": 11,
     "value": "upper",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
@@ -10684,7 +10684,7 @@ exports[`tokenize options: location disable > "hi @\\n. upper\\n:  {'name'}\\n !
     "value": "{",
   },
   {
-    "type": 7,
+    "type": 6,
     "value": "name",
   },
   {
@@ -10697,7 +10697,7 @@ exports[`tokenize options: location disable > "hi @\\n. upper\\n:  {'name'}\\n !
  !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10719,15 +10719,15 @@ exports[`tokenize options: location disable > "hi @\\n:name !" tokens 1`] = `
     "value": "hi ",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -10735,7 +10735,7 @@ exports[`tokenize options: location disable > "hi @\\n:name !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10773,7 +10773,7 @@ exports[`tokenize options: location disable > "hi {  | hello {name} !" tokens 1`
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -10785,7 +10785,7 @@ exports[`tokenize options: location disable > "hi {  | hello {name} !" tokens 1`
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10819,7 +10819,7 @@ exports[`tokenize options: location disable > "hi {  } !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10835,7 +10835,7 @@ exports[`tokenize options: location disable > "hi {  -1 } !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "-1",
   },
   {
@@ -10847,7 +10847,7 @@ exports[`tokenize options: location disable > "hi {  -1 } !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10873,7 +10873,7 @@ exports[`tokenize options: location disable > "hi {  0 !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -10881,7 +10881,7 @@ exports[`tokenize options: location disable > "hi {  0 !" tokens 1`] = `
     "value": "!",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10907,7 +10907,7 @@ exports[`tokenize options: location disable > "hi {  name !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -10915,7 +10915,7 @@ exports[`tokenize options: location disable > "hi {  name !" tokens 1`] = `
     "value": "!",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10931,7 +10931,7 @@ exports[`tokenize options: location disable > "hi {  name } !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -10943,7 +10943,7 @@ exports[`tokenize options: location disable > "hi {  name } !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -10969,7 +10969,7 @@ exports[`tokenize options: location disable > "hi { '\\\\uw' }" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 7,
+    "type": 6,
     "value": "\\uw",
   },
   {
@@ -10977,7 +10977,7 @@ exports[`tokenize options: location disable > "hi { '\\\\uw' }" tokens 1`] = `
     "value": "}",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11003,7 +11003,7 @@ exports[`tokenize options: location disable > "hi { '\\\\x41' }" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 7,
+    "type": 6,
     "value": "x41",
   },
   {
@@ -11011,7 +11011,7 @@ exports[`tokenize options: location disable > "hi { '\\\\x41' }" tokens 1`] = `
     "value": "}",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11037,11 +11037,11 @@ exports[`tokenize options: location disable > "hi { 'foo }" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 7,
+    "type": 6,
     "value": "foo }",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11067,11 +11067,11 @@ exports[`tokenize options: location disable > "hi { 'foo" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 7,
+    "type": 6,
     "value": "foo",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11097,7 +11097,7 @@ exports[`tokenize options: location disable > "hi { 'foo\\n' }" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 7,
+    "type": 6,
     "value": "foo",
   },
   {
@@ -11105,7 +11105,7 @@ exports[`tokenize options: location disable > "hi { 'foo\\n' }" tokens 1`] = `
     "value": "}",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11131,15 +11131,15 @@ exports[`tokenize options: location disable > "hi { @:name  | hello {name} !" to
     "value": "{",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -11155,7 +11155,7 @@ exports[`tokenize options: location disable > "hi { @:name  | hello {name} !" to
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -11167,7 +11167,7 @@ exports[`tokenize options: location disable > "hi { @:name  | hello {name} !" to
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11193,15 +11193,15 @@ exports[`tokenize options: location disable > "hi { @:name !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -11209,7 +11209,7 @@ exports[`tokenize options: location disable > "hi { @:name !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11239,7 +11239,7 @@ exports[`tokenize options: location disable > "hi { { 0 } } !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -11255,7 +11255,7 @@ exports[`tokenize options: location disable > "hi { { 0 } } !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11285,7 +11285,7 @@ exports[`tokenize options: location disable > "hi { { name } } !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -11301,7 +11301,7 @@ exports[`tokenize options: location disable > "hi { { name } } !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11327,7 +11327,7 @@ exports[`tokenize options: location disable > "hi { name !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -11335,7 +11335,7 @@ exports[`tokenize options: location disable > "hi { name !" tokens 1`] = `
     "value": "!",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11361,7 +11361,7 @@ exports[`tokenize options: location disable > "hi {$} !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 13,
+    "type": 12,
     "value": "$",
   },
   {
@@ -11373,7 +11373,7 @@ exports[`tokenize options: location disable > "hi {$} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11389,7 +11389,7 @@ exports[`tokenize options: location disable > "hi {'kazupon'} !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 7,
+    "type": 6,
     "value": "kazupon",
   },
   {
@@ -11401,7 +11401,7 @@ exports[`tokenize options: location disable > "hi {'kazupon'} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11427,23 +11427,23 @@ exports[`tokenize options: location disable > "hi {@.lower:name !" tokens 1`] =
     "value": "{",
   },
   {
-    "type": 8,
+    "type": 7,
     "value": "@",
   },
   {
-    "type": 9,
+    "type": 8,
     "value": ".",
   },
   {
-    "type": 12,
+    "type": 11,
     "value": "lower",
   },
   {
-    "type": 10,
+    "type": 9,
     "value": ":",
   },
   {
-    "type": 11,
+    "type": 10,
     "value": "name",
   },
   {
@@ -11451,7 +11451,7 @@ exports[`tokenize options: location disable > "hi {@.lower:name !" tokens 1`] =
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11467,7 +11467,7 @@ exports[`tokenize options: location disable > "hi {\\nname\\n} !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -11479,7 +11479,7 @@ exports[`tokenize options: location disable > "hi {\\nname\\n} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11514,11 +11514,11 @@ exports[`tokenize options: location disable > "hi {{ !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 13,
+    "type": 12,
     "value": "!",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11565,7 +11565,7 @@ exports[`tokenize options: location disable > "hi {{}} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11595,7 +11595,7 @@ exports[`tokenize options: location disable > "hi {{0}} !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -11611,7 +11611,7 @@ exports[`tokenize options: location disable > "hi {{0}} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11641,7 +11641,7 @@ exports[`tokenize options: location disable > "hi {{name}} !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -11657,7 +11657,7 @@ exports[`tokenize options: location disable > "hi {{name}} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11691,7 +11691,7 @@ exports[`tokenize options: location disable > "hi {} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11717,7 +11717,7 @@ exports[`tokenize options: location disable > "hi {-} !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 13,
+    "type": 12,
     "value": "-",
   },
   {
@@ -11729,7 +11729,7 @@ exports[`tokenize options: location disable > "hi {-} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11755,7 +11755,7 @@ exports[`tokenize options: location disable > "hi {0 !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -11763,7 +11763,7 @@ exports[`tokenize options: location disable > "hi {0 !" tokens 1`] = `
     "value": "!",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11789,11 +11789,11 @@ exports[`tokenize options: location disable > "hi {0" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11809,7 +11809,7 @@ exports[`tokenize options: location disable > "hi {0} !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 6,
+    "type": 5,
     "value": "0",
   },
   {
@@ -11821,7 +11821,7 @@ exports[`tokenize options: location disable > "hi {0} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11847,7 +11847,7 @@ exports[`tokenize options: location disable > "hi {name !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -11855,7 +11855,7 @@ exports[`tokenize options: location disable > "hi {name !" tokens 1`] = `
     "value": "!",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11881,11 +11881,11 @@ exports[`tokenize options: location disable > "hi {name" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11901,7 +11901,7 @@ exports[`tokenize options: location disable > "hi {name$} !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name$",
   },
   {
@@ -11913,7 +11913,7 @@ exports[`tokenize options: location disable > "hi {name$} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11929,7 +11929,7 @@ exports[`tokenize options: location disable > "hi {name} !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "name",
   },
   {
@@ -11941,7 +11941,7 @@ exports[`tokenize options: location disable > "hi {name} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11957,7 +11957,7 @@ exports[`tokenize options: location disable > "hi {snake_case} !" tokens 1`] = `
     "value": "{",
   },
   {
-    "type": 5,
+    "type": 4,
     "value": "snake_case",
   },
   {
@@ -11969,7 +11969,7 @@ exports[`tokenize options: location disable > "hi {snake_case} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -11981,7 +11981,7 @@ exports[`tokenize options: location disable > "hi, :-) !" tokens 1`] = `
     "value": "hi, :-) !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -12011,7 +12011,7 @@ exports[`tokenize options: location disable > "hi, :-} !" tokens 1`] = `
     "value": " !",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -12023,7 +12023,7 @@ exports[`tokenize options: location disable > "hypen-nate" tokens 1`] = `
     "value": "hypen-nate",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -12035,7 +12035,7 @@ exports[`tokenize options: location disable > "name = foo" tokens 1`] = `
     "value": "name = foo",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -12063,7 +12063,7 @@ exports[`tokenize options: location disable > "no apples | one apple  |  too muc
     "value": "too much apples ",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -12091,7 +12091,7 @@ exports[`tokenize options: location disable > "no apples |\\n one apple  |\\n  t
     "value": "too much apples  ",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -12103,7 +12103,7 @@ exports[`tokenize options: location disable > "こんにちは、世界" tokens
     "value": "こんにちは、世界",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
@@ -12115,7 +12115,7 @@ exports[`tokenize options: location disable > "😺" tokens 1`] = `
     "value": "😺",
   },
   {
-    "type": 14,
+    "type": 13,
   },
 ]
 `;
diff --git a/packages/message-compiler/test/compiler.test.ts b/packages/message-compiler/test/compiler.test.ts
index 44abc140..aaa26ff6 100644
--- a/packages/message-compiler/test/compiler.test.ts
+++ b/packages/message-compiler/test/compiler.test.ts
@@ -110,13 +110,6 @@ describe('compiler options', () => {
     })
     expect(ast).toMatchSnapshot('ast')
   })
-
-  test('warning', () => {
-    const onWarn = vi.fn()
-    const { ast } = compile(`%{msg} world`, { onWarn })
-    expect(ast).toMatchSnapshot('ast')
-    expect(onWarn.mock.calls[0][0].message).toBe(`Use modulo before '{msg}'.`)
-  })
 })
 
 describe('edge cases', () => {
diff --git a/packages/message-compiler/test/parser/__snapshots__/modulo.test.ts.snap b/packages/message-compiler/test/parser/__snapshots__/modulo.test.ts.snap
index 866afb0d..c8e79049 100644
--- a/packages/message-compiler/test/parser/__snapshots__/modulo.test.ts.snap
+++ b/packages/message-compiler/test/parser/__snapshots__/modulo.test.ts.snap
@@ -5,6 +5,24 @@ exports[`%{nickname} %{action} issue %{code} 1`] = `
   "body": {
     "end": 35,
     "items": [
+      {
+        "end": 1,
+        "loc": {
+          "end": {
+            "column": 2,
+            "line": 1,
+            "offset": 1,
+          },
+          "start": {
+            "column": 1,
+            "line": 1,
+            "offset": 0,
+          },
+        },
+        "start": 0,
+        "type": 3,
+        "value": "%",
+      },
       {
         "end": 11,
         "key": "nickname",
@@ -20,17 +38,16 @@ exports[`%{nickname} %{action} issue %{code} 1`] = `
             "offset": 1,
           },
         },
-        "modulo": true,
         "start": 1,
         "type": 4,
       },
       {
-        "end": 12,
+        "end": 13,
         "loc": {
           "end": {
-            "column": 13,
+            "column": 14,
             "line": 1,
-            "offset": 12,
+            "offset": 13,
           },
           "start": {
             "column": 12,
@@ -40,7 +57,7 @@ exports[`%{nickname} %{action} issue %{code} 1`] = `
         },
         "start": 11,
         "type": 3,
-        "value": " ",
+        "value": " %",
       },
       {
         "end": 21,
@@ -57,17 +74,16 @@ exports[`%{nickname} %{action} issue %{code} 1`] = `
             "offset": 13,
           },
         },
-        "modulo": true,
         "start": 13,
         "type": 4,
       },
       {
-        "end": 28,
+        "end": 29,
         "loc": {
           "end": {
-            "column": 29,
+            "column": 30,
             "line": 1,
-            "offset": 28,
+            "offset": 29,
           },
           "start": {
             "column": 22,
@@ -77,7 +93,7 @@ exports[`%{nickname} %{action} issue %{code} 1`] = `
         },
         "start": 21,
         "type": 3,
-        "value": " issue ",
+        "value": " issue %",
       },
       {
         "end": 35,
@@ -94,7 +110,6 @@ exports[`%{nickname} %{action} issue %{code} 1`] = `
             "offset": 29,
           },
         },
-        "modulo": true,
         "start": 29,
         "type": 4,
       },
@@ -402,12 +417,12 @@ exports[`hi %{name}! 1`] = `
     "end": 11,
     "items": [
       {
-        "end": 3,
+        "end": 4,
         "loc": {
           "end": {
-            "column": 4,
+            "column": 5,
             "line": 1,
-            "offset": 3,
+            "offset": 4,
           },
           "start": {
             "column": 1,
@@ -417,7 +432,7 @@ exports[`hi %{name}! 1`] = `
         },
         "start": 0,
         "type": 3,
-        "value": "hi ",
+        "value": "hi %",
       },
       {
         "end": 10,
@@ -434,7 +449,6 @@ exports[`hi %{name}! 1`] = `
             "offset": 4,
           },
         },
-        "modulo": true,
         "start": 4,
         "type": 4,
       },
diff --git a/packages/message-compiler/test/parser/modulo.test.ts b/packages/message-compiler/test/parser/modulo.test.ts
index 8522964b..352acc77 100644
--- a/packages/message-compiler/test/parser/modulo.test.ts
+++ b/packages/message-compiler/test/parser/modulo.test.ts
@@ -23,7 +23,7 @@ test('hi %{name}!', () => {
   expect(message.items).toMatchObject([
     {
       type: NodeTypes.Text,
-      value: 'hi '
+      value: 'hi %'
     },
     {
       type: NodeTypes.Named,
@@ -189,15 +189,19 @@ test(`%{nickname} %{action} issue %{code}`, () => {
   expect(ast.type).toEqual(NodeTypes.Resource)
   expect(ast.body.type).toEqual(NodeTypes.Message)
   const message = ast.body as MessageNode
-  expect(message.items).toHaveLength(5)
+  expect(message.items).toHaveLength(6)
   expect(message.items).toMatchObject([
+    {
+      type: NodeTypes.Text,
+      value: '%'
+    },
     {
       type: NodeTypes.Named,
       key: 'nickname'
     },
     {
       type: NodeTypes.Text,
-      value: ' '
+      value: ' %'
     },
     {
       type: NodeTypes.Named,
@@ -205,7 +209,7 @@ test(`%{nickname} %{action} issue %{code}`, () => {
     },
     {
       type: NodeTypes.Text,
-      value: ' issue '
+      value: ' issue %'
     },
     {
       type: NodeTypes.Named,
diff --git a/packages/message-compiler/test/tokenizer/__snapshots__/named.test.ts.snap b/packages/message-compiler/test/tokenizer/__snapshots__/named.test.ts.snap
deleted file mode 100644
index 5a483df3..00000000
--- a/packages/message-compiler/test/tokenizer/__snapshots__/named.test.ts.snap
+++ /dev/null
@@ -1,228 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`modulo cases > multiple >  %{action} issue %s %{code} ! 1`] = `
-{
-  "loc": {
-    "end": {
-      "column": 2,
-      "line": 1,
-      "offset": 1,
-    },
-    "start": {
-      "column": 1,
-      "line": 1,
-      "offset": 0,
-    },
-  },
-  "type": 0,
-  "value": " ",
-}
-`;
-
-exports[`modulo cases > multiple >  %{action} issue %s %{code} ! 2`] = `
-{
-  "loc": {
-    "end": {
-      "column": 3,
-      "line": 1,
-      "offset": 2,
-    },
-    "start": {
-      "column": 2,
-      "line": 1,
-      "offset": 1,
-    },
-  },
-  "type": 4,
-  "value": "%",
-}
-`;
-
-exports[`modulo cases > multiple >  %{action} issue %s %{code} ! 3`] = `
-{
-  "loc": {
-    "end": {
-      "column": 4,
-      "line": 1,
-      "offset": 3,
-    },
-    "start": {
-      "column": 3,
-      "line": 1,
-      "offset": 2,
-    },
-  },
-  "type": 2,
-  "value": "{",
-}
-`;
-
-exports[`modulo cases > multiple >  %{action} issue %s %{code} ! 4`] = `
-{
-  "loc": {
-    "end": {
-      "column": 10,
-      "line": 1,
-      "offset": 9,
-    },
-    "start": {
-      "column": 4,
-      "line": 1,
-      "offset": 3,
-    },
-  },
-  "type": 5,
-  "value": "action",
-}
-`;
-
-exports[`modulo cases > multiple >  %{action} issue %s %{code} ! 5`] = `
-{
-  "loc": {
-    "end": {
-      "column": 11,
-      "line": 1,
-      "offset": 10,
-    },
-    "start": {
-      "column": 10,
-      "line": 1,
-      "offset": 9,
-    },
-  },
-  "type": 3,
-  "value": "}",
-}
-`;
-
-exports[`modulo cases > multiple >  %{action} issue %s %{code} ! 6`] = `
-{
-  "loc": {
-    "end": {
-      "column": 21,
-      "line": 1,
-      "offset": 20,
-    },
-    "start": {
-      "column": 11,
-      "line": 1,
-      "offset": 10,
-    },
-  },
-  "type": 0,
-  "value": " issue %s ",
-}
-`;
-
-exports[`modulo cases > multiple >  %{action} issue %s %{code} ! 7`] = `
-{
-  "loc": {
-    "end": {
-      "column": 22,
-      "line": 1,
-      "offset": 21,
-    },
-    "start": {
-      "column": 21,
-      "line": 1,
-      "offset": 20,
-    },
-  },
-  "type": 4,
-  "value": "%",
-}
-`;
-
-exports[`modulo cases > multiple >  %{action} issue %s %{code} ! 8`] = `
-{
-  "loc": {
-    "end": {
-      "column": 23,
-      "line": 1,
-      "offset": 22,
-    },
-    "start": {
-      "column": 22,
-      "line": 1,
-      "offset": 21,
-    },
-  },
-  "type": 2,
-  "value": "{",
-}
-`;
-
-exports[`modulo cases > multiple >  %{action} issue %s %{code} ! 9`] = `
-{
-  "loc": {
-    "end": {
-      "column": 27,
-      "line": 1,
-      "offset": 26,
-    },
-    "start": {
-      "column": 23,
-      "line": 1,
-      "offset": 22,
-    },
-  },
-  "type": 5,
-  "value": "code",
-}
-`;
-
-exports[`modulo cases > multiple >  %{action} issue %s %{code} ! 10`] = `
-{
-  "loc": {
-    "end": {
-      "column": 28,
-      "line": 1,
-      "offset": 27,
-    },
-    "start": {
-      "column": 27,
-      "line": 1,
-      "offset": 26,
-    },
-  },
-  "type": 3,
-  "value": "}",
-}
-`;
-
-exports[`modulo cases > multiple >  %{action} issue %s %{code} ! 11`] = `
-{
-  "loc": {
-    "end": {
-      "column": 30,
-      "line": 1,
-      "offset": 29,
-    },
-    "start": {
-      "column": 28,
-      "line": 1,
-      "offset": 27,
-    },
-  },
-  "type": 0,
-  "value": " !",
-}
-`;
-
-exports[`modulo cases > multiple >  %{action} issue %s %{code} ! 12`] = `
-{
-  "loc": {
-    "end": {
-      "column": 30,
-      "line": 1,
-      "offset": 29,
-    },
-    "start": {
-      "column": 30,
-      "line": 1,
-      "offset": 29,
-    },
-  },
-  "type": 14,
-}
-`;
diff --git a/packages/message-compiler/test/tokenizer/list.test.ts b/packages/message-compiler/test/tokenizer/list.test.ts
index 055f619d..411f5961 100644
--- a/packages/message-compiler/test/tokenizer/list.test.ts
+++ b/packages/message-compiler/test/tokenizer/list.test.ts
@@ -309,21 +309,13 @@ test('multi lines', () => {
   })
 })
 
-test('with modulo', () => {
+test('has modulo', () => {
   const tokenizer = createTokenizer('hi %{0} !')
   expect(tokenizer.nextToken()).toEqual({
     type: TokenTypes.Text,
-    value: 'hi ',
+    value: 'hi %',
     loc: {
       start: { line: 1, column: 1, offset: 0 },
-      end: { line: 1, column: 4, offset: 3 }
-    }
-  })
-  expect(tokenizer.nextToken()).toEqual({
-    type: TokenTypes.Modulo,
-    value: '%',
-    loc: {
-      start: { line: 1, column: 4, offset: 3 },
       end: { line: 1, column: 5, offset: 4 }
     }
   })
diff --git a/packages/message-compiler/test/tokenizer/named.test.ts b/packages/message-compiler/test/tokenizer/named.test.ts
index 6dba32a4..c7c3bb3c 100644
--- a/packages/message-compiler/test/tokenizer/named.test.ts
+++ b/packages/message-compiler/test/tokenizer/named.test.ts
@@ -361,269 +361,54 @@ test('include hyphen', () => {
   })
 })
 
-describe('modulo cases', () => {
-  test('basic named: hi %{name} !', () => {
-    const tokenizer = createTokenizer('hi %{name} !')
-    expect(tokenizer.nextToken()).toEqual({
-      type: TokenTypes.Text,
-      value: 'hi ',
-      loc: {
-        start: { line: 1, column: 1, offset: 0 },
-        end: { line: 1, column: 4, offset: 3 }
-      }
-    })
-    expect(tokenizer.nextToken()).toEqual({
-      type: TokenTypes.Modulo,
-      value: '%',
-      loc: {
-        start: { line: 1, column: 4, offset: 3 },
-        end: { line: 1, column: 5, offset: 4 }
-      }
-    })
-    expect(tokenizer.nextToken()).toEqual({
-      type: TokenTypes.BraceLeft,
-      value: '{',
-      loc: {
-        start: { line: 1, column: 5, offset: 4 },
-        end: { line: 1, column: 6, offset: 5 }
-      }
-    })
-    expect(tokenizer.nextToken()).toEqual({
-      type: TokenTypes.Named,
-      value: 'name',
-      loc: {
-        start: { line: 1, column: 6, offset: 5 },
-        end: { line: 1, column: 10, offset: 9 }
-      }
-    })
-    expect(tokenizer.nextToken()).toEqual({
-      type: TokenTypes.BraceRight,
-      value: '}',
-      loc: {
-        start: { line: 1, column: 10, offset: 9 },
-        end: { line: 1, column: 11, offset: 10 }
-      }
-    })
-    expect(tokenizer.nextToken()).toEqual({
-      type: TokenTypes.Text,
-      value: ' !',
-      loc: {
-        start: { line: 1, column: 11, offset: 10 },
-        end: { line: 1, column: 13, offset: 12 }
-      }
-    })
-    expect(tokenizer.nextToken()).toEqual({
-      type: TokenTypes.EOF,
-      loc: {
-        start: { line: 1, column: 13, offset: 12 },
-        end: { line: 1, column: 13, offset: 12 }
-      }
-    })
+test('has modulo', () => {
+  const tokenizer = createTokenizer('hi %{name} !')
+  expect(tokenizer.nextToken()).toEqual({
+    type: TokenTypes.Text,
+    value: 'hi %',
+    loc: {
+      start: { line: 1, column: 1, offset: 0 },
+      end: { line: 1, column: 5, offset: 4 }
+    }
   })
-
-  test('not modulo named: hi % {name} !', () => {
-    const tokenizer = createTokenizer('hi % {name} !')
-    expect(tokenizer.nextToken()).toEqual({
-      type: TokenTypes.Text,
-      value: 'hi % ',
-      loc: {
-        start: { line: 1, column: 1, offset: 0 },
-        end: { line: 1, column: 6, offset: 5 }
-      }
-    })
-    expect(tokenizer.nextToken()).toEqual({
-      type: TokenTypes.BraceLeft,
-      value: '{',
-      loc: {
-        start: { line: 1, column: 6, offset: 5 },
-        end: { line: 1, column: 7, offset: 6 }
-      }
-    })
-    expect(tokenizer.nextToken()).toEqual({
-      type: TokenTypes.Named,
-      value: 'name',
-      loc: {
-        start: { line: 1, column: 7, offset: 6 },
-        end: { line: 1, column: 11, offset: 10 }
-      }
-    })
-    expect(tokenizer.nextToken()).toEqual({
-      type: TokenTypes.BraceRight,
-      value: '}',
-      loc: {
-        start: { line: 1, column: 11, offset: 10 },
-        end: { line: 1, column: 12, offset: 11 }
-      }
-    })
-    expect(tokenizer.nextToken()).toEqual({
-      type: TokenTypes.Text,
-      value: ' !',
-      loc: {
-        start: { line: 1, column: 12, offset: 11 },
-        end: { line: 1, column: 14, offset: 13 }
-      }
-    })
-    expect(tokenizer.nextToken()).toEqual({
-      type: TokenTypes.EOF,
-      loc: {
-        start: { line: 1, column: 14, offset: 13 },
-        end: { line: 1, column: 14, offset: 13 }
-      }
-    })
+  expect(tokenizer.nextToken()).toEqual({
+    type: TokenTypes.BraceLeft,
+    value: '{',
+    loc: {
+      start: { line: 1, column: 5, offset: 4 },
+      end: { line: 1, column: 6, offset: 5 }
+    }
   })
-
-  test('other placeholder syntax: hi %s !', () => {
-    const tokenizer = createTokenizer('hi %s !')
-    expect(tokenizer.nextToken()).toEqual({
-      type: TokenTypes.Text,
-      value: 'hi %s !',
-      loc: {
-        start: { line: 1, column: 1, offset: 0 },
-        end: { line: 1, column: 8, offset: 7 }
-      }
-    })
-    expect(tokenizer.nextToken()).toEqual({
-      type: TokenTypes.EOF,
-      loc: {
-        start: { line: 1, column: 8, offset: 7 },
-        end: { line: 1, column: 8, offset: 7 }
-      }
-    })
+  expect(tokenizer.nextToken()).toEqual({
+    type: TokenTypes.Named,
+    value: 'name',
+    loc: {
+      start: { line: 1, column: 6, offset: 5 },
+      end: { line: 1, column: 10, offset: 9 }
+    }
   })
-
-  describe('multiple', () => {
-    test(`%{nickname} %{action} issue %{code}`, () => {
-      const tokenizer = createTokenizer(`%{nickname} %{action} issue %{code}`)
-      expect(tokenizer.nextToken()).toEqual({
-        type: TokenTypes.Modulo,
-        value: '%',
-        loc: {
-          start: { line: 1, column: 1, offset: 0 },
-          end: { line: 1, column: 2, offset: 1 }
-        }
-      })
-      expect(tokenizer.nextToken()).toEqual({
-        type: TokenTypes.BraceLeft,
-        value: '{',
-        loc: {
-          start: { line: 1, column: 2, offset: 1 },
-          end: { line: 1, column: 3, offset: 2 }
-        }
-      })
-      expect(tokenizer.nextToken()).toEqual({
-        type: TokenTypes.Named,
-        value: 'nickname',
-        loc: {
-          start: { line: 1, column: 3, offset: 2 },
-          end: { line: 1, column: 11, offset: 10 }
-        }
-      })
-      expect(tokenizer.nextToken()).toEqual({
-        type: TokenTypes.BraceRight,
-        value: '}',
-        loc: {
-          start: { line: 1, column: 11, offset: 10 },
-          end: { line: 1, column: 12, offset: 11 }
-        }
-      })
-      expect(tokenizer.nextToken()).toEqual({
-        type: TokenTypes.Text,
-        value: ' ',
-        loc: {
-          start: { line: 1, column: 12, offset: 11 },
-          end: { line: 1, column: 13, offset: 12 }
-        }
-      })
-      expect(tokenizer.nextToken()).toEqual({
-        type: TokenTypes.Modulo,
-        value: '%',
-        loc: {
-          start: { line: 1, column: 13, offset: 12 },
-          end: { line: 1, column: 14, offset: 13 }
-        }
-      })
-      expect(tokenizer.nextToken()).toEqual({
-        type: TokenTypes.BraceLeft,
-        value: '{',
-        loc: {
-          start: { line: 1, column: 14, offset: 13 },
-          end: { line: 1, column: 15, offset: 14 }
-        }
-      })
-      expect(tokenizer.nextToken()).toEqual({
-        type: TokenTypes.Named,
-        value: 'action',
-        loc: {
-          start: { line: 1, column: 15, offset: 14 },
-          end: { line: 1, column: 21, offset: 20 }
-        }
-      })
-      expect(tokenizer.nextToken()).toEqual({
-        type: TokenTypes.BraceRight,
-        value: '}',
-        loc: {
-          start: { line: 1, column: 21, offset: 20 },
-          end: { line: 1, column: 22, offset: 21 }
-        }
-      })
-      expect(tokenizer.nextToken()).toEqual({
-        type: TokenTypes.Text,
-        value: ' issue ',
-        loc: {
-          start: { line: 1, column: 22, offset: 21 },
-          end: { line: 1, column: 29, offset: 28 }
-        }
-      })
-      expect(tokenizer.nextToken()).toEqual({
-        type: TokenTypes.Modulo,
-        value: '%',
-        loc: {
-          start: { line: 1, column: 29, offset: 28 },
-          end: { line: 1, column: 30, offset: 29 }
-        }
-      })
-      expect(tokenizer.nextToken()).toEqual({
-        type: TokenTypes.BraceLeft,
-        value: '{',
-        loc: {
-          start: { line: 1, column: 30, offset: 29 },
-          end: { line: 1, column: 31, offset: 30 }
-        }
-      })
-      expect(tokenizer.nextToken()).toEqual({
-        type: TokenTypes.Named,
-        value: 'code',
-        loc: {
-          start: { line: 1, column: 31, offset: 30 },
-          end: { line: 1, column: 35, offset: 34 }
-        }
-      })
-      expect(tokenizer.nextToken()).toEqual({
-        type: TokenTypes.BraceRight,
-        value: '}',
-        loc: {
-          start: { line: 1, column: 35, offset: 34 },
-          end: { line: 1, column: 36, offset: 35 }
-        }
-      })
-      expect(tokenizer.nextToken()).toEqual({
-        type: TokenTypes.EOF,
-        loc: {
-          start: { line: 1, column: 36, offset: 35 },
-          end: { line: 1, column: 36, offset: 35 }
-        }
-      })
-    })
-
-    test(` %{action} issue %s %{code} !`, () => {
-      const tokenizer = createTokenizer(` %{action} issue %s %{code} !`)
-      let token = tokenizer.nextToken()
-      while (token.type !== TokenTypes.EOF) {
-        expect(token).toMatchSnapshot()
-        token = tokenizer.nextToken()
-      }
-      expect(token).toMatchSnapshot()
-    })
+  expect(tokenizer.nextToken()).toEqual({
+    type: TokenTypes.BraceRight,
+    value: '}',
+    loc: {
+      start: { line: 1, column: 10, offset: 9 },
+      end: { line: 1, column: 11, offset: 10 }
+    }
+  })
+  expect(tokenizer.nextToken()).toEqual({
+    type: TokenTypes.Text,
+    value: ' !',
+    loc: {
+      start: { line: 1, column: 11, offset: 10 },
+      end: { line: 1, column: 13, offset: 12 }
+    }
+  })
+  expect(tokenizer.nextToken()).toEqual({
+    type: TokenTypes.EOF,
+    loc: {
+      start: { line: 1, column: 13, offset: 12 },
+      end: { line: 1, column: 13, offset: 12 }
+    }
   })
 })
 
diff --git a/packages/vue-i18n-core/test/__snapshots__/issues.test.ts.snap b/packages/vue-i18n-core/test/__snapshots__/issues.test.ts.snap
index 0cf3caac..a46b3709 100644
--- a/packages/vue-i18n-core/test/__snapshots__/issues.test.ts.snap
+++ b/packages/vue-i18n-core/test/__snapshots__/issues.test.ts.snap
@@ -6,8 +6,6 @@ exports[`issue #1014 1`] = `"<span>Add</span>"`;
 
 exports[`issue #1054, #1053 1`] = `"<p>+$123,456.79</p><span>+$123,456.79</span>"`;
 
-exports[`issue #1055 1`] = `"<p>John opened issue 123</p>"`;
-
 exports[`issue #1365 1`] = `"<p>Animal</p>"`;
 
 exports[`issue #1373 1`] = `"<p class="name">hello, <span>kazupon</span>!</p><p>6/5/2023</p><p>$100.00</p>"`;
diff --git a/packages/vue-i18n-core/test/issues.test.ts b/packages/vue-i18n-core/test/issues.test.ts
index a742fe40..c59ddb0b 100644
--- a/packages/vue-i18n-core/test/issues.test.ts
+++ b/packages/vue-i18n-core/test/issues.test.ts
@@ -750,28 +750,6 @@ test('issue #1054, #1053', async () => {
   expect(wrapper.html()).toMatchSnapshot()
 })
 
-test('issue #1055', async () => {
-  const i18n = createI18n({
-    legacy: false,
-    locale: 'en',
-    messages: {
-      en: {
-        issue: '%{nickname} %{action} issue %{code}'
-      }
-    }
-  })
-
-  const App = defineComponent({
-    template: `
-      <p>{{ $t('issue', { nickname: 'John', action: 'opened', code: '123' }) }}</p>
-    `
-  })
-
-  const wrapper = await mount(App, i18n)
-
-  expect(wrapper.html()).toMatchSnapshot()
-})
-
 test('issue #1083', async () => {
   const i18n = createI18n({
     legacy: false,
diff --git a/packages/vue-i18n-core/test/warnings.test.ts b/packages/vue-i18n-core/test/warnings.test.ts
index b418dfac..7f63cee6 100644
--- a/packages/vue-i18n-core/test/warnings.test.ts
+++ b/packages/vue-i18n-core/test/warnings.test.ts
@@ -1,5 +1,5 @@
 import { I18nWarnCodes } from '../src/warnings'
 
 test('I18nWarnCodes', () => {
-  expect(I18nWarnCodes.FALLBACK_TO_ROOT).toBe(9)
+  expect(I18nWarnCodes.FALLBACK_TO_ROOT).toBe(8)
 })