pax_global_header00006660000000000000000000000064152444763650014532gustar00rootroot0000000000000052 comment=e7e91c14b8c50e3b5cca0d2a8e64badd009f503c cmigemo-1.8.0/000077500000000000000000000000001524447636500131605ustar00rootroot00000000000000cmigemo-1.8.0/.clang-format000066400000000000000000000014751524447636500155420ustar00rootroot00000000000000Language: C BasedOnStyle: LLVM IndentWidth: 4 TabWidth: 8 UseTab: Never ColumnLimit: 80 BreakAfterReturnType: AllDefinitions BreakBeforeBraces: Custom BraceWrapping: AfterCaseLabel: true AfterClass: true AfterControlStatement: Always AfterEnum: false AfterFunction: true AfterNamespace: true AfterObjCDeclaration: true AfterStruct: true AfterUnion: true AfterExternBlock: false BeforeCatch: true BeforeElse: true BeforeLambdaBody: true BeforeWhile: true #IndentBraces: true #SplitEmptyFunction: true #SplitEmptyRecord: true #SplitEmptyNamespace: true BreakBeforeBinaryOperators: NonAssignment IndentPPDirectives: AfterHash PPIndentWidth: 1 IndentCaseLabels: true IndentExternBlock: NoIndent ContinuationIndentWidth: 8 AlignAfterOpenBracket: false AlignConsecutiveMacros: Consecutive cmigemo-1.8.0/.cmakefmt.yaml000066400000000000000000000121251524447636500157120ustar00rootroot00000000000000# yaml-language-server: $schema=https://cmakefmt.dev/schemas/latest/schema.json # Default cmakefmt configuration. # Copy this to .cmakefmt.yaml and uncomment the optional settings # you want to customize. format: # Disable formatting entirely (return source unchanged). # disable: true # Output line-ending style: unix (LF), windows (CRLF), or auto (detect from input). # line_ending: windows # Maximum rendered line width before cmakefmt wraps a call. line_width: 80 # Number of spaces per indentation level when use_tabs is false. tab_size: 2 # Indent with tab characters instead of spaces. # use_tabs: true # How to handle fractional indentation when use_tabs is true: use-space or round-up. # fractional_tab_policy: round-up # Maximum number of consecutive blank lines to preserve. max_empty_lines: 1 # Maximum wrapped lines to tolerate before switching to a more vertical layout. max_hanging_wrap_lines: 2 # Maximum positional arguments to keep in a hanging-wrap layout. max_hanging_wrap_positional_args: 6 # Maximum keyword/flag subgroups to keep in a hanging-wrap layout. max_hanging_wrap_groups: 2 # Maximum rows a hanging-wrap positional group may consume before nesting is forced. max_rows_cmdline: 2 # Commands that must always use vertical (wrapped) layout. # always_wrap: # - target_link_libraries # Return an error if any formatted line exceeds line_width. # require_valid_layout: true # Keep the first positional argument on the command line when wrapping. # wrap_after_first_arg: true # Continuation-line alignment when a wrapped keyword section overflows # line_width: under-first-value (default, cmake-format hanging-indent) or # same-indent (wrap at the keyword's own indent). # continuation_align: same-indent # Sort arguments in keyword sections marked sortable in the command spec. # enable_sort: true # Heuristically sort keyword sections where all arguments are simple unquoted tokens. # autosort: true # Put the closing ')' on its own line when a call wraps. dangle_parens: false # Alignment strategy for a dangling ')': prefix, open, or close. dangle_align: prefix # Lower heuristic bound used when deciding between compact and wrapped layouts. min_prefix_length: 4 # Upper heuristic bound used when deciding between compact and wrapped layouts. max_prefix_length: 10 # Insert a space before '(' for control-flow commands like if/foreach. # space_before_control_paren: true # Insert a space before '(' for function() and macro() definitions. # space_before_definition_paren: true # Output casing for command names: lower, upper, or unchanged. command_case: lower # Output casing for recognized keywords and flags: lower, upper, or unchanged. keyword_case: upper markup: # Enable markup-aware comment handling. enable_markup: true # Preserve the first comment block in a file literally. first_comment_is_literal: true # Preserve comments matching a custom regex literally. # literal_comment_pattern: '^\s*NOTE:' # Preferred bullet character when normalizing markup lists. bullet_char: '*' # Preferred punctuation for numbered lists when normalizing markup. enum_char: '.' # Regex describing fenced literal comment blocks. fence_pattern: '^\s*[`~]{3}[^`\n]*$' # Regex describing ruler-style comments that should be treated specially. ruler_pattern: '^[^\w\s]{3}.*[^\w\s]{3}$' # Minimum ruler length before a hash-only line is treated as a ruler. hashruler_min_length: 10 # Normalize ruler comments when markup handling is enabled. canonicalize_hashrulers: true # Uncomment and edit a block like this to override formatting knobs # for a specific command. This changes layout behavior for that # command name only; it does not define new command syntax. # # per_command_overrides: # my_add_test: # # Override the line width just for this command. # line_width: 120 # # # Override command casing just for this command. # command_case: unchanged # # # Override keyword casing just for this command. # keyword_case: upper # # # Override indentation width just for this command. # tab_size: 4 # # # Override dangling-paren placement just for this command. # dangle_parens: false # # # Override dangling-paren alignment just for this command. # dangle_align: prefix # # # Override the positional-argument hanging-wrap threshold just for this command. # max_hanging_wrap_positional_args: 8 # # # Override the subgroup hanging-wrap threshold just for this command. # max_hanging_wrap_groups: 3 # YAML custom-command specs live under commands:. Command # specs tell the formatter which tokens are positional arguments, # standalone flags, and keyword sections. # # Example: a custom test command with a flag and four keyword sections. # Uncomment this block to teach cmakefmt the argument structure. # # commands: # my_add_test: # pargs: 0 # flags: # - VERBOSE # kwargs: # NAME: # nargs: 1 # SOURCES: # nargs: "+" # LIBRARIES: # nargs: "+" # TIMEOUT: # nargs: 1 cmigemo-1.8.0/.github/000077500000000000000000000000001524447636500145205ustar00rootroot00000000000000cmigemo-1.8.0/.github/dependabot.yml000066400000000000000000000002701524447636500173470ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" groups: ghthub-actions-group: patterns: ["*"] cmigemo-1.8.0/.github/workflows/000077500000000000000000000000001524447636500165555ustar00rootroot00000000000000cmigemo-1.8.0/.github/workflows/ci-linux.yml000066400000000000000000000022341524447636500210310ustar00rootroot00000000000000name: CI on Linux on: workflow_call: jobs: build: name: Build strategy: matrix: include: - { arch: aarch64, runner: ubuntu-24.04-arm, } - { arch: x86_64, runner: ubuntu-latest, } runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@v7 - name: Build run: | cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --parallel - name: Test run: cmake --build build --target test - name: Profiling run: | cmake --build build --target profile mkdir -p tmp/profile-linux-${{ matrix.arch }} cp build/bench/profile*.log tmp/profile-linux-${{ matrix.arch }} - name: Packaging run: | cmake --build build --target package --parallel - name: List files in build run: tree -Fh build - name: Upload profiling logs uses: actions/upload-artifact@v7 with: name: profile-linux-${{ matrix.arch }} path: tmp/profile-linux-${{ matrix.arch }} - name: Upload the package uses: actions/upload-artifact@v7 with: path: build/cmigemo-*.tar.gz archive: false cmigemo-1.8.0/.github/workflows/ci-macos.yml000066400000000000000000000014231524447636500207730ustar00rootroot00000000000000name: CI on macOS on: workflow_call: jobs: build: name: Build runs-on: macos-latest steps: - name: Trust AWS Tap run: brew trust aws/tap - name: Install dependencies via Homebrew run: | brew update brew install tree - uses: actions/checkout@v7 - name: Build run: | cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --parallel - name: Test run: cmake --build build --target test - name: Packaging run: | cmake --build build --target package --parallel - name: List files in build run: tree -Fh build - name: Upload the package uses: actions/upload-artifact@v7 with: path: build/cmigemo-*.tar.gz archive: false cmigemo-1.8.0/.github/workflows/ci-wasm.yml000066400000000000000000000026151524447636500206440ustar00rootroot00000000000000name: CI on WebAssembly on: workflow_call: jobs: build: name: Build runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - name: Set up Emscripten SDK uses: mymindstorm/setup-emsdk@v16 - name: Set up Node.js uses: actions/setup-node@v7 with: node-version: 'latest' - name: Build run: | emcmake cmake -B build-wasm -DBUILD_DICT=ON -DCMAKE_BUILD_TYPE=Release cmake --build build-wasm - name: Test run: node wasm/test/test.js - name: Packaging id: packaging run: | VERSION=$(grep -w MIGEMO_VERSION build-wasm/src/include/migemo.h | cut -d '"' -f 2) PRERELEASE=$(grep -w MIGEMO_VERSION_PRERELEASE build-wasm/src/include/migemo.h | cut -d '"' -f 2) FULL_VER="${VERSION}${PRERELEASE}" PKG_NAME="cmigemo-${FULL_VER}-wasm" PKG_DIR="build-wasm/${PKG_NAME}" mkdir -p "$PKG_DIR" cp build-wasm/bin/migemo_wasm.* "$PKG_DIR" cp wasm/index.js wasm/library.js wasm/demo.html "$PKG_DIR" mkdir -p "$PKG_DIR/dict" cp -r build-wasm/dict/utf-8/. "$PKG_DIR/dict/" ( cd build-wasm && zip -r "${PKG_NAME}.zip" "$PKG_NAME" ) - name: List files in build run: tree -Fh build-wasm - name: Upload the package uses: actions/upload-artifact@v7 with: path: build-wasm/cmigemo-*.zip archive: false cmigemo-1.8.0/.github/workflows/ci-windows-msvc.yml000066400000000000000000000030551524447636500223340ustar00rootroot00000000000000name: CI on Windows (MSVC) on: workflow_call: jobs: build: name: Build runs-on: windows-2025-vs2026 defaults: run: shell: cmd steps: - name: Set up MSYS2 packages uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # v2.32.0 id: msys2 with: msystem: UCRT64 update: true release: false pacboy: >- cmake:p iconv: gzip: perl: tree: - name: Setup MSYS2 PATH run: | echo ${{ steps.msys2.outputs.msys2-location }}\%MSYSTEM%\bin>> %GITHUB_PATH% echo ${{ steps.msys2.outputs.msys2-location }}\usr\bin>> %GITHUB_PATH% - name: Setup VC++ environment (VCVARSALL) run: for /f "usebackq tokens=*" %%i in (`vswhere -products * -latest -property installationPath`) do (echo VCVARSALL=%%i\VC\Auxiliary\Build\vcvarsall.bat) >> %GITHUB_ENV% - uses: actions/checkout@v7 - name: Build run: | call "%VCVARSALL%" amd64 cmake -B build -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release cmake --build build --parallel - name: Test run: | call "%VCVARSALL%" amd64 cmake --build build --target test - name: Packaging run: | call "%VCVARSALL%" amd64 cmake --build build --target package --parallel - name: List files in build shell: msys2 {0} run: tree -Fh build - name: Upload the package uses: actions/upload-artifact@v7 with: path: build/cmigemo-*.zip archive: false cmigemo-1.8.0/.github/workflows/ci-windows-msys2.yml000066400000000000000000000027471524447636500224500ustar00rootroot00000000000000name: CI on Windows (MSYS2) on: workflow_call: jobs: build: name: Build runs-on: windows-2025-vs2026 defaults: run: shell: cmd steps: - name: Set up MSYS2 packages uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # v2.32.0 id: msys2 with: msystem: MSYS update: true release: false pacboy: >- cmake: make: gcc: iconv: gzip: perl: tree: - uses: actions/checkout@v7 - name: Build shell: msys2 {0} run: | cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --parallel - name: Test shell: msys2 {0} run: cmake --build build --target test - name: Profiling shell: msys2 {0} run: | cmake --build build --target profile mkdir -p tmp/profile-windows-msys-amd64 cp build/bench/profile*.log tmp/profile-windows-msys-amd64 - name: Packaging shell: msys2 {0} run: | cmake --build build --target package --parallel - name: List files in build shell: msys2 {0} run: tree -Fh build - name: Upload profiling logs uses: actions/upload-artifact@v7 with: name: profile-windows-msys-amd64 path: tmp/profile-windows-msys-amd64 - name: Upload the package uses: actions/upload-artifact@v7 with: path: build/cmigemo-*.tar.gz archive: false cmigemo-1.8.0/.github/workflows/ci-windows-ucrt64.yml000066400000000000000000000027411524447636500225140ustar00rootroot00000000000000name: CI on Windows (UCRT64) on: workflow_call: jobs: build: name: Build runs-on: windows-2025-vs2026 defaults: run: shell: cmd steps: - name: Set up MSYS2 packages uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # v2.32.0 id: msys2 with: msystem: UCRT64 update: true release: false pacboy: >- cmake:p gcc:p iconv: gzip: perl: tree: - uses: actions/checkout@v7 - name: Build shell: msys2 {0} run: | cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --parallel - name: Test shell: msys2 {0} run: cmake --build build --target test - name: Profiling shell: msys2 {0} run: | cmake --build build --target profile mkdir -p tmp/profile-windows-ucrt64-amd64 cp build/bench/profile*.log tmp/profile-windows-ucrt64-amd64 - name: Packaging shell: msys2 {0} run: | cmake --build build --target package --parallel - name: List files in build shell: msys2 {0} run: tree -Fh build - name: Upload profiling logs uses: actions/upload-artifact@v7 with: name: profile-windows-ucrt64-amd64 path: tmp/profile-windows-ucrt64-amd64 - name: Upload the package uses: actions/upload-artifact@v7 with: path: build/cmigemo-*.zip archive: false cmigemo-1.8.0/.github/workflows/ci.yml000066400000000000000000000030451524447636500176750ustar00rootroot00000000000000name: CI on: [push] concurrency: group: ci-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: linux: name: Linux (Ubuntu) uses: ./.github/workflows/ci-linux.yml secrets: inherit macos: name: macOS uses: ./.github/workflows/ci-macos.yml secrets: inherit windows-ucrt64: name: Windows (UCRT64) uses: ./.github/workflows/ci-windows-ucrt64.yml secrets: inherit windows-msvc: name: Windows (MSVC) uses: ./.github/workflows/ci-windows-msvc.yml secrets: inherit windows-msys2: name: Windows (MSYS2) uses: ./.github/workflows/ci-windows-msys2.yml secrets: inherit wasm: name: WebAssembly uses: ./.github/workflows/ci-wasm.yml secrets: inherit release: name: Create release runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/') needs: - linux - macos - windows-ucrt64 - windows-msvc - windows-msys2 - wasm steps: - uses: actions/download-artifact@v8 with: pattern: cmigemo-* merge-multiple: true skip-decompress: true - name: List files in build run: tree -Fh . - name: Release uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 with: draft: true prerelease: ${{ contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') }} files: | *.tar.gz *.zip fail_on_unmatched_files: true generate_release_notes: true append_body: true cmigemo-1.8.0/.gitignore000066400000000000000000000000501524447636500151430ustar00rootroot00000000000000/build/ /build-*/ /tags /tmp/ gmon.out cmigemo-1.8.0/AGENTS.md000066400000000000000000000146411524447636500144710ustar00rootroot00000000000000# AGENTS.md ## Requirements - **Build**: CMake (3.21+), C11 compiler (GCC, Clang, MSVC) - **Dictionary generation** (default, `BUILD_DICT=ON`): `curl`, `iconv`, `gzip`, `perl` and network access (downloads `SKK-JISYO.L`) - **Profiling** (GCC/Clang only): `gprof` ## Build - Configure: `cmake -B build` (default type: `Release`; for debug: `-DCMAKE_BUILD_TYPE=Debug`) - Build: `cmake --build build --parallel` - Artifacts: executables in `build/bin/` (`cmigemo`, `romaji`, `test_*_test`, `bench_char_query`, `bench_migemo_open`), libraries in `build/lib/` (`migemo` shared, `migemo_static`, `migemo_profile`) - Test: `cmake --build build --target test` (CTest) or `--target check` (ctest with `--output-on-failure`, defined in `test/CMakeLists.txt`) - Profiling: `cmake --build build --target profile` (needs `gprof`; GCC/Clang only, not MSVC) -> `build/bench/profile_*.log` - Package: `cmake --build build --target package` (CPack ZIP on Windows, TGZ elsewhere) - Clean: `cmake --build build --target clean` or `rm -rf build` ## Makefile Shortcuts `make build`, `make test` (build + `check`), `make profile`, `make package`, `make format` (clang-format on `src test include bench tools`), `make format-cmake` (cmakefmt), `make tags`, `make clean`, `make distclean` ## Run CLI ```console ./build/bin/cmigemo -d build/dict/utf-8/migemo-dict ``` (Windows: `cmigemo.exe`; default dict encoding is `cp932` there, `utf-8` elsewhere.) - Options: `-d `, `-s`/`-u ` (max 8, `-u` is an alias), `--convert` (switch to static dictionary, sdict), `--save ` (imply `--convert`, save sdict), `--sdict ` (load sdict; conflicts with `-d/-s/-u` and `--convert/--save`), `-w ` (expand and exit), `-v`/`-e` (vim/emacs regexp style), `-n` (no newline match), `-q`. - Without `-d`, the binary searches (platform-dependent): `./dict//`, `../dict//`, `./build/dict//`, then `./dict/`, `../dict/`, `./build/dict/`, plus the compiled-in install dir (`/cmigemo/`). - `migemo_open()` auto-loads `roma2hira.dat`, `hira2kata.dat`, `han2zen.dat`, `zen2han.dat` from the dictionary's directory; **missing sub-dictionaries are silently ignored** (src/migemo.c). ## Dictionary Generation - Pipeline: download `SKK-JISYO.L` (EUC-JISX0213) from `https://skk-dev.github.io/dict/` -> `iconv` to UTF-8 -> `dict/skk2migemo.pl` -> `dict/optimize-dict.pl` -> per-encoding copies - Encodings: `utf-8`, `euc-jp`, `cp932`, each built into `build/dict//`; default: Windows = `cp932`, non-Windows = `utf-8` - `migemo-dict-zh` (Chinese dict) is copied only into `utf-8`; cp932 conversion tolerates iconv errors - Skip all dictionary work (and the curl/iconv/gzip/perl requirements): `cmake -B build -DBUILD_DICT=OFF` - Build only dictionaries: `cmake --build build --target dictionaries` (per-encoding `dict_` targets also exist) ## Test - Executables `test_migemo_test`, `test_romaji_test`, `test_rxgen_test` from `test/migemo.c`, `test/romaji.c`, `test/rxgen.c`; CTest names `test_migemo`, `test_romaji`, `test_rxgen` - New tests: add `test/.c` and an `add_migemo_test( .c)` call in `test/CMakeLists.txt` (optionally pass `TEST_DICTDIR_*` compile definitions as ARGN) - Test fixture: `test/_testdata/migemo-dict` (static file, not generated); tests explicitly load `dict/roma2hira.dat` via `TEST_DICTDIR_ROMA2HIRA` - Run all: `cmake --build build --target check` ## Benchmark / Profiling - `bench/char_query.c`, `bench/migemo_open.c` -> `bench_char_query`, `bench_migemo_open` executables; run against the utf-8 dict (`DICTDIR=build/dict/utf-8`) - `cmake --build build --target profile` runs all benchmarks and gprof's them -> `build/bench/profile_.log` - New benchmark: add `bench/.c` + `add_profile_target()` in `bench/CMakeLists.txt` (marked with a comment) - Profiling only works with GCC/Clang + `gprof`; the profile targets invoke gprof unconditionally and are broken under MSVC - Bench/profile targets only exist when `BUILD_TESTING=ON` (default) ## Project Structure - OKF Indexing: Each main directory contains an `index.md` (Open Knowledge Format) acting as a directory map. ALWAYS read the relevant `index.md` first to locate source files efficiently before performing broad searches. - `include/migemo.h.in` - public C API template; generated to `build/src/include/migemo.h` at configure time; version comes from `project(VERSION)` in top-level `CMakeLists.txt` - `src/` - core shared library: `migemo_objects` objects -> `migemo` (shared, with `.def`/`.rc` exports) and `migemo_static`; `stree.c` = static dictionary (sdict) binary format - `tools/cmigemo.c` - CLI executable (`cmigemo`); `tools/romaji.c` - interactive romaji conversion console (`romaji`, links `migemo_static`) - `bench/` - benchmark and gprof profiling harness - `dict/` - dictionary build scripts + static `.dat` sub-dictionaries + `migemo-dict-zh` - `wasm/` - Emscripten port; built only under `EMSCRIPTEN` (`emcmake cmake -B build-wasm -DBUILD_DICT=ON`); JS API in `wasm/index.js`, browser test via `node wasm/test/test.js` - `misc/` - reference C# wrapper and vim plugin (not built) - `doc/` - Japanese docs + doxygen config ## Coding Standards - C formatting: `clang-format` per `.clang-format` (LLVM-based, 4-space indent, 80 cols, return type on own line); `make format` - CMake formatting: `cmakefmt` per `.cmakefmt.yaml` (2-space indent, line_width 80); `make format-cmake` - Preserve `// vim:set ts=8 sts=4 sw=4 tw=0 et:` modelines in C sources (Makefile uses `noet`) - MSVC: `/utf-8 /W3 /wd4710 /wd4711 /wd5045`, `_CRT_SECURE_NO_WARNINGS` ## Install ```console cmake --install build ``` - Components: `core` (binary + generated header) and `dict` (dictionaries into `${CMAKE_INSTALL_DATADIR}/cmigemo//`) ## CI - `.github/workflows/ci.yml` fans out to Linux (x86_64 + aarch64), macOS, Windows UCRT64, MSVC, MSYS2 and WebAssembly; each job builds, tests, profiles (gprof on MSYS2/Linux/macOS only) and packages; changes must stay portable across all - Tags (`refs/tags/*`) trigger a draft GitHub Release with all uploaded packages - WASM job: `emcmake cmake -B build-wasm -DBUILD_DICT=ON`, then `node wasm/test/test.js`; packages `migemo_wasm.js/.wasm` + `wasm/` assets ## Constraints - Default build downloads the dictionary; offline builds need `-DBUILD_DICT=OFF` - `BUILD_TESTING=OFF` disables tests and the bench/profile targets at configure time - `profile` target requires `gprof` (GCC/Clang); MSVC builds have no profiling step (CI never runs it there) cmigemo-1.8.0/CMakeLists.txt000066400000000000000000000045701524447636500157260ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.21) project( cmigemo VERSION 1.8.0 DESCRIPTION "C/Migemo library and tool" LANGUAGES C) set(PROJECT_VERSION_PRERELEASE "") set(PROJECT_VERSION_FULL "${PROJECT_VERSION}${PROJECT_VERSION_PRERELEASE}") set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) #------------------------------------------------------------------------------ if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) endif() option(BUILD_DICT "Build dictionary files" ON) option(BUILD_TESTING "Build tests" ON) #------------------------------------------------------------------------------ include(GNUInstallDirs) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) #------------------------------------------------------------------------------ include(CheckCCompilerFlag) # -Wall check_c_compiler_flag("-Wall" COMPILER_SUPPORTS_WALL) if(COMPILER_SUPPORTS_WALL) add_compile_options(-Wall) endif() # -Wno-pointer-sign check_c_compiler_flag("-Wno-pointer-sign" COMPILER_SUPPORTS_WNO_POINTER_SIGN) if(COMPILER_SUPPORTS_WNO_POINTER_SIGN) add_compile_options(-Wno-pointer-sign) endif() # Disable MSVC warnings if(MSVC) add_compile_options(/utf-8 /W3 /wd4710 /wd4711 /wd5045) add_compile_definitions(_CRT_SECURE_NO_WARNINGS) endif() #------------------------------------------------------------------------------ add_subdirectory(src) add_subdirectory(tools) if(BUILD_DICT) add_subdirectory(dict) endif() if(BUILD_TESTING) enable_testing() add_subdirectory(test) add_subdirectory(bench) endif() if(EMSCRIPTEN) add_subdirectory(wasm) endif() #------------------------------------------------------------------------------ set(CPACK_PACKAGE_VENDOR "koron") if(WIN32) set(CPACK_GENERATOR "ZIP") else() set(CPACK_GENERATOR "TGZ") endif() if(WIN32) if(MSVC) set(SYSTEM_SUFFIX "-msvc") elseif(DEFINED ENV{MSYSTEM} AND NOT "$ENV{MSYSTEM}" STREQUAL "") set(SYSTEM_SUFFIX "-$ENV{MSYSTEM}") endif() endif() string(TOLOWER "${CMAKE_SYSTEM_NAME}${SYSTEM_SUFFIX}-${CMAKE_SYSTEM_PROCESSOR}" SYSTEM_LOWER) set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${PROJECT_VERSION_FULL}-${SYSTEM_LOWER}") include(CPack) cmigemo-1.8.0/LICENSE000066400000000000000000000020551524447636500141670ustar00rootroot00000000000000Copyright (c) 2003-2026 MURAOKA Taro (KoRoN) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. cmigemo-1.8.0/Makefile000066400000000000000000000016741524447636500146300ustar00rootroot00000000000000# vim:set ts=8 sts=8 sw=8 tw=0 noet: # # C/Migemo Makefile .PHONY: build test profile tags format format-cmake package clean distclean TAGS_TARGETS = src/*.c src/*.h test/*.c test/*.h bench/*.c bench/*.h build: cmake -B build cmake --build build --parallel tags: $(TAGS_TARGETS) ctags $(TAGS_TARGETS) --langmap=c:+.in include/migemo.h.in test: cmake -B build cmake --build build --parallel --target check profile: cmake -B build cmake --build build --target profile format: mv include/migemo.h.in include/migemo.h find src test include bench tools -type f \( -name "*.c" -o -name "*.h" \) | xargs clang-format -i mv include/migemo.h include/migemo.h.in format-cmake: cmakefmt --in-place . package: cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --target package --config Release --parallel clean: @if [ -d build ]; then cmake --build build --target clean 2>/dev/null || true; fi distclean: rm -rf build rm -f tags cmigemo-1.8.0/README.md000066400000000000000000000072761524447636500144530ustar00rootroot00000000000000# C/Migemo library C/Migemo is regexp pattern generator/expander. C/Migemo is a C-language implementation of Migemo (Ruby/Migemo). Software utilizing the C/Migemo library gains the ability to perform incremental Japanese searches using Romaji input. Because it is implemented in C, it is easier to integrate with the vast amount of software written in C compared to the original Ruby/Migemo, and —presumably— it offers improved execution speed. The original Migemo is a tool devised by Satoru Takabayashi that converts Romaji input into regular expressions for Japanese text searching. It was implemented using Ruby and Emacs Lisp to enable incremental Japanese searches in Emacs while typing in Romaji. ## Getting Started ### Build ```console $ cmake -B build $ cmake --build build ``` ### Test ```console $ cmake --build build --target test ``` ### Profiling ```console $ cmake --build build --target profile ``` See `build/profile.log` for the profiling result. ### Clean ```console $ cmake --build build --target clean ``` Or just `rm -rf build`. ## Pre-requirements - Building the program - CMake (3.16 or above) - C11 compiler and binutils equivalents (gcc, clang, msvc or so) - Building the dictionary - CMake (3.16 or above) - curl - iconv - gzip - perl The dictionary is built from [`SKK-JISYO.L`](https://skk-dev.github.io/dict/) - Profiling - gprof ## Build ``` $ cmake -B build $ cmake --build build ``` ### Build Options & Packaging The following options and components are available for selective building and installation (e.g., for distribution packaging): - `BUILD_DICT` (CMake Option, default: `ON`): Set to `OFF` (`cmake -B build -DBUILD_DICT=OFF`) to skip dictionary generation and its external build dependencies (`perl`, `iconv`, `gzip`, etc.). - Target `dictionaries`: Builds all dictionary encodings at once: ```bash cmake --build build --target dictionaries ``` - Install Components: Allows installing core files or dictionary files separately: ```bash # Install core binary, library, and headers only cmake --install build --component core # Install generated dictionary files only cmake --install build --component dict ``` ## Static Dictionary (sdict) C/Migemo supports a pre-compiled binary dictionary format called **sdict** (Static Dictionary). ### Benefits - Fast Startup: Drastically reduces initialization/load time (e.g., from ~50ms down to ~4ms). - Memory Efficiency: Significantly reduces memory footprint (e.g., from ~18MB down to ~8MB). - Improved Performance: Enhances query execution speed due to better CPU cache locality. ### CLI Options `cmigemo` provides the following options for `sdict`: - `--convert`: Converts loaded dynamic dictionaries to `sdict` in-memory and continues execution. Useful for testing `sdict` performance quickly. - `--save `: Saves the converted `sdict` to a specified file path (implies `--convert`). - `--sdict `: Loads a pre-compiled `sdict` file directly (conflicts with `-d`/`-s`/`-u` and `--convert`/`--save`). ### Trying sdict in Development ```bash $ make # Generate and save an sdict file (using -w '' to exit immediately after saving) $ ./build/bin/cmigemo --save build/dict/utf-8/migemo-sdict -w '' # Launch cmigemo using the saved sdict $ ./build/bin/cmigemo --sdict build/dict/utf-8/migemo-sdict ``` ## Vim plugin If you want to use C/Migemo only as a vim plugin, use https://github.com/haya14busa/vim-migemo ## Licenses C/Migemo is distributed under the MIT License. The built dictionary is subject to the GPL, in accordance with the license of the source SKK-JISYO.L. cmigemo-1.8.0/bench/000077500000000000000000000000001524447636500142375ustar00rootroot00000000000000cmigemo-1.8.0/bench/CMakeLists.txt000066400000000000000000000043451524447636500170050ustar00rootroot00000000000000#------------------------------------------------------------------------------ get_target_property(MIGEMO_SOURCES migemo_objects SOURCES) get_target_property(MIGEMO_DIR migemo_objects SOURCE_DIR) list(TRANSFORM MIGEMO_SOURCES PREPEND "${MIGEMO_DIR}/" REGEX "^[^/]") add_library(migemo_profile STATIC ${MIGEMO_SOURCES}) target_include_directories( migemo_profile PUBLIC ${PROJECT_SOURCE_DIR}/src ${PROJECT_BINARY_DIR}/src/include) target_compile_definitions( migemo_profile PUBLIC DICTDIR="${PROJECT_BINARY_DIR}/dict/utf-8") if(BUILD_DICT) add_dependencies(migemo_profile dict_utf-8) endif() find_program(GPROF_EXECUTABLE gprof) if(GPROF_EXECUTABLE AND CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") target_compile_options(migemo_profile PUBLIC -pg -fno-omit-frame-pointer) target_link_options(migemo_profile INTERFACE -pg -fno-omit-frame-pointer) endif() #------------------------------------------------------------------------------ function(add_profile_target target_name) set(bench_target "bench_${target_name}") set(profile_target "profile_${target_name}") add_executable(${bench_target} "${target_name}.c") target_link_libraries(${bench_target} PRIVATE migemo_profile) set(work_dir "${PROJECT_BINARY_DIR}/bench/${target_name}") file(MAKE_DIRECTORY "${work_dir}") add_custom_target( ${profile_target} COMMAND $ COMMAND ${CMAKE_COMMAND} -DSRC="$.gmon" -DDST=gmon.out -P "${CMAKE_CURRENT_SOURCE_DIR}/copy_if_exists.cmake" COMMAND ${GPROF_EXECUTABLE} $ gmon.out > "${PROJECT_BINARY_DIR}/bench/${profile_target}.log" COMMAND ${CMAKE_COMMAND} -E remove gmon.out "$.gmon" WORKING_DIRECTORY ${work_dir} DEPENDS ${bench_target} COMMENT "Profiling ${target_name} -> ${profile_target}.log") set_property(DIRECTORY APPEND PROPERTY ALL_PROFILE_TARGETS ${profile_target}) endfunction() add_profile_target(char_query) add_profile_target(migemo_open) # Add it here when adding a benchmark target. get_property(all_profiles DIRECTORY PROPERTY ALL_PROFILE_TARGETS) add_custom_target( profile DEPENDS ${all_profiles} COMMENT "Running all profiles") cmigemo-1.8.0/bench/bench_common.h000066400000000000000000000024221524447636500170370ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // bench_common.h - // #pragma once #include #include #ifndef DICTDIR # define DICTDIR "../../dict" #endif typedef uint64_t bench_time_t; #if defined(_MSC_VER) # include static inline bench_time_t time_now(void) { LARGE_INTEGER count; QueryPerformanceCounter(&count); return (bench_time_t)count.QuadPart; } static inline double time_to_sec(bench_time_t duration) { LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); return (double)duration / (double)freq.QuadPart; } #else static inline bench_time_t time_now(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (bench_time_t)((uint64_t)ts.tv_sec * 1000000000ULL + (uint64_t)ts.tv_nsec); } static inline double time_to_sec(bench_time_t duration) { return (double)duration / 1e9; } #endif static inline bench_time_t time_since(bench_time_t start) { return time_now() - start; } #define TIME_MEASURE_ADD(dur) \ for (bench_time_t _start = 0, _done = 0; \ !_done && (_start = time_now(), 1); \ (dur) += time_since(_start), _done = 1) cmigemo-1.8.0/bench/char_query.c000066400000000000000000000030501524447636500165430ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // profile_char_query.c - Profile single-character queries // // Author: MURAOKA Taro #include "common.h" #define NUM_TRIAL 50 #include #include "bench_common.h" #include "migemo.h" #include "migemo_struct.h" static bench_time_t profile_char_query(migemo *mo, int trial) { char key[2] = {'\0', '\0'}; bench_time_t dur = 0; for (int i = 0; i < trial; ++i) { for (key[0] = 'a'; key[0] <= 'z'; ++key[0]) { TIME_MEASURE_ADD(dur) { char *ans = migemo_query(mo, key); migemo_release(mo, ans); } } } return dur; } int main(int argc, char **argv) { migemo *mo; bench_time_t dur_load = 0; bench_time_t dur_query = 0; bench_time_t dur_switch = 0; bench_time_t dur_query2 = 0; TIME_MEASURE_ADD(dur_load) { mo = migemo_open(DICTDIR "/" MIGEMO_DICT_FILENAME); } if (!mo) return 1; dur_query = profile_char_query(mo, NUM_TRIAL); TIME_MEASURE_ADD(dur_switch) { migemo_switch_sdict(mo, MIGEMO_SDICT_PRESERVE_MDICT); } dur_query2 = profile_char_query(mo, NUM_TRIAL); printf("Results:\n"); printf(" load : %.9f secs\n", time_to_sec(dur_load)); printf(" query (mdict) : %.9f secs\n", time_to_sec(dur_query)); printf(" switch : %.9f secs\n", time_to_sec(dur_switch)); printf(" query (sdict) : %.9f secs\n", time_to_sec(dur_query2)); migemo_close(mo); return 0; } cmigemo-1.8.0/bench/copy_if_exists.cmake000066400000000000000000000001001524447636500202570ustar00rootroot00000000000000if(EXISTS "${SRC}") file(COPY_FILE "${SRC}" "${DST}") endif() cmigemo-1.8.0/bench/index.md000066400000000000000000000026121524447636500156710ustar00rootroot00000000000000--- type: Directory Index title: "bench Index" description: "Benchmarks and profiling harnesses for measuring migemo dictionary loading and query performance." tags: [index] --- # Overview Contains standalone benchmark programs that measure migemo performance (dictionary loading and single-character queries) and the CMake targets that build and run them, including gprof-based profiling for GCC/Clang. # Directory Contents | File / Path | Type | Description | | :--- | :--- | :--- | | [bench_common.h](./bench_common.h) | C header | Provides cross-platform high-resolution timing utilities (`time_now`, `time_to_sec`, `TIME_MEASURE_ADD`) shared by the benchmark programs. | | [char_query.c](./char_query.c) | C source | Benchmark that times dictionary loading, single-character queries, and sdict switching, run against the utf-8 dictionary. | | [CMakeLists.txt](./CMakeLists.txt) | CMake script | Defines the `migemo_profile` static library and the `bench_*`/`profile_*`/`profile` targets that build, run, and gprof the benchmarks. | | [copy_if_exists.cmake](./copy_if_exists.cmake) | CMake script | Helper script invoked by the profile targets to copy a `.gmon` file into `gmon.out` only if it exists. | | [migemo_open.c](./migemo_open.c) | C source | Benchmark that repeatedly calls `migemo_open` and `migemo_close` to measure dictionary load and close times. | # References - [Parent Directory](../index.md) cmigemo-1.8.0/bench/migemo_open.c000066400000000000000000000015111524447636500166770ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // profile_migemo_open.c - Profile migemo_open (loading the dictionary) // // Author: MURAOKA Taro #define NUM_TRIAL 25 #include #include "bench_common.h" #include "migemo.h" #define CLOCK2SEC(t) ((double)(t) / (double)CLOCKS_PER_SEC) int main(int argc, char **argv) { int trial = NUM_TRIAL; migemo *mo; bench_time_t sum_open = 0, sum_close = 0; for (int i = 0; i < trial; i++) { TIME_MEASURE_ADD(sum_open) { mo = migemo_open(DICTDIR "/" MIGEMO_DICT_FILENAME); } TIME_MEASURE_ADD(sum_close) { migemo_close(mo); } } printf("Results:\n"); printf(" migemo_open : %.9f secs\n", time_to_sec(sum_open)); printf(" migemo_close : %.9f secs\n", time_to_sec(sum_close)); return 0; } cmigemo-1.8.0/dict/000077500000000000000000000000001524447636500141035ustar00rootroot00000000000000cmigemo-1.8.0/dict/CMakeLists.txt000066400000000000000000000131041524447636500166420ustar00rootroot00000000000000find_package(Perl REQUIRED) #------------------------------------------------------------------------------ # Detect required commands: curl, iconv, gzip find_program(CURL_EXECUTABLE curl REQUIRED) find_program(ICONV_EXECUTABLE iconv REQUIRED) find_program(GZIP_EXECUTABLE gzip REQUIRED) #------------------------------------------------------------------------------ set(SKKDICT_BASEURL "https://skk-dev.github.io/dict") set(SKKDICT_FILE "SKK-JISYO.L") set(SKKDICT_UTF8_FILE "SKK-JISYO.L.utf-8") set(DICT_FILE "migemo-dict") set(DAT_FILES han2zen.dat hira2kata.dat roma2hira.dat zen2han.dat) set(SKKDICT_PATH "${CMAKE_CURRENT_BINARY_DIR}/${SKKDICT_FILE}") set(SKKDICT_UTF8_PATH "${CMAKE_CURRENT_BINARY_DIR}/${SKKDICT_UTF8_FILE}") set(BASE_DICT_PATH "${CMAKE_CURRENT_BINARY_DIR}/${DICT_FILE}") set_property( DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${SKKDICT_PATH}.gz" "${SKKDICT_PATH}" "${SKKDICT_UTF8_PATH}" "${BASE_DICT_PATH}") #------------------------------------------------------------------------------ # Download SKK-JISYO.L add_custom_command( OUTPUT ${SKKDICT_PATH} COMMAND ${CURL_EXECUTABLE} -fsSLO "${SKKDICT_BASEURL}/${SKKDICT_FILE}.gz" COMMAND ${GZIP_EXECUTABLE} -d "${SKKDICT_FILE}.gz" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Downloading and extracting ${SKKDICT_FILE}") # Convert SKK-JISYO.L (EUC-JP) to SKK-JISYO.L.utf-8 (UTF-8) add_custom_command( OUTPUT ${SKKDICT_UTF8_PATH} COMMAND ${ICONV_EXECUTABLE} -f EUC-JISX0213 -t UTF-8 ${SKKDICT_PATH} > ${SKKDICT_UTF8_PATH} DEPENDS ${SKKDICT_PATH} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Converting ${SKKDICT_FILE} to UTF-8") #------------------------------------------------------------------------------ # Generate C/Migemo dictionary file (migemo-dict). add_custom_command( OUTPUT ${BASE_DICT_PATH} COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/skk2migemo.pl < ${SKKDICT_UTF8_PATH} > ${CMAKE_CURRENT_BINARY_DIR}/tmp.dict COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/optimize-dict.pl < ${CMAKE_CURRENT_BINARY_DIR}/tmp.dict > ${BASE_DICT_PATH} COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/tmp.dict DEPENDS ${SKKDICT_UTF8_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/skk2migemo.pl ${CMAKE_CURRENT_SOURCE_DIR}/optimize-dict.pl WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating base migemo-dict") add_custom_target(generate_base_dict DEPENDS ${BASE_DICT_PATH}) #------------------------------------------------------------------------------ # A helper function that generates a dictionary for the specified encoding. function(add_dict_encoding_target ENCODING_NAME ICONV_ENCODING IGNORE_ERROR) set(OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${ENCODING_NAME}") set(OUT_DICT "${OUT_DIR}/${DICT_FILE}") set(COMMANDS_LIST "") set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${OUT_DIR}") list( APPEND COMMANDS_LIST COMMAND ${CMAKE_COMMAND} -E make_directory ${OUT_DIR}) foreach(dat ${DAT_FILES}) if(ICONV_ENCODING STREQUAL "UTF-8") list( APPEND COMMANDS_LIST COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${dat} ${OUT_DIR}/${dat}) else() list( APPEND COMMANDS_LIST COMMAND ${ICONV_EXECUTABLE} -f UTF-8 -t ${ICONV_ENCODING} ${CMAKE_CURRENT_SOURCE_DIR}/${dat} > ${OUT_DIR}/${dat}) endif() endforeach() # Copy migemo-dict-zh (Chinese dictionary) if(ICONV_ENCODING STREQUAL "UTF-8") list( APPEND COMMANDS_LIST COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/migemo-dict-zh ${OUT_DIR}/) endif() # Convert and copy the main dictionary: migemo-dict if(ICONV_ENCODING STREQUAL "UTF-8") list( APPEND COMMANDS_LIST COMMAND ${CMAKE_COMMAND} -E copy ${BASE_DICT_PATH} ${OUT_DICT}) else() if(IGNORE_ERROR) list( APPEND COMMANDS_LIST COMMAND ${ICONV_EXECUTABLE} -cs -f UTF-8 -t ${ICONV_ENCODING} ${BASE_DICT_PATH} > ${OUT_DICT} || ${CMAKE_COMMAND} -E true) else() list( APPEND COMMANDS_LIST COMMAND ${ICONV_EXECUTABLE} -f UTF-8 -t ${ICONV_ENCODING} ${BASE_DICT_PATH} > ${OUT_DICT}) endif() endif() set(DAT_PATHS ${DAT_FILES}) list(TRANSFORM DAT_PATHS PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/") add_custom_command( OUTPUT ${OUT_DICT} ${COMMANDS_LIST} DEPENDS ${BASE_DICT_PATH} ${DAT_PATHS} ${CMAKE_CURRENT_SOURCE_DIR}/migemo-dict-zh WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating ${ENCODING_NAME} dictionary") # Custom targeting for registration to the overall target add_custom_target(dict_${ENCODING_NAME} ALL DEPENDS ${OUT_DICT}) add_dependencies(dict_${ENCODING_NAME} generate_base_dict) install( DIRECTORY "${OUT_DIR}/" DESTINATION "${CMAKE_INSTALL_DATADIR}/cmigemo/${ENCODING_NAME}" COMPONENT dict) endfunction() #------------------------------------------------------------------------------ # Generate dictionaries with character encodings. add_dict_encoding_target("utf-8" "UTF-8" FALSE) add_dict_encoding_target("euc-jp" "EUC-JISX0213" FALSE) add_dict_encoding_target("cp932" "CP932" TRUE) add_custom_target(dictionaries DEPENDS dict_utf-8 dict_euc-jp dict_cp932) cmigemo-1.8.0/dict/han2zen.dat000066400000000000000000000026041524447636500161440ustar00rootroot00000000000000# vi:set ts=8 sts=8 sw=8 tw=0 noet: # # han2zen.dat - 半角→全角変換表 # # Author: MURAOKA Taro # 半角→全角スペース変換は設定不可。 # デリミタをisspace()で定義してしまったため。 #   ! ! " ” # 下の書き方は特例としてコメントではなく '#' の定義となる ## # $ $ % % & & ' ’ ( ( ) ) * * + + , , - - . . / / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 : : ; ; < < = = > > ? ? @ @ A A B B C C D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z Z [ [ \ ¥ ] ] ^ ^ _ _ ` ‘ a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z { { | | } } ~ ~ 。 。 「 「 」 」 、 、 ・ ・ ヲ ヲ ァ ァ ィ ィ ゥ ゥ ェ ェ ォ ォ ャ ャ ュ ュ ョ ョ ッ ッ ー ー ア ア イ イ ウ ウ エ エ オ オ カ カ キ キ ク ク ケ ケ コ コ サ サ シ シ ス ス セ セ ソ ソ タ タ チ チ ツ ツ テ テ ト ト ナ ナ ニ ニ ヌ ヌ ネ ネ ノ ノ ハ ハ ヒ ヒ フ フ ヘ ヘ ホ ホ マ マ ミ ミ ム ム メ メ モ モ ヤ ヤ ユ ユ ヨ ヨ ラ ラ リ リ ル ル レ レ ロ ロ ワ ワ ン ン ゙ ゛ ゚ ゜ cmigemo-1.8.0/dict/hira2kata.dat000066400000000000000000000014701524447636500164450ustar00rootroot00000000000000# vi:set ts=8 sts=8 sw=8 tw=0 noet: # # hira2kata.dat - 平仮名→カタカナ変換表 # # Author: MURAOKA Taro あ ア い イ う ウ え エ お オ か カ き キ く ク け ケ こ コ さ サ し シ す ス せ セ そ ソ た タ ち チ つ ツ て テ と ト な ナ に ニ ぬ ヌ ね ネ の ノ は ハ ひ ヒ ふ フ へ ヘ ほ ホ ま マ み ミ む ム め メ も モ や ヤ ゆ ユ よ ヨ ら ラ り リ る ル れ レ ろ ロ わ ワ ゐ ヰ ゑ ヱ を ヲ が ガ ぎ ギ ぐ グ げ ゲ ご ゴ ざ ザ じ ジ ず ズ ぜ ゼ ぞ ゾ だ ダ ぢ ヂ づ ヅ で デ ど ド ば バ び ビ ぶ ブ べ ベ ぼ ボ ぱ パ ぴ ピ ぷ プ ぺ ペ ぽ ポ ぁ ァ ぃ ィ ぅ ゥ ぇ ェ ぉ ォ ゃ ャ ゅ ュ ょ ョ ん ン っ ッ ゎ ヮ cmigemo-1.8.0/dict/index.md000066400000000000000000000031271524447636500155370ustar00rootroot00000000000000--- type: Directory Index title: "dict Index" description: "Dictionary sources for C/Migemo: build script, Perl conversion/optimization tools, static Japanese conversion tables, and a Chinese dictionary." tags: [index] --- # Overview This directory holds the dictionary sources used by C/Migemo: the CMake build that downloads SKK-JISYO.L and produces the `migemo-dict` files per encoding, Perl scripts that convert and optimize the dictionary, the static `.dat` tables for Japanese character conversions, and the bundled Chinese dictionary. # Directory Contents | File / Path | Type | Description | | :--- | :--- | :--- | | [CMakeLists.txt](./CMakeLists.txt) | Build | CMake script that downloads SKK-JISYO.L and builds the `migemo-dict` files for the utf-8, euc-jp, and cp932 encodings. | | [han2zen.dat](./han2zen.dat) | Data | Half-width to full-width character conversion table. | | [hira2kata.dat](./hira2kata.dat) | Data | Hiragana to Katakana conversion table. | | [migemo-dict-zh](./migemo-dict-zh) | Data | Chinese dictionary mapping pinyin syllables to Chinese characters. | | [optimize-dict.pl](./optimize-dict.pl) | Script | Perl script that rebalances dictionary entries in DFS midpoint order so C/Migemo can load the dictionary efficiently. | | [roma2hira.dat](./roma2hira.dat) | Data | Table to convert Japanese ROMAJI to HIRAGANA. | | [skk2migemo.pl](./skk2migemo.pl) | Script | Perl script that converts SKK-JISYO data into tab-separated migemo-dict lines. | | [zen2han.dat](./zen2han.dat) | Data | Full-width to half-width character conversion table. | # References - [Parent Directory](../index.md) cmigemo-1.8.0/dict/migemo-dict-zh000066400000000000000000003473631524447636500166630ustar00rootroot00000000000000a 啊 嗄 錒 阿 锕 吖 ai 嗌 娭 磑 硙 砹 閡 餲 堨 阸 阨 戹 誒 㝵 獃 艾 䅬 䀳 隘 㝶 嗳 鴱 靉 鑀 賹 譪 薆 礙 碍 硋 砨 瞹 皧 璦 瑷 爱 濭 曖 暧 懝 懓 愛 嬡 嫒 壒 塧 叆 僾 伌 䬵 䝽 䔽 㿄 㤅 㘷 㗒 㕌 佁 㑸 䑂 噯 欸 馤 靄 霭 躷 藹 蔼 矮 毐 昹 娾 䨠 㢊 㗨 敱 癌 䠹 騃 㱯 皚 皑 敳 捱 嵦 嘊 啀 䶣 诶 唉 挨 锿 鎄 銰 埃 哎 哀 an 阥 韽 匼 蝻 厈 頇 胺 䎨 鮟 㱘 䯥 䮗 豻 䎏 犴 儑 䬓 闇 黯 黬 錌 荌 洝 案 暗 按 岸 堓 匎 䅁 㸩 㟁 䁆 㽢 晻 㜝 銨 隌 罯 揞 埯 垵 唵 俺 䅖 雸 玵 啽 䜙 鵪 鹌 鶕 諳 桉 菴 馣 鞍 鞌 铵 谙 誝 蓭 葊 萻 腤 盫 盦 痷 氨 庵 峖 峎 安 媕 侒 ang 肮 㦹 㼜 醠 盎 枊 軮 䍩 雵 䒢 卬 昻 昂 岇 䭺 䭹 䩕 䀚 㭿 骯 ao 隩 燠 圫 鴁 磽 澳 奧 墺 𩼈 㠗 㜩 㕭 驁 垇 坳 詏 擙 扷 懊 慠 嶴 岙 嫯 奥 奡 傲 䮯 䫨 䜒 䁱 㥿 㜜 㘭 㘬 䞝 抝 㤇 拗 镺 䯠 𥜌 襖 袄 芺 狕 媼 媪 䴈 㑃 聱 䚫 鏖 䐿 骜 鏊 謸 謷 敖 爊 熬 𦪈 鼇 鷔 鳌 鰲 隞 遨 螯 蔜 翺 翱 磝 璈 獓 獒 滶 摮 廒 嶅 嗸 嗷 厫 䵅 䦋 䥝 㿰 㠂 㟼 梎 凹 軪 柪 ba 癹 萆 湃 夿 峇 吧 霸 覇 䱝 䃻 耙 䎱 䎬 㖠 䥯 罷 罢 猈 爸 灞 欛 弝 壩 垻 坝 䰾 䩻 䩗 䇑 䆉 㶚 鈀 钯 㞎 靶 把 茇 墢 䟦 钹 㔜 坺 䳁 菝 跋 拔 鼥 魃 馛 颰 軷 詙 胈 秡 犮 炦 抜 妭 叐 䳊 㧊 扒 芭 叭 鲃 釟 豝 羓 粑 笆 疤 玐 朳 捌 巴 岜 哵 八 仈 bai 棑 䴽 唄 呗 败 贁 蛽 粺 稗 敗 拝 拜 庍 䢙 䒔 㠔 㗑 䙓 百 柏 佰 㼣 襬 絔 粨 矲 擺 摆 捭 㗗 㿟 白 䳆 㼟 掰 ban 埿 肦 魬 拌 伴 䕰 靽 鉡 辦 绊 絆 秚 瓣 湴 扮 怑 姅 半 办 㪵 㚘 㩯 㺜 阪 闆 钣 鈑 蝂 舨 粄 版 板 昄 岅 坂 䬳 䉽 㸞 螌 扳 颁 頒 朌 般 攽 辬 褩 虨 癍 瘢 班 斒 斑 搬 bang 氆 棓 挷 髈 䎧 㾦 䂜 磅 蒡 傍 鎊 䰷 蚌 玤 镑 谤 謗 蜯 艕 稖 棒 塝 䧛 䖫 㯁 㭋 㔙 㮄 䟺 膀 榜 绑 綁 牓 浜 鞤 邫 邦 縍 梆 捠 幫 幚 幇 帮 垹 bao 掊 抔 裒 脬 苴 枹 趵 暴 鑤 鉋 刨 㙸 犦 爆 曓 鮑 鸔 鲍 铇 豹 袌 虣 菢 抱 报 忁 報 勽 儤 䤖 㲒 㫧 㲏 褴 堡 葆 鸨 鴇 鳵 駂 饱 飽 靌 賲 褓 緥 珤 怉 寶 寳 寚 宲 宝 堢 保 䴐 䳰 䳈 䭋 䎂 㻄 㙅 䪨 䥤 雹 瓟 䨌 窇 嫑 䨔 䈏 㿺 㵡 胞 苞 煲 骲 闁 襃 褒 蕔 笣 孢 包 勹 bei 棓 萆 埤 犤 簰 絥 臂 痺 䡶 被 碚 䠙 䋳 㸬 㾱 鞴 㼎 悖 孛 䁅 鐾 㷶 㛝 愂 背 韛 钡 鋇 鄁 郥 邶 辈 輩 軰 贝 貝 褙 蓓 紴 糒 琲 珼 狽 狈 犕 牬 焙 梖 昁 憊 惫 备 僃 備 偹 偝 倍 俻 䰽 䩀 䔒 㻗 㸽 㸢 㶔 㰆 㣁 㔨 北 鉳 㤳 岥 椑 陂 綼 庳 鹎 鵯 錃 藣 禆 碑 盃 桮 杯 揹 悲 卑 伓 ben 夯 獖 燌 鐼 蟦 軬 贲 賁 㱵 逩 輽 笨 桳 撪 捹 坌 倴 䬱 㨧 㤓 夲 苯 畚 楍 本 奙 㮺 㡷 奔 锛 錛 犇 渀 泍 beng 螷 甏 錋 堋 挷 抨 唪 跰 泵 㱶 迸 搒 镚 鏰 逬 蹦 蠯 槰 塴 䨻 㷯 䋽 菶 䩬 㑟 䭰 埲 鞛 誁 琫 䳞 䙀 甭 绷 繃 綳 𢏳 閍 祊 嵭 崩 嘣 伻 bi 肸 肹 舭 畁 殍 萆 鸊 濞 芘 陴 纰 枇 螷 埤 紕 髲 费 䬛 䦘 鉍 睥 䪐 䖩 㵨 裨 篦 㡙 䕗 䀣 㵥 㘠 㢰 蔽 䭮 㹃 㗉 薜 䟆 㱸 㓖 鷩 襣 鎞 鵖 鲾 鰏 蓖 贲 賁 臂 骳 箄 痺 𡚁 鼊 鷝 鮅 魓 髀 驆 駜 馝 饆 飶 韠 鞸 陛 闭 閟 閉 閇 铋 鐴 鏎 鄪 鄨 邲 避 躄 躃 蹕 跸 赑 贔 貱 诐 詖 觱 襞 袐 蜌 蓽 荜 苾 腷 聛 罼 縪 粊 篳 箆 箅 筚 碧 睤 痹 疪 畢 畀 璧 珌 獙 獘 狴 熚 煏 滭 湢 毙 毖 毕 檘 楅 梐 柲 枈 斃 敝 愎 愊 怭 必 彃 弼 弻 弊 廦 庇 幣 币 嬖 婢 妼 奰 壁 堛 坒 嗶 哔 咇 佖 䯗 䮡 䫾 䫁 䩛 䧗 䟤 䏶 䎵 䌟 䋔 䊧 䄶 䁹 㿫 㻫 㳼 㯇 㮿 㪤 㧙 㢸 㢶 㡀 㙄 㘩 啚 蚍 䣥 䇷 比 䠋 潷 滗 㻶 鄙 貏 粃 筆 笔 秕 疕 沘 柀 朼 彼 妣 夶 吡 匕 俾 佊 䘡 䏢 䃾 㪏 㠲 㚰 魮 㮰 䵄 荸 䨆 鼻 皀 颷 逼 豍 螕 稫 皕 毴 屄 偪 庳 bian 獱 萹 辯 緶 辩 缏 便 抃 覍 弁 㻞 㳎 㳒 釆 㲢 辨 鴘 閞 遍 辮 辫 辧 辡 變 苄 艑 玣 汴 汳 昪 揙 忭 徧 変 变 卞 匥 䪻 䡢 䛒 䒪 䉸 㺹 㵷 㴜 㭓 㣐 㝸 扁 褊 贬 貶 藊 窆 碥 惼 匾 䁵 㦚 蝙 甂 边 編 编 鳊 鯿 鯾 鞭 鍽 邊 邉 辺 糄 籩 箯 笾 稨 砭 猵 牑 煸 biao 嫖 骠 驃 徱 蔈 膘 鳔 鰾 覅 俵 䞄 㧼 㯱 飈 錶 諘 褾 裱 表 檦 婊 䔸 㯹 㠒 㟽 飍 髟 臕 麃 麅 颮 藨 灬 颩 脿 骉 驫 飚 飙 飑 飇 飆 镳 镖 鑣 鏢 贆 謤 穮 磦 瘭 猋 爂 熛 瀌 滮 標 标 彪 幖 墂 儦 bie 瘪 䉲 徶 彆 䏟 䋢 㢼 癟 蛂 㿜 别 蹩 襒 蟞 莂 別 䭱 䠥 𤺓 𢠳 龞 鼈 鳖 鱉 虌 憋 bin 频 頻 獱 儐 鬢 鬓 鬂 髩 髕 髌 臏 膑 殯 殡 擯 摈 傧 䐔 蠙 矉 汃 玢 檳 槟 賔 賓 宾 驞 馪 顮 霦 镔 鑌 邠 豳 豩 缤 繽 璸 瑸 瀕 濱 濒 滨 椕 斌 彬 bing 燹 鵧 屛 琕 廪 癝 癛 䈂 幷 并 㓈 竝 並 𠊧 鮩 靐 鈵 病 棅 栤 摒 寎 傡 倂 併 䗒 䴵 䓑 稟 柄 禀 鞞 饼 餠 餅 陃 鉼 邴 蛃 苪 窉 秉 眪 炳 昺 昞 抦 怲 偋 丙 䋑 㨀 冰 梹 絣 栟 氷 掤 冫 兵 仌 bo 磻 濼 艴 菔 茀 彂 簿 蔔 啵 疈 㖕 簸 繴 檗 譒 蘗 擘 挀 孹 駊 跛 蚾 箥 㧳 䪬 踣 桲 膊 猼 泊 㱟 䫊 泺 䊿 㩭 豰 䬪 䒄 㗘 䞳 䍨 䢪 栢 㝿 饽 誖 薄 伯 鲌 鮊 鈸 鹁 鵓 髆 驳 駮 駁 馞 馎 餺 镈 铂 鑮 鎛 鋍 鉑 郣 踄 謈 襮 襏 袯 葧 苩 艊 舶 脖 胉 糪 簙 箔 礴 礡 瓝 犻 牔 煿 渤 浡 欂 敀 搏 挬 懪 愽 帛 嶏 壆 嚗 博 勃 僰 侼 亳 䶈 䰊 䯋 䮂 䮀 䭯 䭦 䪇 䥬 䢌 䟛 䙏 䗚 䑈 䍸 䂍 㹀 㶿 㴾 㬧 㬍 㪍 㩧 㟑 袚 撥 拨 播 餑 波 剥 剝 鲅 鮁 鱍 髉 驋 钵 鉢 蹳 菠 缽 碆 砵 盋 癶 玻 柭 嶓 哱 bu 埔 誧 纀 轐 擈 扑 瓿 鈈 卩 惚 部 蔀 鮬 䍌 不 䬏 䳝 䴝 䴺 鈽 簿 餢 钸 钚 郶 荹 篰 歩 歨 步 捗 悑 怖 布 埠 埗 咘 吥 佈 䝵 䑰 䏽 䊇 㾟 㻉 㳍 㚴 㘵 㨐 䒈 鳪 補 补 捕 哺 卟 卜 䪔 䪁 䋠 䀯 㙛 醭 鵏 餔 逋 晡 庯 峬 堡 ca 䟃 囃 䵽 礤 擦 嚓 cai 蔡 菜 縩 寀 埰 䰂 䌨 踩 采 䐆 跴 綵 睬 棌 採 彩 婇 倸 䣋 䌽 㥒 犲 财 財 裁 纔 溨 材 才 䴭 㒲 猜 can 掺 穇 鰺 淺 㽩 薒 粲 璨 燦 灿 澯 䛹 㻮 㣓 㛑 䬫 㘔 㜗 黲 黪 朁 憯 慘 惨 䅟 㿊 㦧 蚕 䑶 㱚 䗞 䳻 㥇 䫮 蠺 蠶 蝅 殘 残 慚 慙 惭 嬱 嬠 䣟 䝳 䙁 䘉 䗝 䏼 䍼 㺑 㨻 餐 飡 蓡 参 參 叄 叅 骖 驂 謲 湌 喰 傪 cang 匨 賶 䢢 䅮 藏 鑶 㶓 㵴 鸧 鶬 傖 伧 蒼 苍 螥 艙 舱 滄 沧 嵢 凔 倉 仺 仓 cao 傮 慅 䒃 襙 肏 草 艸 騲 懆 愺 䒑 㯥 槽 䏆 漕 鏪 褿 螬 蓸 艚 曺 曹 嶆 嘈 䐬 䄚 㜖 鄵 操 糙 撡 ce 萴 荝 溭 側 侧 㥽 䊂 粣 筴 䇲 䔴 頙 遪 蓛 萗 茦 箣 筞 策 笧 矠 畟 測 测 敇 拺 憡 惻 恻 廁 嫧 厠 厕 册 冊 䜺 䈟 㩍 㨲 cen 䯔 䨙 涔 䅾 㻸 梣 䤁 笒 橬 岑 埁 䲋 䃡 㞥 梫 嵾 参 參 叄 ceng 繒 缯 蹭 㣒 鄫 曾 竲 碀 嶒 層 层 䉕 䁬 㬝 曽 cha 痄 扱 荖 苴 擑 茬 㢎 㛳 剎 刹 詫 䡨 差 衩 诧 訍 紁 汊 岔 姹 奼 侘 䟕 䓭 䒲 䊬 㤞 㣾 䰈 镲 鑔 蹅 䆛 碴 査 查 檫 㫅 㪯 䁟 䲦 䑘 䕓 𦉆 槎 鍤 锸 詧 茶 秅 搽 嵖 察 垞 䶪 䤩 㢒 㢉 挿 扠 靫 杈 叉 馇 餷 銟 艖 臿 肞 疀 揷 插 嫅 嗏 偛 chai 茈 齜 瘥 袃 蠆 虿 囆 䘍 㳗 茝 柴 䓱 豺 祡 喍 儕 侪 㾹 㑪 釵 拆 钗 芆 差 犲 chan 颤 顫 覘 觇 掺 嘽 啴 蟺 禅 摻 苫 脠 襝 螹 掸 單 单 㙴 䀡 㵌 䠨 𤮭 韂 羼 硟 懺 懴 忏 儳 䱿 䪜 㬄 骣 驏 㹌 㹽 䤘 燀 䵐 䴼 阐 闡 閳 铲 鏟 谄 讇 譂 諂 蕆 蒇 繟 簅 産 產 灛 滻 浐 旵 摌 幝 嵼 囅 剷 剗 刬 冁 产 丳 䩶 䥀 䑎 䐮 䊲 㯆 㦃 㢟 躔 䧯 鋋 儃 㺥 禪 蟬 䡪 㙻 澶 䜛 孱 馋 饞 镵 鑱 酁 鄽 谗 讒 誗 蟾 蝉 艬 缠 纒 纏 繵 緾 磛 獑 煘 瀺 瀍 潺 潹 湹 毚 欃 棎 廛 巉 嬋 婵 嚵 劖 僝 䤫 䣑 䡲 䂁 㸥 㶣 㢆 㔆 惉 鉆 幨 鋓 辿 襜 裧 袩 梴 攙 搀 chang 脹 瑒 玚 𢠵 戃 闛 倡 鬯 韔 誯 畼 畅 焻 暢 悵 怅 唱 䩨 㫤 惝 䕋 厂 昶 鋹 氅 敞 廠 厰 僘 䠀 㙊 长 長 仧 㦂 裳 塲 場 场 鲿 鱨 镸 鏛 鋿 萇 苌 膓 腸 肠 甞 瓺 瑺 徜 常 尝 嫦 嚐 嘗 兏 償 偿 䯴 䠆 䗅 閶 鼚 鲳 鯧 阊 锠 錩 裮 菖 琩 猖 淐 晿 昌 娼 倀 伥 chao 謅 焯 縐 朝 禉 勦 剿 趠 繛 觘 耖 仯 仦 㷅 麨 眧 煼 炒 巐 吵 䏚 䎐 㶤 鼌 鼂 謿 嘲 䬤 䄻 樔 鄛 轈 窲 潮 晁 巣 巢 䰫 鈔 钞 訬 超 罺 欩 抄 怊 弨 che 詀 䜠 辙 轍 䧪 䑲 㱌 䨁 䛸 㵃 㥉 㔭 䁤 屮 迠 聅 硩 瞮 爡 烲 澈 撤 掣 徹 彻 坼 勶 䚢 䒆 㿭 㾝 㯙 㬚 䋲 㨋 䰩 㵔 撦 扯 偖 䞣 车 車 蛼 莗 硨 砗 唓 俥 伡 chen 桭 嗔 抻 瀋 胂 肜 綝 稱 趁 櫬 㧱 讖 龀 齔 齓 趂 谶 襯 衬 藽 疢 榇 夦 嚫 儭 儬 䞋 鍖 䫖 捵 硶 磣 踸 趻 贂 祳 碜 墋 陳 陈 迧 沈 諶 訦 煁 䢈 軙 䢻 䟢 䚘 䜟 麎 鷐 霃 鈂 辰 谌 螴 薼 蔯 莐 莀 茞 臣 沉 樄 曟 晨 敐 愖 忱 屒 尘 宸 塵 䤟 䣅 䢅 䒞 䆣 㽸 㴴 㲀 㫳 㕴 縝 棽 郴 賝 謓 諃 瞋 琛 cheng 撜 梬 郢 樘 搶 抢 柽 鐺 铛 㐼 䀕 秤 牚 靗 逞 骋 騁 睈 悜 徎 庱 塣 侱 䔲 䫆 承 脀 湞 浈 䧕 䗊 㞼 䇸 椉 乘 乗 㨃 澄 裎 橙 騬 铖 鋮 酲 郕 诚 誠 虰 荿 脭 絾 筬 窚 程 珹 珵 瀓 澂 洆 棖 枨 揨 掁 挰 成 懲 憕 惩 峸 宬 娍 塖 塍 堘 埕 城 呈 丞 䮪 䆸 䆵 䆑 䄇 䁎 㼩 㲂 瞠 憆 稱 称 噌 饓 頳 阷 鏿 赬 赪 蟶 蛏 緽 竀 穪 琤 爯 浾 泟 檉 橕 棦 撑 撐 埥 偁 䞓 chi 迣 胵 胝 鵄 扡 胣 杝 謻 糦 翨 呞 祇 芪 紕 驪 攡 鵣 勑 瘈 哆 䇼 眙 踅 饎 飭 㞿 㒆 跮 䗖 㔑 䮻 㓼 杘 𤆍 鷘 鶒 饬 銐 鉓 遫 趩 赤 觢 翤 翅 翄 瘛 痸 痓 熾 烾 炽 灻 淔 斥 敕 抶 懘 憏 慗 恜 彳 啻 叱 勅 傺 侙 乿 䳵 䰡 䤲 䠠 䟷 㽚 㡿 拸 䑛 豉 恀 䜻 䜵 㳏 㶴 袳 㟂 㱀 㘜 誃 尺 搋 齿 齒 鉹 褫 裭 蚇 耻 粎 歯 欼 恥 姼 垑 呎 叺 侈 䊼 㢋 㢁 遲 遟 迟 泜 池 㙜 䈕 弛 䶵 趍 䶔 箈 䐤 䔟 䛂 驰 馳 遅 踟 貾 謘 蚳 荎 茌 耛 篪 箎 筂 竾 汦 歭 持 徲 徥 彽 岻 墀 倁 䮈 䪧 䞾 䜄 䙙 㮛 㢮 㞴 㓾 鴟 郗 黐 摛 喫 吃 骴 齝 魑 誺 訵 螭 蚩 絺 笞 瞝 眵 癡 痴 瓻 欫 彲 彨 媸 噄 嗤 哧 chong 衶 爞 罿 𣀒 铳 銃 揰 㧤 𠖥 寵 宠 埫 㹐 虫 䳯 褈 隀 蟲 蝩 痋 漴 崈 崇 䖝 䌬 㓽 舂 𧘂 衝 翀 𢥞 蹖 茺 珫 浺 沖 摏 憧 憃 忡 徸 嘃 冲 充 chou 謅 盩 婤 牰 鯈 鈕 燾 簉 臭 臰 殠 䔏 杻 魗 醜 矁 瞅 杽 吜 偢 侴 丒 丑 䪮 詶 薵 稠 籌 䛬 綢 绸 仇 䥒 䇺 幬 帱 䊭 裯 紬 䌷 雠 雔 醻 酬 酧 躊 踌 讐 讎 菗 絒 筹 皗 疇 畴 燽 椆 栦 懤 愁 惆 嬦 嚋 儔 俦 䲖 䓓 䌧 㿧 㵞 㦞 㤽 㐜 怞 瘳 𢭆 霌 篘 犫 犨 搊 抽 chu 绌 麆 禇 槒 触 䙕 絀 畜 滀 䧁 俶 䜴 竐 䦌 㤘 㗰 䮞 處 处 搐 黜 閦 鄐 遚 踀 豖 觸 荲 臅 竌 矗 琡 泏 歜 欪 斶 斣 敊 拀 怵 儊 傗 亍 䟣 㤕 㙇 㔘 䙘 楮 褚 㹼 処 儲 储 齼 齭 礎 础 濋 檚 楚 椘 杵 憷 䖏 䊰 除 䎝 蕏 蜍 㼥 鉏 鋤 雛 䎤 躇 䠂 𦷝 鶵 雏 锄 躕 蹰 趎 藸 蒭 蒢 芻 耡 耝 篨 犓 滁 櫥 櫉 橱 曯 廚 幮 厨 刍 䠧 䟞 䅳 㶆 㡡 㕑 㕏 樗 齣 貙 岀 初 出 chua 欻 歘 䫄 chuai 嘬 腄 䦷 䦤 踹 䦟 揣 㪜 膗 㪓 chuan 舡 篅 玔 串 钏 釧 賗 汌 荈 堾 舛 腨 喘 僢 㱛 傳 传 伝 圌 歂 遄 輲 諯 船 舩 椽 暷 䁣 㼷 㯌 巛 穿 瑏 氚 川 chuang 磢 䎫 創 剙 剏 刱 创 獊 愴 怆 㵂 闯 闖 漺 摤 䇬 幢 䚒 䭚 橦 疒 牀 床 噇 䡴 䃥 㡖 戧 窗 窓 牕 牎 䆫 窻 瘡 疮 摐 刅 chui 桘 郵 魋 龡 䞼 槌 埀 㥨 㝽 䳠 腄 棰 㓃 篅 顀 陲 锤 鎚 錘 菙 箠 湷 搥 捶 垂 倕 䍋 䄲 㩾 吹 炊 chun 肫 膞 橁 鰆 輇 錞 䞐 踳 蠢 萶 箺 睶 惷 偆 䦮 䐏 䏛 䄝 㿤 㖺 淳 湻 䏝 㵮 鹑 鶉 漘 純 纯 㝄 鯙 陙 醕 醇 蓴 蒓 莼 脣 滣 浱 憌 唇 䫃 䥎 䣩 䣨 䔚 䓐 䐇 㸪 㝇 輴 杶 萅 春 旾 鶞 膥 櫄 椿 暙 媋 堾 chuo 鏃 齱 焯 踔 婼 踱 㲋 畷 腏 䋘 醊 䍳 䄪 擉 趠 绰 繛 綽 龊 齪 鑡 酫 逴 辶 辵 辍 輟 諁 磭 珿 涰 歠 惙 婥 娖 嚽 啜 䮕 䓎 䇍 䆯 䃗 䂐 㚟 犳 齹 鎈 戳 ci 訾 茈 粢 秶 鹚 鷀 鶿 茲 螅 赐 郪 嵳 㢀 䦻 賜 㹂 刾 刺 䰍 䓧 螆 蛓 莿 絘 次 朿 佽 䳐 䯸 䗹 㩞 㡹 㞖 玼 跐 紪 皉 泚 此 佌 㠿 餈 糍 祠 薺 䆅 㓨 䧳 雌 飺 辭 辤 辞 辝 词 詞 茨 礠 磁 甆 瓷 珁 濨 柌 慈 嬨 垐 䳄 䲿 䭣 䨏 䛐 䖪 䈘 䂣 㤵 㘹 㘂 疵 趑 庛 薋 髊 趀 赼 蠀 偨 cong 縱 窼 藂 謥 欉 從 从 漎 淙 錝 賩 賨 誴 琮 爜 灇 潀 慒 悰 徖 従 孮 婃 叢 丛 䳷 䕺 䉘 㼻 憁 緫 樅 枞 鏓 樬 樷 葱 囱 囪 骢 驄 騘 鏦 鍯 鍐 蟌 蔥 蓯 苁 聰 聪 聦 聡 繱 篵 瞛 璁 瑽 燪 焧 漗 棇 暰 悤 怱 忩 匆 cou 藪 趨 楱 辏 輳 腠 湊 凑 傶 㫶 cu 酢 蹵 縐 皶 趨 顣 蹴 䙯 䥄 䠞 槭 䬨 䠓 踧 䥘 蔟 簇 鼀 醋 蹙 趗 脨 縬 瘯 瘄 猝 殧 梀 憱 塶 噈 促 䟟 䛤 䎌 䃚 㰗 㗤 豠 殂 徂 䢐 䓚 麤 麄 麁 觕 粗 cuan 濽 㵀 镩 鑹 竄 簒 篡 窜 爨 熶 殩 㸑 劗 㭫 櫕 巑 䰖 䆘 㠝 鋑 躥 蹿 汆 攛 撺 䞼 cui 踤 崪 崒 缞 橇 㷪 紣 淬 䃀 粹 䂱 毳 㥞 㧘 顇 萃 臎 膵 膬 脺 脆 脃 翠 翆 綷 粋 竁 瘁 疩 琗 焠 悴 忰 啛 啐 倅 伜 䆊 䄟 㳃 㱖 㯜 㯔 㝮 䊫 皠 趡 璀 漼 䧽 㷃 㵏 慛 凗 縗 摧 鏙 竴 磪 獕 槯 榱 崔 墔 嗺 催 cun 墫 壿 踆 浚 籿 寸 吋 䍎 忖 刌 袸 拵 存 邨 皴 澊 村 cuo 侳 鄼 昔 䟶 齰 齚 措 䐣 䱜 錯 错 锉 銼 逪 蓌 莡 莝 歵 挫 厝 剒 剉 脞 瑳 縒 䂳 䴾 㟇 醝 嵳 嵯 鹾 鹺 虘 蔖 矬 痤 䣜 䠡 㽨 撮 蹉 遳 蒫 磋 睉 搓 摧 㭫 䥘 䰈 da 箚 劄 觰 酇 酂 躂 跶 羍 沓 搨 鎝 瘩 㟷 大 眔 打 䩢 䵣 迖 达 達 韃 䳴 䑽 䐊 畗 繨 答 鞑 靼 鐽 逹 詚 褟 蟽 薘 荙 笪 畣 炟 溚 怛 妲 呾 匒 䃮 㿯 㾑 㯚 㜓 耷 搭 墶 㙮 荅 褡 撘 噠 哒 dai 曃 駘 遝 蝳 釱 遞 递 轪 軑 嘚 蹛 㿃 贷 貸 㫹 㶡 逮 待 汏 𦄂 黱 黛 靆 霴 迨 軩 軚 跢 襶 袋 艜 绐 緿 紿 簤 甙 瑇 玳 瀻 殆 柋 戴 怠 廗 帶 帯 带 帒 岱 埭 叇 代 䒫 䈆 㻖 㯂 㞭 㐲 歹 歺 傣 䚟 䚞 獃 呆 懛 呔 大 dan 覘 訑 唌 禫 黮 贉 餤 蟺 赡 㺗 舕 㵅 钽 鉭 㫜 淡 彈 弹 潬 膻 㱽 䉷 䄷 䨢 瘅 澹 癉 担 鴠 髧 駳 馾 饏 霮 诞 誕 觛 蜑 蛋 萏 腅 窞 癚 疍 狚 沊 氮 柦 暺 旦 憺 憚 惮 弾 帎 嚪 噉 啿 啗 啖 僤 但 䳉 䭛 䩥 䨵 㲷 㡺 㗖 撢 胆 㽎 伔 掸 䱋 䮰 疸 亶 撣 黵 衴 膽 紞 瓭 玬 澸 刐 䉞 䃫 㕪 㔊 酖 噡 眈 單 单 鄲 擔 黕 頕 郸 躭 襌 聸 聃 耽 耼 簞 箪 砃 甔 殫 殚 媅 妉 単 匰 勯 儋 丹 dang 瘍 瑒 玚 偒 逿 蕩 愓 檔 雼 闣 趤 蘯 菪 荡 簜 礑 碭 砀 瞊 盪 瓽 璗 潒 氹 宕 婸 壋 垱 圵 凼 䦒 䑗 黨 攩 䣣 擋 挡 讜 档 谠 譡 灙 欓 党 䣊 當 当 儅 鐺 铛 襠 裆 蟷 艡 簹 筜 璫 珰 澢 嵣 噹 dao 檮 梼 叨 䧂 燾 纛 道 軇 衟 衜 菿 翿 稻 稲 盜 盗 瓙 檤 悼 噵 到 䲽 蹈 導 导 倒 䆃 捯 隯 隝 禱 禂 祷 擣 搗 捣 嶹 嶌 嶋 島 岛 壔 䌦 㿒 㠀 鱽 魛 釖 舠 氘 朷 忉 幍 刂 刀 䣣 㨶 de 墬 地 的 㥁 䙷 徳 得 䙸 嘚 㝵 锝 鍀 淂 惪 恴 德 㯖 㥀 㤫 dei 哋 得 den 參 deng 鐙 蹬 磴 霯 隥 鄧 邓 瞪 櫈 嶝 墱 凳 僜 䮴 䠬 等 朩 戥 䒭 镫 登 豋 覴 簦 竳 璒 燈 灯 嬁 噔 di 疐 胝 滺 浟 苐 揥 鬄 髢 籊 蹏 適 埅 嵽 莜 藋 䑭 䏑 䀸 䧝 棣 弟 䶍 䞶 谛 諦 珶 䱱 睇 遰 杕 墆 䩚 奃 哋 墬 地 釱 遞 递 轪 軑 踶 馰 鉪 逓 螮 蝃 虳 蔕 蒂 腣 肑 缔 締 第 禘 祶 碲 甋 玓 焍 渧 樀 楴 梊 旳 摕 慸 怟 帝 嶳 娣 埊 坔 啲 僀 偙 䩘 䟡 䑯 䀿 㼵 㦅 㢩 䱃 砥 䂡 㡳 詆 氐 底 骶 阺 邸 軧 诋 觝 菧 茋 苖 聜 牴 柢 掋 拞 抵 弤 埞 坘 呧 䣌 䢑 䍕 㭽 㪆 蹢 䊮 翟 籴 狄 覿 䮤 㹍 䨀 镝 鏑 鸐 頔 靮 迪 豴 觌 藡 蔐 蔋 荻 糴 篴 笛 潪 滌 涤 梑 敵 敌 廸 嫡 嚁 嘀 啇 唙 仢 䵠 䴞 䯼 䨤 㰅 㣙 隄 堤 菂 羝 鍉 鞮 趆 袛 磾 眡 滴 墑 低 仾 的 䨢 踧 赿 坻 dia 嗲 dian 蒧 驔 阽 㥆 钿 鈿 佃 䧃 甸 痁 㵤 㼭 㝪 玷 靛 電 蜔 簟 磹 癜 电 琔 澱 淀 殿 橂 扂 惦 店 婝 奠 壂 墊 垫 坫 㶘 㞟 㓠 點 㚲 踮 蕇 碘 痶 琠 点 敟 婰 奌 嚸 典 䓦 䍄 㸃 䟍 滇 颠 顛 攧 齻 顚 蹎 癲 癫 瘨 槙 槇 敁 掂 巔 巓 巅 嵮 厧 傎 䩚 diao 踔 盄 銚 𨍳 軺 蜩 錭 矵 釕 莜 䂽 调 調 䂪 蓧 䠼 藋 魡 铞 钓 鑃 鋽 銱 釣 訋 竨 窵 窎 瘹 掉 弔 吊 伄 䵲 䔙 㪕 㒛 㹿 钌 屌 䉆 鳭 鼦 鵰 鲷 鯛 鮉 雕 貂 蛁 虭 碉 瞗 琱 汈 殦 扚 彫 奝 叼 刁 凋 䄷 䄪 die 柣 褶 殜 楪 渫 褻 咥 鐵 鳎 鰨 揲 啑 耋 耊 惵 䞇 䘭 㬪 㫼 喋 㩹 㑙 昳 㲲 㷸 諜 䪥 跕 蝶 䲀 䠟 碟 鰈 㭯 䞕 㻡 嵽 𢶣 鲽 镻 迭 蹀 趃 谍 詄 褺 褋 蜨 苵 艓 臷 胅 聑 绖 絰 眰 眣 疊 疉 畳 瓞 牒 牃 氎 曡 挕 戜 恎 峌 堞 垤 叠 䴑 䳀 䮢 䏲 㲳 㩸 㦶 㥈 跌 爹 攧 墆 ding 鋌 汀 艼 耵 饤 飣 顁 锭 錠 订 訂 腚 磸 碠 碇 矴 椗 忊 定 娗 啶 㝎 鼑 鼎 鐤 濎 㼗 酊 𪔂 𩠑 顶 頂 薡 檙 嵿 㴿 㫀 婈 丁 疔 釘 钉 盯 靪 玎 庰 帄 奵 叮 仃 㝪 diu 铥 銩 丢 丟 dong 湩 衕 峝 峒 硐 蕫 諌 㜱 洞 垌 䅍 駧 霘 腖 胴 胨 眮 棟 栋 挏 戙 動 动 凍 冻 働 䞒 䍶 㼯 㢥 㗢 㓊 㑈 董 箽 懂 嬞 墥 䵔 䂢 㨂 㖦 鼕 蝀 涷 崠 鸫 鶇 鯟 菄 苳 笗 氭 氡 東 昸 崬 岽 娻 埬 咚 冬 倲 东 dou 窬 讀 瀆 渎 都 都 逗 䛠 㷆 竇 鬭 鬬 鬪 鬦 鬥 饾 餖 闘 閗 鋀 豆 荳 脰 窦 痘 浢 毭 梪 䬦 䕆 䄈 㢄 㛒 枓 䕱 斗 陡 阧 钭 鈄 蚪 枡 敨 抖 唞 㪷 㞳 郖 蔸 篼 橷 唗 吺 兠 兜 㨮 du 鍺 斁 橐 襡 簬 閬 䲧 簵 䄍 度 肚 靯 镀 鍍 蠹 蠧 螙 荰 秺 渡 殬 杜 妬 妒 喥 䟻 䅊 裻 錖 赌 賭 覩 篤 笃 睹 琽 暏 帾 堵 䐗 䈞 䀾 碡 䢱 䙱 读 讀 瀆 渎 蝳 毒 黷 黩 髑 騳 韥 韣 韇 鑟 贕 豄 讟 読 皾 瓄 獨 独 犢 犊 牘 牍 涜 殰 櫝 椟 嬻 匵 凟 儥 䮷 䫳 䪅 䓯 㾄 㸿 㱩 阇 闍 都 都 醏 督 嘟 厾 竇 㹍 纛 duan 锻 鍛 躖 葮 腶 缎 緞 籪 簖 碫 瑖 煅 毈 段 椴 斷 断 塅 䠪 㱭 㫁 短 剬 鍴 褍 端 媏 偳 dui 濻 㠚 䨺 兑 䯟 䨴 隊 队 䔪 䇤 㵽 鐓 碓 錞 镦 鐜 轛 譈 薱 綐 祋 瀩 濧 懟 憞 憝 怼 對 対 对 兌 兊 䬽 䬈 䇏 㳔 㬣 㟋 㙂 陮 𠂤 頧 磓 痽 嵟 塠 堆 垖 dun 腞 炖 遁 沌 囤 盾 燉 顿 頓 扽 鶨 钝 鈍 遯 逇 踲 砘 潡 庉 崸 伅 䤜 㬿 盹 𣎴 躉 趸 蹲 敦 驐 蹾 蜳 礅 犜 撴 撉 惇 弴 墪 墩 噸 吨 鐓 duo 鍺 柂 媠 軃 橢 馱 沱 驮 沲 茤 炧 䙟 柁 舵 㧷 䍴 䙃 墯 墮 堕 㻧 桗 踱 𥞛 𢜬 饳 飿 陏 陊 跺 跥 炨 柮 惰 嶞 尮 剁 刴 䩔 䤻 䑨 䅜 锗 㔍 䩣 㻔 㖼 䠤 䙤 鬌 躲 躱 趓 缍 綞 痑 朶 朵 挆 挅 憜 奲 埵 垜 垛 嚲 哚 亸 䯬 䫂 䤪 䒳 㥩 㛊 㛆 㙐 襗 莌 㣞 裰 掇 鮵 铎 鐸 鈬 痥 毲 椯 敪 敠 敚 敓 悳 奪 夺 剫 凙 䐾 哆 崜 夛 多 嚉 咄 剟 錞 䄍 點 杕 e 蘁 锇 鋨 玀 疴 鈳 齃 䛖 㡋 䳬 閼 阏 惡 恶 䓊 䑥 䞩 䆓 䔾 㟧 嶭 詻 㕎 㱦 胺 堨 阸 阨 戹 誒 齶 鹗 鶚 鳄 鱷 鰐 魥 饿 餩 餓 颚 顎 頞 锷 鑩 鍔 鄂 遏 遌 轭 軶 軛 貖 豟 谔 讍 諤 覨 蝁 蚅 蕚 萼 苊 腭 硆 砐 琧 湂 櫮 搹 搤 扼 愕 悪 崿 岋 堮 堊 垩 圔 噩 咹 咢 呝 呃 厄 卾 僫 偔 䫷 䣞 䝈 䙳 䑪 㷈 㮙 㩵 㧖 㦍 㠋 㗁 㖾 㔩 㓵 㼢 噁 枙 囮 蛾 硪 㼂 㼰 哦 騀 鹅 鵞 鵝 魤 额 額 頟 隲 鈋 迗 讹 譌 誐 訛 莪 磀 睋 皒 珴 涐 峩 峨 娥 吪 俄 䳘 䳗 䱮 䩹 䖸 䕏 䄉 婐 钶 痾 峉 屙 婀 娿 妿 妸 阿 ei 誒 诶 en 䊐 摁 䭡 䭓 䬶 䅰 煾 奀 蒽 恩 eng 鞥 er 腝 臑 儞 渳 眲 佴 衈 毦 铒 贰 貳 貮 誀 樲 弐 弍 咡 刵 二 䣵 䏪 䎶 㛅 㒃 耳 㚷 鉺 駬 饵 餌 邇 迩 薾 珥 爾 洱 栮 峏 尔 尓 尒 䌺 䋙 㢽 㮕 䎟 檽 䮘 而 耏 㜨 兒 儿 鸸 鴯 鲕 鮞 髵 隭 陑 轜 輀 袻 荋 胹 聏 洏 栭 唲 児 侕 䎠 䋩 㧫 㖇 fa 䒥 蕟 髮 髪 琺 珐 㛲 灋 法 佱 䂲 茷 砝 阀 閥 藅 罸 罰 罚 筏 疺 栰 姂 垡 伐 乏 䣹 䇅 㘺 㕹 发 發 彂 発 瞂 沷 橃 傠 fan 袢 蟠 潘 畨 鄤 仮 觙 犿 㽹 㼝 㝃 䐪 汎 䉊 泛 氾 軬 飯 饭 飰 飯 軓 贩 販 訉 范 範 笵 盕 畈 犯 滼 梵 嬎 奿 䣲 䒦 㶗 㴀 㤆 㕨 䒠 反 魬 返 軡 瓪 䛀 繁 緐 樊 䋣 燔 䀟 䊩 䡊 釩 颿 蕃 蹯 藩 笲 憣 鷭 钒 鐇 襎 蠜 蘩 薠 舧 膰 羳 籵 礬 矾 璠 煩 烦 瀿 瀪 橎 棥 柉 忛 墦 勫 凣 凢 凡 䮳 䭵 䫶 䪤 䪛 䌓 䋦 䉒 䀀 㺕 㸋 㠶 番 繙 籓 鱕 飜 轓 翻 杋 旛 旙 幡 帆 嬏 噃 僠 fang 放 趽 㯐 倣 仿 㑂 䦈 䢍 紡 纺 鶭 髣 访 訪 舫 眆 瓬 昘 昉 旊 䲱 㧍 㕫 鳑 鰟 房 埅 妨 鲂 魴 防 肪 㤃 方 邡 坊 枋 鴋 钫 鈁 蚄 芳 牥 淓 汸 匚 䉊 fei 胏 陫 郿 髴 紼 祓 肺 芾 砩 沸 痱 疿 费 費 蟦 杮 鼣 靅 镄 鐨 胇 癈 狒 濷 櫠 曊 昲 廢 廃 废 屝 吠 厞 剕 俷 䰁 䤵 䠊 䛍 䚨 䕠 䑔 䉬 䆏 㵒 㭭 㩌 㔗 朏 斐 匪 餥 诽 誹 蕜 翡 篚 榧 棐 悱 奜 䨾 䨽 䕁 㥱 肥 蜰 萉 腓 淝 䈈 妃 啡 鯡 蜚 菲 非 鲱 騛 騑 馡 飞 飝 飛 靟 霏 裶 绯 緋 猆 渄 扉 婓 䀟 蕟 fen 歕 粪 份 鲼 鱝 膹 糞 瀵 憤 愤 忿 奮 奋 坋 僨 偾 㿎 㮥 㖹 黺 羵 粉 㥹 汾 䯨 濆 焚 棼 棻 獖 燌 鐼 肦 鼢 鼖 黂 魵 馩 馚 轒 豶 豮 蚡 蚠 蕡 蒶 羒 秎 炃 橨 梤 枌 弅 幩 妢 墳 坟 坆 䴅 䩿 㸮 㷊 砏 分 隫 芬 𦐈 鳻 饙 餴 雰 鈖 酚 訜 衯 翂 纷 紛 燓 氛 朆 昐 帉 岎 吩 兝 䢍 燔 䀟 feng 豊 㡝 鴌 鳳 鳯 赗 賵 甮 煈 焨 湗 奉 凤 俸 諷 唪 覂 䟪 馮 冯 逢 夆 䏎 缝 縫 渢 沨 艂 綘 漨 浲 摓 堸 䩼 䙜 㵯 㦀 葑 风 風 讽 凨 麷 飌 靊 锋 鏠 鋒 酆 鄷 豐 蠭 蜂 蘴 莑 篈 碸 砜 盽 瘋 疯 猦 犎 熢 烽 灃 沣 檒 楓 桻 枫 捀 崶 峰 峯 封 寷 妦 堼 凮 凬 僼 偑 仹 丰 汎 氾 fo 佛 坲 仏 fou 復 芣 竎 椱 否 缶 鴀 雬 缻 缹 殕 裦 紑 哹 剻 䳕 fu 軵 襆 纀 仆 抙 錇 掊 宓 䘄 阝 附 㵗 峊 䧞 䎅 䂤 父 胕 榑 傅 復 馥 𧌓 𦱖 鳆 鲋 鰒 鮒 驸 駙 陚 阜 鍢 鍑 輹 赴 赙 赋 负 賻 賦 負 讣 詂 訃 覆 褔 複 袝 蝮 蝜 蛗 蚹 蕧 萯 腹 緮 紨 稪 祔 富 嬔 媍 婦 婏 妇 复 坿 圑 咐 副 冨 偩 付 䯱 䮛 䭸 䨱 䦣 䠵 䟔 䞸 䞯 䞜 䝾 䘀 䒇 㾈 㽬 㳇 㬼 㤱 㚆 㙏 頫 㕮 甫 莆 脯 鯆 䯽 䗄 俛 撫 抚 䓛 䫝 黼 鬴 釡 釜 郙 辅 輔 蜅 蚥 腑 腐 簠 秿 盙 焤 滏 暊 斧 捬 拊 弣 府 嘸 呒 俯 俌 乶 䫍 䩉 䌗 䋨 㓡 苻 扶 涪 䪙 䘠 嚩 㜑 莩 䃽 䍖 服 黻 福 洑 䔰 䋹 㤔 㠅 䡍 罦 罘 粰 枎 孚 芣 髴 紼 祓 艴 菔 茀 拂 絥 福 鶝 鵩 鴔 鳬 鳧 鮄 颫 韨 韍 鉜 鉘 郛 辐 輻 踾 諨 袱 蝠 蜉 蚨 虙 葍 茯 芙 艀 翇 缚 绋 绂 縛 綍 紱 箙 笰 符 癁 畐 畉 甶 琈 玸 烰 炥 澓 浮 氟 棴 桴 栿 柫 払 怫 彿 弗 幞 幅 帗 巿 岪 垘 咈 匐 刜 凫 冹 俘 伏 乀 䵾 䵗 䨗 䟮 䞞 䕎 䒀 䑧 䌿 㫙 㪄 㟊 㚕 柎 鈇 稃 泭 夫 枹 麸 麱 麬 麩 鳺 鄜 邞 跗 趺 豧 衭 荴 膚 肤 綒 糐 筟 砆 玞 旉 敷 懯 怤 尃 孵 姇 妋 呋 伕 佛 㡝 芾 砩 㷆 畗 ga 旮 骱 钆 咖 噶 尬 𠁥 玍 尕 釓 錷 尜 嘠 嘎 gai 閡 阂 胲 骸 㮣 溉 摡 䏗 㧉 㕢 概 蓋 葢 盖 賌 𩕭 钙 鈣 瓂 漑 槪 槩 戤 匄 匃 乢 丐 絠 改 忋 䪱 隑 陔 郂 赅 賅 豥 该 該 荄 絯 祴 畡 晐 峐 姟 垓 侅 𠁥 gan 漧 酐 扞 釬 旰 幹 贛 赣 簳 榦 骭 詌 绀 紺 淦 涻 汵 檊 凎 倝 䲺 䯎 赶 㺂 澉 擀 䔈 贑 灨 鳡 鱤 趕 衦 稈 秆 盰 皯 橄 桿 敢 感 䵟 䤗 䇞 䃭 仠 柑 乹 鳱 泔 虷 干 竿 矸 杆 迀 蜬 苷 芉 肝 粓 筸 疳 甘 玕 攼 忓 嵅 尷 尶 尴 尲 坩 凲 亁 gang 矼 阬 摃 頏 颃 溝 戇 戆 戅 筻 焵 槓 港 崗 岗 䴚 㽘 㟵 㟠 缸 笐 釭 疘 钢 鋼 杠 舡 鎠 肛 罡 罓 罁 纲 綱 碙 犅 牨 棡 掆 岡 堽 堈 剛 刚 冮 冈 gao 睪 稁 槀 桕 镐 鎬 皜 蒿 笴 鯌 锆 鋯 郜 诰 誥 禞 祰 祮 煰 告 吿 叝 藳 槁 暠 䗣 藁 菒 缟 縞 筶 稿 稾 檺 杲 搞 夰 㾸 㚖 㚏 滜 睾 皋 高 膏 𦤎 鼛 鷎 髙 餻 臯 羙 羔 糕 篙 皐 櫜 橰 槹 槔 䨢 ge 閘 仡 硌 袼 嶱 髂 鉀 鞈 郃 頜 闔 滆 紇 纥 颌 鉿 扢 箇 個 个 鉻 铬 虼 嗰 各 䧄 擖 哿 笴 舸 䐙 隔 㦴 㪾 镉 鎘 䕻 㷴 䗘 㝓 䫦 㗆 䘁 裓 䛋 革 䩐 䢔 阖 閤 槅 敋 㨰 䨣 茖 葛 格 噶 齃 鰪 鮯 骼 韚 韐 鞷 阁 閣 轕 輵 諽 觡 蛒 臵 膈 獦 搿 挌 愅 塥 嗝 呄 匌 佮 䪺 䪂 䛿 䈓 䆟 㵧 㠷 疙 犵 咯 鴚 麧 胳 擱 搁 𪃿 鸽 鴿 鎶 謌 肐 牱 牫 牁 滒 渮 歌 戨 戓 戈 圪 哥 割 蓋 葢 砝 gei 胲 給 给 gen 哏 茛 亙 亘 艮 㮓 㫔 䫀 跟 根 剆 刯 geng 暅 頸 炔 更 堩 䱴 䱭 䱎 䱍 綆 鲠 鯁 骾 郠 莄 耿 绠 梗 挭 峺 埂 哽 䌄 䋁 㾘 羹 羮 粳 稉 秔 緪 絚 鹒 鶊 赓 賡 菮 耕 縆 絙 畊 浭 搄 揯 庚 亙 䨣 gong 輁 澒 嗊 唝 䇨 䢚 共 贡 貢 羾 㯯 㔶 㓋 蛬 㤨 穬 廾 鞏 鋛 銾 珙 汞 栱 拲 拱 巩 䡗 䂬 㼦 㺬 㭟 㫒 㧬 蚣 篢 魟 供 龚 龔 龏 躳 躬 觵 觥 肱 糼 碽 玜 杛 攻 愩 恭 弓 幊 工 宮 宫 塨 厷 匑 功 公 釭 疘 贛 赣 䔈 贑 灨 䱋 gou 痀 軥 鴝 鷇 佝 枸 耩 逅 穀 㨌 䞀 詬 骺 冓 雊 遘 购 購 诟 訽 觏 覯 煹 構 撀 搆 彀 媾 姤 夠 够 垢 坸 傋 䝭 䃓 㳶 㝤 㝅 㜌 㗕 茩 苟 豿 蚼 耉 耈 耇 笱 玽 狗 岣 㺃 鉤 构 勾 溝 韝 鞲 钩 鈎 褠 芶 缑 緱 篝 沟 gu 骰 賈 贾 瓠 抇 鵠 鹄 搰 胍 梏 㧽 凅 榾 故 痼 鶮 鲴 鯝 顾 顧 頋 雇 锢 錮 稒 祻 牿 棝 怘 崮 崓 堌 固 僱 䶜 䓢 䍛 㽽 谷 汩 䀰 䀇 䀜 㼋 嘏 䊺 䵻 䡩 䍍 鈷 骨 轂 蓇 穀 扢 鼔 鼓 馉 餶 诂 詁 蠱 蛌 蛊 薣 臌 脵 股 羖 罟 縎 糓 瞽 盬 皼 皷 狜 牯 焸 瀔 濲 淈 毂 榖 杚 愲 尳 唃 唂 古 䐨 䅽 䀦 㾶 㯏 㚉 㒴 鶻 鹘 䮩 䜼 呱 估 蛄 沽 钴 鸪 鴣 鮕 鈲 酤 辜 軱 觚 菰 菇 苽 罛 箛 箍 笟 泒 橭 柧 孤 嫴 姑 夃 咕 䓛 gua 括 捖 髺 罫 诖 詿 褂 罣 絓 掛 挂 坬 啩 卦 㒷 䈑 寡 叧 剮 剐 冎 蝸 腡 脶 筈 栝 緺 聒 胍 鸹 鴰 騧 颳 頢 銽 踻 趏 葀 瘑 瓜 煱 桰 懖 劀 刮 呱 guai 㷇 旝 㽇 䂯 癐 恠 怪 夬 叏 䊽 㧔 箉 柺 枴 拐 乖 罫 guan 鳏 淪 擐 贯 貫 䌯 䎚 灌 潅 鸛 䙛 鹳 鱹 雚 鑵 鏆 遦 謴 罐 罆 祼 礶 矔 盥 瓘 爟 涫 泴 毌 樌 摜 掼 慣 惯 悺 悹 丱 䝺 䙮 䗰 㴦 㮡 䗆 脘 䪀 䲘 館 鳤 馆 館 錧 輨 舘 管 筦 痯 琯 䩪 䦎 䘾 䏓 関 关 鰥 观 觀 覌 棺 冠 莞 鱞 關 闗 観 蒄 癏 瘝 官 倌 䂯 guang 广 迋 俇 潢 㫛 逛 櫎 桄 臩 臦 獷 犷 廣 広 洸 炛 黆 銧 輄 茪 胱 珖 烡 炗 灮 姯 垙 咣 光 僙 侊 䍍 gui 敮 隗 洼 眭 朹 祈 鐀 瞶 瞆 撌 媿 騩 禬 桧 觖 鳜 趹 撅 繪 廆 炔 匱 匮 䯣 䙆 䖯 㙺 檜 巜 鱖 柜 䍷 䰎 䇈 鱥 鞼 跪 贵 貴 襘 蓕 筀 溎 櫃 桂 暩 昋 攰 嶡 劌 劊 刿 刽 䳏 䠩 䝿 䐴 䌆 㪈 㸵 䣀 㲹 䍯 庪 㔳 䁛 䞈 鬼 陒 轨 軌 诡 詭 觤 蟡 蛫 簋 祪 癸 氿 晷 攱 恑 庋 宄 姽 垝 厬 匭 匦 佹 䤥 䞨 㩻 㨳 㧪 潙 溈 鮭 鲑 窐 歸 归 傀 規 龟 龜 硅 茥 鬹 鬶 闺 閨 郌 邽 规 袿 膭 皈 瓌 璝 瑰 珪 槼 槻 椝 摫 帰 嬀 嫢 媯 妫 圭 亀 䃽 㱦 gun 裷 錕 睔 棍 睴 璭 䵪 㫎 緄 㯻 掍 䜇 䃂 鲧 鯀 鮌 辊 輥 袬 袞 衮 蔉 蓘 绲 磙 滾 滚 丨 䎾 㙥 裩 㔳 䙛 鰥 㨰 guo 蜮 蠃 呙 啯 㳀 過 过 腂 蜾 猓 䙨 錁 果 輠 馃 餜 鐹 裹 菓 綶 粿 淉 槨 椁 惈 䴹 㞅 䤋 馘 䂸 㚍 䐸 㕵 虢 膕 腘 聝 簂 漍 摑 掴 慖 幗 帼 國 圀 国 囻 囶 囯 䬎 䆐 㶁 㖪 蟈 濄 墎 鍋 郭 锅 鈛 蝈 崞 堝 埚 嘓 緺 聒 敋 ha 獬 奤 铪 蛤 鉿 哈 𠀀 hai 咳 還 还 閡 㺔 䇋 㦟 害 𥩲 𠀅 骇 駭 饚 餀 氦 嗐 亥 㧡 㤥 胲 醢 酼 烸 海 颏 頦 骸 孩 䱺 䯐 䠽 㨟 㜾 嗨 咍 㕢 䂤 䍖 han 汉 顉 撖 鈐 嚂 壏 闞 椷 澣 頜 酐 䘶 淊 㽳 漢 㵄 㜦 䐄 䫲 䖔 䌍 㑵 攌 䁔 㲦 汗 馯 浛 颌 扞 釬 鶾 駻 颔 顄 頷 雗 闬 閈 鋎 銲 貋 譀 螒 蜭 蛿 菡 莟 翰 睅 皔 猂 熯 焊 瀚 澏 涆 暵 晥 晘 旱 撼 捍 憾 悍 屽 娨 垾 哻 傼 䧲 䕿 䏷 䎯 㪋 㨔 㢨 㒈 㘕 鬫 㽉 㵎 㙳 蔊 罕 䛞 䓿 䍐 㸁 㘎 厈 豃 浫 喊 䓍 䍑 㺖 㘚 㙈 邯 琀 涵 䮧 韩 韓 鋡 邗 肣 筨 焓 梒 晗 崡 寒 娢 圅 含 凾 函 佄 䶃 䨡 䥁 䤴 䗙 䈄 㼨 㶰 㮀 㟔 㟏 㙔 㖤 歛 酣 唅 甝 頇 鼾 魽 馠 顸 谽 蚶 炶 憨 嫨 䗣 旰 幹 澉 擀 鳱 泔 虷 䏎 䦈 hang 行 筕 绗 絎 桁 鸻 鴴 䴂 䦳 䣈 酐 䟘 汻 吭 杭 沆 頏 颃 魧 迒 貥 蚢 苀 航 斻 䲳 䘕 䀪 㤚 夯 䢚 笐 hao 睪 茠 藃 呺 薧 貉 貈 䯫 耗 皓 薃 號 号 浩 镐 鎬 皜 鰝 颢 顥 鄗 聕 秏 皥 皡 皞 灝 灏 瀥 澔 滈 淏 曍 暭 暤 晧 昦 昊 悎 峼 哠 傐 䬉 䪽 䧚 䝞 䚽 䒵 㵆 㬶 㞻 㝀 㚪 㙱 㘪 郝 好 恏 譹 諕 豪 蠔 籇 獔 獋 獆 濠 毫 椃 壕 嚎 噑 嘷 嗥 勂 儫 䧫 䝥 㬔 㩝 㠙 㕺 蒿 薅 嚆 侾 暠 滜 蚝 he 籺 猲 嚇 欱 轄 鬩 輅 嵑 鉀 饸 餄 藿 喛 鵠 暍 嗃 赫 䵱 䚂 䪚 䓼 䎋 壑 䴳 㷤 㷎 翯 皬 蠚 鶴 鹤 鸖 鶴 靏 靎 隺 贺 賀 袔 碋 癋 爀 熇 煂 焃 俰 佫 䳽 㵑 㬞 㦦 㕰 蝎 郃 䒩 㿣 㭱 䢗 鞨 㮝 翮 蚵 䕣 盍 䳚 鹖 鶡 䞦 㔠 和 咊 耠 核 荷 龢 㕡 褐 何 㥺 涸 貉 貈 頜 合 闔 滆 紇 菏 纥 閡 阂 盒 餲 龁 齕 鲄 魺 鉌 釛 詥 訸 覈 螛 蒚 萂 篕 秴 禾 礉 盉 盇 狢 熆 澕 河 毼 楁 柇 曷 敆 惒 廅 姀 啝 哬 厒 劾 䶅 䫘 䅂 䃒 㹇 㮫 㭘 㪉 㓭 喝 诃 訶 抲 峆 嗬 呵 㲦 颌 㙳 硅 凅 䢔 阖 閤 槅 犵 麧 蓋 葢 䯨 㻧 䮤 hei 嘿 黑 黒 潶 hen 噷 恨 狠 哏 詪 很 佷 䓳 痕 鞎 拫 㯊 heng 胻 訇 澋 绗 絎 撔 啈 誙 䄓 䒛 䬝 黌 黉 横 橫 桁 鸻 鴴 韹 鑅 鐄 衡 蘅 珩 楻 揘 恒 恆 姮 䯒 䬖 㶇 㔰 亨 諻 脝 悙 哼 hong 謍 洚 瓨 鬨 澒 閧 蕻 鍙 㶹 嗊 唝 晎 䀧 㬴 䧆 虹 䫺 鴻 讧 訌 红 硡 紅 鸿 鞃 霟 闳 閎 鋐 鉷 鈜 谼 谹 葓 葒 荭 苰 舼 耾 翝 翃 纮 綋 紭 紘 粠 篊 竤 竑 硔 玒 灴 潂 渱 浤 洪 泓 汯 彋 弘 嵤 峵 宖 宏 娂 妅 垬 吰 仜 䲨 䫹 䪦 䩑 䨎 䡏 䡌 䞑 䜫 䍔 䉺 䆖 䃔 䂫 㢬 㖓 渹 訇 哄 顭 鍧 轰 轟 輷 軣 谾 薨 焢 烘 揈 呍 叿 䬝 黌 黉 㷎 魟 港 缸 hou 呴 㕈 缿 逅 鲘 鲎 鱟 鮜 鄇 郈 豞 洉 後 堠 垕 后 厚 候 䪷 䞧 㫗 㸸 犼 吼 㖃 銗 侯 㤧 鯸 餱 鍭 葔 翭 糇 篌 矦 睺 瘊 猴 帿 喉 䳧 䫛 䙈 䗔 䂉 㺅 㮢 㬋 㗋 齁 𪖙 䫺 䡩 䞀 詬 骺 茩 腄 hu 酏 欻 芐 淴 鴩 鹱 鸌 鳠 鱯 韄 濩 䍓 䛎 笏 䲵 楛 頀 䨥 瓠 謼 鳸 鄠 護 蔰 綔 簄 祜 熩 滬 沪 沍 槴 枑 昈 摢 护 扈 戽 戸 户 戶 怙 弖 帍 岵 嫮 嫭 婟 嚛 冴 冱 互 䪝 䨼 䕶 䇘 㺉 㸦 㨭 㦿 㕆 滸 虎 虝 萀 琥 浒 唬 乕 䗂 㹱 䮸 䉿 觳 㯛 䔯 糊 抇 鵠 鹄 搰 鹕 鶦 鶘 鰗 魱 鬍 餬 頶 鍸 醐 衚 螜 蝴 蔛 葫 胡 縠 絗 箶 瓳 瑚 猢 狐 煳 焀 瀫 湖 槲 楜 斛 弧 媩 壺 壷 壶 囫 嘝 喖 䭍 䭌 䭅 䩴 䧼 䠒 䞱 䚛 䎁 䊀 䉉 䈸 䁫 㿥 㾰 㪶 㗅 呼 膴 峘 嘑 虖 滹 乎 惚 雐 轷 軤 虍 苸 烼 烀 泘 歑 曶 昒 忽 幠 寣 垀 啒 唿 匫 匢 㫚 㷤 核 㽇 胍 㧽 汩 䊺 䵻 鈷 鶻 撫 hua 鋘 蘤 澮 獪 稞 砉 咶 觟 㩇 㚌 䠉 㠢 劃 化 话 譮 諣 話 舙 繣 畵 畫 画 澅 樺 槬 桦 杹 摦 嫿 婳 䛡 㦎 㕷 㕦 㓰 蘳 㕲 䏦 狯 㮯 华 划 䔢 華 滑 骅 驊 铧 鏵 釫 譁 螖 蕐 磆 猾 崋 嬅 䶤 䱻 䅿 㭉 㦊 㠏 㟆 嘩 哗 𢄶 鷨 錵 芲 花 䔯 䴳 輠 䇈 鮭 罫 䊐 huai 佪 坏 蘹 咶 諙 蘾 壞 壊 徊 踝 褱 褢 耲 瀤 淮 櫰 槐 懷 懐 怀 䴜 䈭 䃶 㜳 竵 㠢 huan 瑗 獂 郇 浣 鯶 喛 㓉 渙 轘 擐 鰀 逭 豢 瘓 痪 瑍 煥 焕 烉 漶 涣 槵 梙 換 换 愌 患 幻 宦 奐 奂 垸 喚 唤 䯘 䆠 䀨 䀓 㼫 㹖 㬇 㪱 㕕 輐 㣪 藧 缓 緩 睆 嵈 唍 䈠 㬊 䭴 豲 䝠 䥧 懁 㦥 萑 嬛 缳 繯 環 䴟 䮝 貆 還 还 捖 鬟 雈 阛 闤 镮 锾 鐶 鍰 萈 荁 肒 羦 糫 瓛 环 狟 澴 洹 桓 寰 寏 䦡 䍺 㿪 㶎 㵹 㡲 讙 獾 犿 鵍 鴅 驩 酄 貛 歡 歓 欢 懽 嚾 䠉 㠢 峘 䒛 攌 㔳 灌 潅 鸛 脘 䊐 huang 爌 軦 皩 曂 㨪 滉 榥 晃 䁜 𣄙 鎤 谎 謊 詤 皝 熀 炾 晄 愰 恍 怳 幌 宺 䐠 䌙 㬻 㤺 皇 磺 湟 㾠 潢 䊗 𪏙 黄 黃 鷬 鳇 鱑 鰉 騜 餭 隍 锽 鍠 遑 趪 蟥 蝗 葟 艎 簧 篁 穔 癀 璜 瑝 獚 熿 煌 撗 惶 徨 崲 媓 墴 堭 喤 凰 兤 偟 䳨 䮲 䪄 䞹 䑟 䐵 䍿 䊣 䅣 㾮 㞷 荒 慌 衁 肓 朚 巟 塃 嚝 䄓 櫎 洸 hui 叀 钺 鉞 噦 哕 烜 鑴 薉 煒 韋 違 繐 眭 沬 悝 澮 禬 桧 琿 珲 楎 㜇 㱱 䩈 彙 䅏 䌇 蔧 篲 彗 䛛 䇻 䙡 䙌 㤬 㒑 會 会 㻅 㨤 濊 藱 繢 繪 廆 饖 餯 颒 頮 韢 靧 阓 闠 鐬 鏸 贿 賄 诲 讳 譿 譓 諱 誨 詯 蟪 螝 薈 蕙 荟 翽 翙 缋 绘 絵 穢 秽 瞺 璯 獩 燴 烩 潓 滙 湏 泋 汇 殨 櫘 橞 槥 暳 晦 憓 慧 惠 恵 恚 彚 寭 嬇 圚 嚖 噧 嘒 喙 卉 匯 儶 僡 䫭 䧥 䤧 䜋 䕇 䂕 㷄 㰥 㬩 㩨 㨹 㥣 㞧 㑹 㑰 蝰 芔 毀 虺 𠧩 譭 燬 烠 毇 毁 檓 悔 䛼 䏨 䃣 㷐 㩓 洄 鮰 逥 迴 蜖 蛕 蛔 蚘 茴 痐 恛 廽 廻 囬 回 囘 煇 顪 麾 鰴 隳 隓 辉 輝 豗 诙 詼 褘 袆 翬 翚 禈 烣 灰 瀈 洃 暉 晖 撝 揮 挥 拻 恢 徽 幑 婎 噕 噅 咴 渙 䠉 輠 檜 䍷 䰎 䎚 㽇 䵻 墯 墮 hun 焄 湣 緡 敯 祵 混 溷 诨 諢 觨 焝 慁 圂 倱 俒 䧰 䚠 䅱 䅙 㥵 鯶 睔 餫 餛 梡 渾 浑 顐 䫟 䛰 琿 珲 楎 鼲 魂 馄 轋 繉 棞 忶 堚 䴷 䰟 㨡 㑮 葷 荤 昬 昏 阍 閽 睯 睧 涽 殙 棔 惽 惛 婚 䮝 㮯 㕵 緄 㯻 掍 㨰 䊐 䐊 huo 蠖 矱 或 䋭 㦜 矆 掝 㗲 靃 霩 㨯 䂄 䦚 䰥 攉 騞 嚄 砉 鹱 鸌 鳠 鱯 韄 濩 霍 藿 嗀 雘 閄 镬 鑊 货 貨 讗 謋 蓃 获 艧 臛 臒 耯 穫 禍 祸 礊 矐 眓 癨 瓁 獲 瀖 湱 沎 檴 楇 曤 旤 捇 惑 彠 彟 奯 嚿 嚯 嗀 咟 剨 䉟 䄀 䁨 㸌 㯉 㦯 㘞 伙 鈥 火 邩 夥 䣶 秮 䄑 䄆 钬 活 萿 秳 佸 䯏 豁 锪 鍃 劐 濊 㓉 㩇 㚌 頀 䨥 瓠 㯛 壑 和 咊 耠 龢 㕡 䐸 硅 㨰 㶡 ji 粢 秶 楖 覘 瘵 繫 墍 嵠 緁 蟿 缉 邔 荠 骑 騎 蘄 錤 踑 萁 檱 奇 攲 諆 脔 艻 睽 紒 唶 躤 藉 蛣 偈 訐 櫭 秸 憿 㡶 祭 鯽 稷 㠖 蔇 檕 旣 既 塈 䒁 㾒 䶓 㹄 檵 㠱 伎 䓫 㙨 齌 㡭 㭰 葪 髻 㸄 濟 纪 紀 济 癠 茤 瘈 𥡴 𡜱 鵋 鲫 鲚 鱭 鱀 鰶 鯚 鮆 魝 鬾 骥 驥 霽 霁 際 际 跽 记 计 誋 記 計 觊 覬 褀 裚 蘻 蘮 蘎 薊 蓟 茍 芰 臮 罽 继 繼 継 穧 穊 穄 稩 瞡 痵 璾 猤 瀱 漈 済 洎 梞 曁 暨 旡 技 懻 惎 悸 忌 彑 彐 寄 寂 季 妓 垍 坖 嚌 哜 劑 剤 剂 冀 兾 䶩 䰏 䮺 䨖 䦇 䢋 䠏 䝸 䜞 䗁 䓽 䐀 䋟 㾵 㻑 㳵 㲅 㰟 㥍 㒫 㑧 玘 蟣 䤒 䢳 踦 幾 麂 鱾 魢 魕 鈘 穖 犱 泲 擠 撠 掎 挤 戟 己 妀 丮 䍤 㴉 㨈 㦸 㞦 㞛 㞆 㚡 莋 瘠 㡇 㔕 钑 鈒 蕺 焏 亟 㠎 㘍 㖢 㮟 㥛 㲺 耤 籍 㠍 䟌 䐚 㮨 脊 芨 圾 击 觙 𨸚 鹡 鸄 鶺 鴶 鞊 霵 雧 雦 集 鏶 鍓 銡 郆 辑 轚 輯 蹐 踖 襋 螏 蝍 蕀 蓻 蒺 膌 级 級 箿 笈 禝 礏 皍 疾 狤 濈 潗 漃 湒 汲 殛 檝 橶 槉 極 楫 棘 极 擮 撃 揤 戢 愱 急 忣 彶 庴 嶯 嵴 岌 嫉 姞 塉 堲 吉 及 卽 即 卙 偮 佶 伋 亼 䳭 䲯 䯂 䩯 䣢 䞘 䚐 䐕 䁒 㾊 㽺 㻷 㴕 㱞 㭲 㧀 㤂 㡮 㞃 㙫 㗱 㗊 䤠 犄 嵇 緝 觭 稽 齎 饑 赍 賷 賫 畸 朞 激 枅 𣪠 迹 蹟 跡 肌 禨 虮 几 聻 擊 鰿 𠼻 齑 齏 麡 鸡 鷄 鶏 鳮 饥 飢 韲 鞿 雞 隮 鑙 鑇 鐖 銈 躸 躋 跻 讥 譤 譏 諅 覊 覉 襀 虀 耭 羈 羇 羁 绩 績 簊 箕 筓 笄 積 稘 积 磯 矶 畿 璣 玑 毄 櫅 機 樍 机 嵆 峜 屐 尐 姬 姫 墼 基 嘰 嗘 喞 唧 咭 叽 勣 剞 刏 刉 僟 乩 丌 䰥 㑵 䍯 庪 給 给 隔 䛋 革 䩐 䦈 㱦 覿 䓧 薺 䆅 jia 揳 骱 柙 舺 伽 脥 駱 䀹 颉 頡 拮 䁍 價 价 駕 驾 稼 榢 架 嫁 価 叚 假 賈 椵 鉀 钾 贾 仮 胛 甲 玾 檟 槚 榎 斝 斚 徦 岬 婽 䑝 㕅 唊 袷 浹 浃 梜 饸 餄 铪 鞈 鵊 颊 頰 頬 鞂 铗 鋏 郟 郏 跲 裌 蛺 蛱 莢 荚 硈 扴 戞 戛 恝 埉 圿 䩡 䛟 䕛 䀫 㿓 㼪 㮖 㪴 迦 葭 家 佳 幏 夾 夹 麚 鴐 镓 鎵 鉫 跏 貑 豭 袈 腵 耞 笳 痂 珈 猳 犌 泇 毠 枷 拁 嘉 加 傢 乫 㔠 鉿 嘏 䢔 鴚 䇲 jian 箴 瑊 椾 魙 鏨 钘 銒 鈃 礆 瞷 瞯 閒 纖 鎫 帴 淺 揵 錢 騫 跈 濫 臶 䟅 䭕 见 見 䵛 覸 䵖 腱 䤔 㔋 檻 䬻 㦗 楗 梘 枧 濺 譼 渐 溅 諌 漸 螹 鰎 饯 餞 键 鑳 鑬 鑒 鑑 鏩 鍵 鍳 鋻 鉴 釼 踺 踐 践 趝 贱 賤 賎 谏 諫 諓 覵 襉 薦 蔪 荐 艦 舰 繝 糋 箭 磵 珔 牮 瀳 澗 涧 洊 毽 榗 栫 旔 擶 徤 建 劔 劒 劎 劍 剱 剣 剑 僭 僣 健 俿 俴 侟 件 䭈 䧖 䥜 䇟 㺝 㰄 㯺 㨴 㣤 㓺 䩆 㳨 趼 䛳 䄯 㔓 碱 䶠 䯛 䭠 䅐 蹇 囝 撿 捡 暕 䯡 鐧 锏 筧 𢆞 鹼 鹻 鹸 鰔 鐗 谫 譾 謭 謇 襺 襇 裥 蠒 藆 翦 繭 絸 簡 简 笕 硷 瞼 睑 瑐 瀽 湕 減 檢 検 检 柬 揀 挸 拣 戬 戩 弿 寋 堿 剪 减 儉 倹 俭 䵤 䵡 䮿 䟰 䉍 㶕 㨵 餰 豣 肩 犍 鶼 礛 湔 監 間 鞬 间 监 煎 鬋 揃 椷 菅 麉 鹣 鵳 鳽 鳒 鲣 鰹 鰜 魐 騝 馢 顅 韉 韀 鞯 靬 鑯 豜 虃 蕳 蕑 蒹 葌 菺 艱 艰 缣 缄 縑 緘 籛 篯 箋 笺 碊 睷 玪 猏 牋 熸 熞 瀸 瀐 殲 歼 櫼 樫 搛 戔 戋 惤 尖 姧 姦 奸 堅 坚 囏 冿 兼 偂 枅 聻 㽉 㵎 茛 㺂 劗 䞼 茧 jiang 勥 繦 繈 傹 降 弜 嵹 糨 洚 𢘸 醬 醤 酱 謽 袶 蔃 绛 絳 糡 犟 摾 弶 夅 匠 匞 䞪 䒂 䙹 顜 蔣 蒋 槳 耩 讲 講 膙 獎 滰 桨 奬 奨 奖 䋌 䉃 䁰 㯍 㢡 疆 𤕭 將 将 漿 浆 瓨 𤕯 鳉 鱂 韁 豇 螿 螀 薑 葁 茳 翞 缰 繮 礓 疅 畺 畕 江 殭 橿 摪 姜 壃 僵 jiao 灂 趭 齩 藠 斆 斅 胶 嘐 艽 觉 覺 覐 爝 焳 纠 糺 轇 皛 䪒 窖 酵 㬭 醮 嶠 峤 較 较 䣤 䂃 徼 敫 教 敎 噍 釂 醶 轿 轎 譥 訆 窌 皭 珓 潐 漖 滘 斠 挍 嬓 噭 嘦 嘂 呌 叫 䆗 㰾 㠐 繳 缴 儌 䠛 狡 絞 䴛 㩰 㳅 角 踋 腳 脚 湫 餃 䚩 矫 鲛 矯 佼 勦 剿 𠞰 鱎 饺 铰 鉸 賋 譑 蟜 虠 臫 绞 筊 皦 皎 璬 煍 烄 灚 漅 湬 曒 暞 晈 敿 敽 攪 撹 撟 摷 搅 捁 挢 徺 孂 劋 僥 侥 䥞 䘨 䁶 䀊 㽲 㽱 㭂 嚼 嫶 茭 驕 骄 蕉 簥 燋 焦 跤 僬 姣 鮫 膠 憿 澆 浇 𨺹 鹪 鷮 鷦 鷍 鵁 鴵 鐎 郊 詨 蟭 蟂 蛟 茮 芁 膲 穚 礁 椒 憍 嶕 峧 嬌 娇 嘄 交 䴔 顜 jie 毑 扻 寁 械 廨 獬 骱 絜 偕 箑 抾 洯 嵑 罝 苴 䔿 䁓 䇒 紒 唶 躤 芥 𡽱 魪 魀 鎅 诫 誡 褯 蚧 艥 繲 砎 疥 畍 界 琾 玠 犗 楐 戒 悈 徣 庎 岕 届 屆 堺 吤 借 介 丯 䲸 䱄 䰺 䯰 䛺 㿍 㾏 㠹 㝏 㑘 檞 解 飷 觧 媎 姐 櫛 栉 䀹 䂝 䣠 睫 蛣 捷 䂒 鮚 楬 㓤 葜 偈 㦢 㓗 㮞 碣 㝌 结 节 節 颉 頡 拮 結 訐 櫭 卩 鲒 騔 鐑 鍻 鉣 迼 踕 趌 诘 讦 誱 詰 袺 衱 蠽 蠞 蠘 蜐 蓵 莭 脻 羯 竭 癤 疖 瀄 潔 滐 榤 楶 桀 栨 杰 昅 擳 搩 截 幯 嵥 崨 岊 孑 婕 喼 卪 劼 劫 刼 刧 刦 傑 偼 倢 䲙 䥛 䗻 䕙 䌖 䅥 䂶 䀷 㸅 㮮 㨩 㨗 㞯 㛃 㘶 㔾 謯 薢 擑 掲 嗟 秸 鶛 階 阶 街 蝔 菨 腉 稭 皆 瑎 湝 椄 揭 接 巀 堦 喈 䂃 袷 葪 髻 㸄 耤 㠍 洁 䟌 鹖 鶡 䞦 紇 㑵 䘁 裓 㨰 犵 砝 jin 訡 釿 厪 鋟 劲 䖐 㴆 寖 䶖 浸 䋮 肵 勁 䑤 盡 殣 禁 璡 琎 近 𠬶 齽 靳 進 进 赆 贐 賮 藎 蓳 荩 缙 縉 瘽 璶 瑨 燼 烬 濜 濅 溍 浕 歏 枃 暜 晋 晉 搢 嬧 嫤 妗 墐 嚍 噤 劤 凚 僸 伒 䫴 䝲 䗯 䌝 䆮 䀆 㶳 㶦 㱈 㰹 㯲 㬜 㨷 䥆 槿 廑 㬐 菫 慬 覲 瑾 僅 仅 馑 饉 锦 錦 谨 謹 觐 緊 紧 漌 巹 尽 堇 卺 儘 侭 䭙 䤐 䒺 䐶 㹏 㯸 㝻 衿 筋 金 紟 祲 矜 黅 鹶 钅 觔 襟 菳 荕 瑧 珒 津 斤 惍 巾 嶜 埐 今 㦗 䌍 䉷 jing 陘 陉 殑 檠 黥 惊 幜 㵾 擏 䵞 㢣 㕋 䔔 靚 倞 脛 胫 靖 傹 靖 靜 静 靓 镜 鏡 逕 迳 踁 誩 葝 竸 競 竫 竧 竟 竞 痙 痉 獍 瀞 濪 淨 浄 梷 桱 曔 敬 徑 径 弳 弪 婧 婙 妌 境 凈 净 俓 䡖 㹵 㬌 㣏 景 烴 烃 颈 頸 頚 阱 警 蟼 肼 穽 璥 璟 燛 汬 暻 憼 憬 宑 剄 刭 儆 井 丼 䜘 㘫 莖 箐 涇 精 鲸 鯨 经 經 睛 𦀇 精 鼱 麠 麖 鶄 鶁 鵛 驚 葏 菁 荊 荆 茎 腈 聙 経 猄 泾 晶 旍 旌 巠 婛 坙 坕 兢 亰 京 䴖 勁 䑤 澋 獷 粳 稉 秔 jiong 鎣 檾 㑋 澃 㤯 㢠 幜 皛 炅 颎 顈 逈 迥 褧 綗 絅 窘 熲 煛 煚 烱 炯 泂 囧 冏 僒 侰 䢛 䐃 䌹 㷡 㷗 㖥 㓏 垧 蘔 蘏 扃 駫 駉 埛 坰 冋 冂 jiu 稵 艽 蝤 缪 繆 畂 摎 㶭 㺩 䊆 㧕 䳔 捄 桕 咎 齨 麔 鹫 鷲 鯦 舊 舅 臼 疚 柾 柩 旧 救 慦 廐 廏 廄 就 媨 厩 匶 匛 匓 僦 䳎 䡂 䛮 䓘 䊘 䆒 䅢 㲃 㩆 㠇 赳 韮 韭 镹 酒 舏 紤 玖 灸 奺 乣 九 乆 久 㡱 㺵 鳩 觓 究 纠 糺 糾 轇 鸠 鬮 鬏 阄 醔 萛 牞 樛 朻 揫 揪 揂 啾 勼 丩 㝌 湫 㼋 䬨 䠓 ju 鄹 鄒 柤 鬻 繘 萭 楀 偊 湨 渠 懅 籧 軥 鶌 蛆 砠 鲏 簍 蔞 㞫 䣰 苣 䆽 鐻 遽 蚷 絇 窶 窭 寠 㳥 拒 锯 鋸 泃 据 倶 句 鮔 駏 飓 颶 钜 鉅 醵 邭 躆 踞 距 貗 讵 詎 虡 聚 耟 粔 簴 秬 犋 焣 炬 澽 洰 歫 昛 據 拠 懼 愳 惧 怚 怇 巨 岠 屨 屦 姖 壉 埾 埧 勮 劇 剧 冣 具 倨 俱 䶙 䵕 䱟 䛯 㬬 㩀 㨿 㠪 㜘 㘌 咀 齟 䅓 竘 䈮 龃 踽 跙 袓 蝺 蒟 莒 舉 筥 矩 欅 櫸 榘 榉 椇 擧 挙 弆 举 䶥 䢹 䄔 䃊 䗇 鞫 锔 踘 掬 鼳 鶪 鵴 鵙 驧 駶 閰 鄓 郹 輂 躹 蹫 跼 趜 諊 蘜 菊 粷 箤 狊 犑 焗 淗 泦 毱 毩 橘 椈 梮 挶 巈 局 婅 匊 侷 䴗 䱡 䰬 䪕 䤎 䡞 䜯 䕮 䏱 䋰 㽤 㮂 㩴 㥌 㘲 菹 葅 沮 駒 裾 疽 岨 鞠 鋦 檋 罝 居 拘 苴 鶋 鴡 鮈 驹 雎 陱 踙 跔 蜛 艍 腒 眗 琚 狙 涺 椐 抅 崌 娵 刟 凥 㞐 䳔 捄 桔 㕢 鉏 车 車 juan 脧 悁 泫 鞙 鋗 絭 腃 雋 隽 㯞 飬 絹 䚈 䳪 劵 卷 桊 巻 𠔉 鬳 韏 锩 錈 鄄 羂 罥 绢 睠 睊 眷 瓹 獧 狷 淃 慻 帣 勬 勌 倦 䡓 䖭 䌸 䄅 㪻 㢾 㢧 捲 𩜇 菤 臇 埢 㷷 涓 捐 鹃 鵑 镌 鐫 鎸 裐 蠲 朘 娟 姢 剶 䐪 jue 蕞 矞 泬 蛙 闕 咑 阙 闋 镼 璚 蹻 駃 鴂 𠢤 䟾 䞵 蕝 䏐 㓸 㭾 㟲 鱊 潏 㤜 䖼 噱 䙠 䁷 䏣 蠼 㔃 觖 㰐 㭈 䋉 䝌 倔 蹶 撧 觉 覺 覐 爝 焳 嵑 鳜 趹 柽 𩪗 𧽸 龣 鷢 鴃 镢 钁 鐝 鐍 鈌 逫 躩 蹷 赽 貜 谻 谲 诀 譎 訣 觼 覚 蟩 蟨 蚗 蕨 芵 臄 绝 絶 絕 砄 矡 矍 瘚 疦 瑴 珏 玨 玦 玃 獗 爵 爴 爑 熦 焆 決 氒 殌 欮 欔 橜 橛 桷 斍 攫 掘 捔 挗 抉 戄 憰 憠 彏 弡 嶥 崫 崛 屫 孓 孒 厥 勪 劂 刔 决 僪 傕 亅 䦼 䦆 䡈 䠇 䞷 䘿 䐘 䍊 䇶 䆢 䆕 䀗 㻕 㹟 㸕 㷾 㵐 㩱 㔢 撅 屩 噘 䣤 角 踋 腳 嚼 㭰 觳 抇 鱖 㔳 䈑 㻡 䍳 jun 鵔 陖 狻 逡 菎 㝦 浚 睃 葰 㕙 㓴 㒞 雋 鵘 骏 駿 馂 餕 郡 蔨 箟 箘 竣 畯 珺 焌 濬 殾 晙 攟 攈 捃 懏 峻 寯 呁 儁 俊 䝍 䜭 䕑 䇹 㽙 㻒 㴫 㑺 蜠 均 頵 麕 麇 菌 麏 鲪 鮶 钧 銞 銁 鈞 軍 覠 袀 蚐 莙 碅 皹 皸 皲 汮 桾 姰 君 军 䝌 㤯 㢠 訇 龜 ka 卡 髂 鉲 胩 咔 佧 喀 咖 kai 𩋧 豈 咳 愒 欬 㲉 礚 烗 炏 炌 愾 忾 勓 䡷 㡁 闿 闓 鍇 锴 楷 颽 铠 鎧 輆 蒈 暟 慨 愷 恺 塏 垲 嘅 剴 剀 凱 凯 䒓 䐩 䁗 奒 痎 開 锎 鐦 揩 开 閡 㳀 䫦 㗆 kan 餡 轁 刋 薟 䘓 看 闞 阚 衎 竷 磡 矙 瞰 墈 䀍 䶫 塪 顑 轗 輡 莰 砍 歞 歁 欿 惂 崁 埳 坎 冚 偘 侃 㸝 龕 勘 龛 栞 戡 嵁 堪 刊 檻 槛 䬻 譼 監 䳚 䫲 䖔 鬫 㵎 㙳 kang 邟 抗 闶 閌 砊 炕 亢 钪 鈧 犺 囥 匟 伉 㰠 䡉 摃 扛 慷 鱇 鏮 躿 糠 粇 穅 漮 槺 忼 康 嫝 杭 沆 䲘 kao 靠 铐 銬 犒 䐧 丂 稁 𥬯 鲓 鮳 攷 薧 槀 考 燺 烤 洘 栲 拷 䯪 鷱 髛 尻 䘓 䎋 藳 槁 ke 閜 殻 匼 砢 兣 锞 䶗 溘 嗑 骒 騍 醘 课 課 衉 缂 緙 碦 氪 榼 搕 揢 愙 愘 恪 尅 客 娔 堁 垎 勊 勀 剋 刻 克 䙐 㾧 㤩 㕉 㰤 㵣 㪙 可 㪃 坷 渴 嶱 礍 炣 渇 敤 岢 㪼 㪡 㞹 殼 壳 咳 簻 棵 髁 科 颗 顆 磕 稞 苛 疴 鈳 峇 轲 軻 趷 蝌 薖 萪 胢 窠 瞌 珂 犐 樖 柯 龕 欬 㲉 礚 喀 㒞 䋉 䁍 铪 㥛 㲺 蚵 䕣 盍 荷 颏 頦 鉿 錁 哿 䗘 㝓 䘁 㕎 钶 痾 ken 颀 頎 㸧 褃 裉 硍 珢 掯 齦 龈 龂 齗 錹 豤 肻 肯 肎 懇 恳 墾 垦 啃 keng 硎 䡰 挳 阬 铿 鏗 鍞 銵 硻 硜 硁 牼 摼 妔 奟 坑 坈 劥 脛 誙 吭 鉺 kong 矼 控 鞚 㸜 㤟 恐 孔 空 倥 鵼 錓 箜 硿 涳 悾 崆 埪 㑋 kou 鏂 㽛 䳟 鷇 佝 𦶲 釦 蔻 蔲 簆 筘 窛 瞉 滱 敂 扣 怐 寇 宼 叩 冦 䳹 㲄 㰯 㓂 口 劶 㔚 袧 芤 摳 抠 彄 剾 䧆 䍍 溝 ku 窋 绹 綯 跨 㒂 矻 酷 趶 褲 裤 袴 绔 絝 秙 瘔 焅 庫 库 嚳 喾 俈 㠸 苦 䇢 扝 胐 骷 顝 郀 轱 軲 跍 窟 桍 枯 堀 圐 哭 刳 楛 䔯 kua 晇 胯 跨 骻 䋀 㐄 锞 銙 恗 垮 侉 誇 荂 姱 夸 咵 挎 髁 㡁 䦚 錁 kuai 蕢 蒉 墤 㬮 鬠 㱮 㟴 㔞 駃 澮 獪 禬 桧 鲙 鱠 鄶 郐 膾 脍 糩 筷 浍 欳 快 廥 塊 块 噲 哙 凷 儈 侩 䶐 䯤 䭝 䈛 㙗 㙕 蒯 擓 䓒 㧟 呙 㭈 會 会 㻅 㨤 狯 㫎 檜 巜 旝 栝 kuan 䤭 款 窾 歀 欵 䲌 䥗 䕀 㯘 髖 髋 臗 寬 寛 宽 梡 㮯 kuang 迋 鄺 框 爌 鑛 鉱 邝 躀 贶 貺 纩 纊 絖 礦 矿 矌 眶 眖 況 曠 昿 旷 懭 懬 岲 壙 圹 卝 况 儣 䵃 䊯 黋 俇 夼 诳 誑 狂 鵟 抂 㤮 诓 誆 邼 軭 筐 硄 洭 恇 哐 匩 匡 劻 㔞 䂄 磺 湟 㾠 㫛 逛 穬 kui 亏 磈 隗 闋 顷 頃 潰 䍪 饋 腃 尯 蕢 蒉 鐀 瞶 瞆 撌 媿 騩 馈 餽 鑎 蔮 聵 聭 聩 籄 簣 篑 溃 樻 槶 憒 愧 愦 嘳 喟 䕚 䈐 㕟 跬 䫥 䦱 頍 蹞 煃 䠑 㛻 㨒 頄 馗 頯 魁 楑 睽 骙 騤 鍨 鄈 逵 躨 虁 蘷 葵 聧 犪 湀 櫆 楏 暌 晆 揆 戣 奎 夔 喹 䳫 䯓 䧶 䤆 䟸 䕫 㚝 㙓 闚 窺 窥 悝 鍷 虧 蘬 藈 盔 巋 岿 刲 㱮 㟴 觖 㰐 㡭 䇻 䙡 䙌 㤬 㒑 蝰 㾠 㚍 匱 匮 䯣 䙆 䖯 㙺 䰎 䁛 鮭 歸 傀 㷇 䏗 㧉 kun 鶤 齳 睏 涃 困 㫻 䠅 㩲 祵 齫 阃 閸 閫 裍 綑 稛 稇 硱 梱 捆 悃 壼 壸 菎 昆 焜 錕 鹍 鵾 鲲 鯤 髨 髡 髠 騉 锟 醌 貇 褌 裈 蜫 瑻 琨 猑 晜 惃 崑 崐 婫 堃 坤 麇 餛 鰥 㕎 kuo 噋 蛞 括 鞹 鞟 阔 闊 濶 漷 擴 挄 拡 扩 彍 彉 廓 姡 䯺 䦢 䟯 㗥 擃 鄺 鬠 㪙 霩 㨯 秮 䄑 䄆 㣪 髺 筈 栝 䙃 la 摺 旯 搚 落 擸 砬 癩 癞 啦 鞡 蜡 腊 爉 䶛 䪉 䝓 䗶 㻋 㸊 剌 癩 鯻 鬎 镴 鑞 辣 辢 蠟 蝲 蝋 臘 臈 瘌 瓎 楋 攋 揧 䱫 䓥 䏀 䃳 䂰 㻝 䟑 藞 喇 邋 揦 㕇 垃 翋 拉 磖 菈 柆 嚹 嘑 lai 黧 㠣 䲚 癩 癞 鵣 勑 顂 頼 赖 赉 賴 賚 襰 藾 籟 籁 睞 睐 瀬 瀨 濑 櫴 娕 䓶 䄤 㾢 唻 䂾 㥎 䧒 来 徠 徕 倈 俫 來 䠭 䚅 㚓 麳 鶆 鯠 騋 铼 錸 郲 逨 萊 莱 箂 筙 琜 猍 淶 涞 棶 梾 庲 崍 崃 孻 婡 䋱 䅘 㸊 䀳 lan 罱 廪 惏 煉 䃹 镧 濫 嚂 壏 缆 纜 瓓 爤 爛 爁 燗 烂 滥 㱫 㜮 䊖 覽 𡒄 顲 醂 览 覧 灠 漤 浨 欖 榄 攬 擥 揽 懶 懒 孏 孄 嬾 壈 䌫 㰖 㩜 㨫 㛦 䳿 厱 啉 欄 栏 闌 鑭 䪍 㦨 藍 蓝 韊 阑 钄 躝 谰 讕 譋 襴 襤 襕 蘭 蘫 葻 繿 糷 籣 籃 篮 礷 璼 燷 燣 灡 灆 瀾 澜 欗 斕 斓 攔 拦 懢 幱 嵐 岚 婪 囒 兰 儖 䰐 䦨 䑌 䍀 䆾 㳕 㞩 㘓 㑣 䲚 䧒 㔋 暕 礛 㘕 lang 鎯 哴 䕞 浪 蒗 崀 埌 䍚 䀶 㾗 硠 閬 誏 烺 朤 朗 朖 塱 㮾 㫰 㙟 㓪 莨 狼 郞 郎 琅 䆡 榔 㾿 锒 鋃 躴 螂 蜋 蓢 蓈 艆 筤 稂 瑯 欴 樃 桹 廊 嫏 勆 俍 䱶 䯖 䡙 㱢 㢃 㟍 㝗 啷 䃹 羮 lao 姥 烙 蓼 簝 獠 櫟 酪 澇 涝 髝 軂 耮 耢 橯 憦 嫪 㟙 橑 潦 䕩 轑 荖 铑 銠 老 狫 栳 恅 咾 佬 䵏 䳓 䝤 䇭 㧯 䃕 㨓 㞠 牢 癆 勞 劳 䜎 铹 鐒 醪 蟧 簩 窂 磱 痨 浶 憥 嶗 崂 嘮 唠 哰 労 僗 䲏 䝁 㟹 㟉 㗦 撈 捞 le 脟 朸 屴 了 饹 餎 樂 乐 捋 㖀 勒 艻 鳓 鰳 頱 韷 阞 簕 竻 砳 玏 泐 氻 楽 扐 忇 哷 叻 仂 㦡 㔹 𡃖 lei 漯 囄 嘞 㭩 𩔗 類 类 淚 䍥 㴃 累 礧 礌 攂 肋 颣 頪 錑 銇 酹 蘱 纇 禷 涙 泪 埒 䮑 䣦 䢮 䒹 䉪 㲕 㡞 壘 垒 㑍 轠 櫑 樏 鸓 頛 鑸 诔 讄 誄 蘽 藟 蕾 蕌 耒 絫 礨 磥 磊 癗 瘣 灅 洡 櫐 厽 儽 儡 傫 䴎 䣂 䛶 䉂 㿔 㼍 㶟 㙼 㒦 䉓 羸 纍 擂 靁 雷 檑 䨓 㔣 蠝 㵢 㒍 鼺 镭 鑘 鐳 虆 蘲 罍 缧 纝 縲 畾 瓃 欙 嫘 壨 䐯 䍣 㹎 勒 㻋 㰐 㲺 㵽 leng 睖 輘 碐 䚏 愣 踜 堎 䮚 冷 稜 倰 楞 棱 薐 崚 塄 䬋 䉄 li 迣 杝 釃 酾 纚 鑠 叓 颯 灑 秜 氂 薶 擽 硌 珞 濼 捩 浰 酈 郦 䬅 攦 立 㱹 䁻 䴄 㻎 躒 跞 礫 䲞 䚕 戾 䮋 㻺 斄 莉 麗 蠫 琍 丽 唎 朸 屴 櫟 栎 砬 鬲 隶 𥝢 麜 鷑 鷅 鴗 鳨 鱳 鱱 鬁 靋 靂 雴 雳 隸 隷 鉝 轹 轣 轢 赲 讈 詈 蠣 蠇 蝷 蜧 蛠 蛎 蚸 藶 蒞 莅 荔 茘 苙 苈 脷 纅 綟 糲 粝 粒 篥 筣 笠 秝 禲 礰 礪 磿 砾 砺 砅 矋 盭 皪 癧 癘 痢 疬 疠 瓥 瓑 瓅 瑮 珕 猁 犡 爏 爄 瀝 濿 溧 涖 沴 沥 歷 歴 櫪 櫔 棙 栵 栛 栗 枥 曞 曆 暦 攭 攊 搮 戻 慄 悷 悧 巁 岦 婯 壢 塛 坜 囇 嚦 唳 呖 吏 厲 厯 厤 厉 历 勵 励 力 利 凓 儷 儮 傈 俪 俐 例 䶘 䴡 䰜 䰛 䮥 䬆 䥶 䤙 䡃 䟐 䟏 䘈 䔉 䔁 䓞 䍽 䊪 䇐 䅄 䃯 㿨 㾐 㽝 㽁 㼖 㺡 㯤 㮚 㬏 㧰 㤦 㤡 㡂 㟳 㘑 㗚 㕸 㔏 㒧 㑦 䤚 㾖 欐 蟸 蠡 兣 豊 礼 鳢 鲤 鱧 鯉 锂 鋰 里 醴 邐 逦 裡 裏 粴 禮 礼 盠 理 澧 浬 欚 李 峲 峢 峛 娌 俚 䧉 䗍 㸚 釐 梩 騹 犛 䖥 㹈 貍 狸 璃 離 䔧 㿛 㒿 鱺 囄 黧 驪 离 攡 𠩺 黎 鹂 鸝 鵹 鲡 鯬 骊 鑗 鏫 錅 鋫 醨 邌 謧 褵 蟍 蜊 蘺 藜 蔾 蓠 菞 艃 罹 缡 縭 糎 粚 粍 籬 篱 穲 睝 瓈 犂 犁 灕 漦 漓 樆 棃 梸 梨 悡 廲 孷 孋 嫠 嚟 喱 厘 劙 剺 剓 刕 䵩 䵓 䴻 䱘 䣫 䣓 䙰 䖿 䖽 䔣 䔆 䍦 䍠 䋥 䊍 䉫 䅻 䄜 㷰 㴝 㰚 㰀 㦒 㠟 㓯 哩 䚏 𩔗 淚 䍥 㴃 㠣 㥎 䗶 悝 翮 镉 鎘 䕻 㷴 lia 倆 俩 lian 膁 淰 涊 攣 孌 苓 㼑 㜃 蘞 蘝 襝 裣 敛 鏈 蔹 浰 煉 鰊 链 鍊 錬 萰 练 纞 練 瑓 炼 瀲 澰 潋 湅 殮 殓 楝 戀 恋 媡 堜 㶑 㱨 㪝 㜻 㦑 膦 㰸 薟 莶 斂 鄻 臉 脸 羷 摙 嬚 䌞 䇜 㰈 㯬 㪘 濂 螊 㓎 䆂 䃛 溓 㝺 䙺 連 僆 蓮 璉 琏 㼓 漣 𢅖 𢅏 鲢 鰱 鬑 镰 鐮 鎌 连 蹥 譧 謰 覝 褳 裢 蠊 薕 莲 臁 聯 聮 聫 联 翴 縺 籨 籢 簾 稴 磏 燫 熑 濓 涟 櫣 槤 梿 憐 慩 怜 廉 帘 嫾 奱 奩 奁 噒 嗹 匳 匲 劆 亷 䭑 䨬 䥥 䏈 䁠 㾾 㺦 㶌 㦁 㥕 㢘 㡘 㟀 㜕 羸 䐄 歛 liang 蹣 量 谅 諒 哴 鍄 辆 輛 輌 湸 晾 悢 喨 亮 兩 两 両 魎 魉 裲 蜽 脼 緉 掚 啢 唡 䩫 䠃 䓣 㔝 㒳 涼 凉 良 惊 駺 辌 輬 綡 糧 粱 粮 樑 椋 梁 墚 䭪 䣼 䝶 㹁 倆 俩 䁁 䀶 㾗 阆 踉 莨 靚 倞 liao 缪 繆 翏 蟉 㺒 撂 䍡 䢧 料 尞 爒 炓 廖 尦 尥 䎆 䉼 㡻 蓼 瞭 釕 㶫 燎 憭 镽 鄝 䩍 䑠 䄦 療 繚 鷚 飂 聊 漻 䝀 㵳 镣 鐐 嘹 㝋 暸 簝 獠 摎 鹩 鹨 鷯 髎 飉 顟 遼 辽 蹘 賿 豂 蟟 膫 膋 缭 窷 疗 璙 熮 敹 憀 廫 嶛 嶚 嵺 屪 寮 寥 嫽 僚 䨅 䜮 䜍 㙩 撩 蹽 㜃 了 橑 潦 轑 㨓 㞠 䕞 䣈 钌 lie 猎 䟹 裂 捩 脟 擸 𤢪 鴷 鱲 鮤 鬣 鬛 颲 迾 躐 趔 蛶 蛚 茢 聗 睙 獵 犣 煭 烈 浖 洌 挒 姴 埓 劽 劣 列 冽 儠 䴕 䜲 䓟 䉭 䅀 䁽 㽟 㼲 㸹 㲱 㯿 㭞 㬯 㧜 㤠 咧 䟩 巤 䮋 㻺 爉 䶛 䪉 䝓 㸊 邋 lin 赁 賃 粦 閵 轥 躪 躙 躏 蹸 藺 蔺 焛 橉 悋 恡 吝 䫰 䗲 䉮 㖁 菻 廪 癝 癛 澟 檩 檁 撛 懔 懍 廩 凜 凛 僯 䕲 㨆 㐭 罧 厸 磷 瞵 鄰 遴 辚 轔 臨 淋 临 粼 惏 綝 麟 麐 鳞 鱗 驎 霖 隣 鏻 邻 翷 繗 箖 碄 矝 痳 疄 甐 璘 琳 獜 燐 瀶 潾 林 暽 晽 斴 嶙 壣 亃 䮼 䫐 䢯 䚬 㷠 㝝 㔂 䟹 䢧 膦 㝺 䚏 啉 㖼 ling 令 炩 掕 另 领 領 阾 袊 彾 嶺 䉹 呤 靈 霝 灵 泠 岭 㻏 零 苓 睖 輘 碐 龗 龄 齢 齡 麢 鹷 鸰 鴒 鲮 鯪 魿 駖 霛 霊 陵 閝 铃 錂 鈴 醽 酃 軨 跉 詅 裬 衑 蛉 蘦 蕶 蔆 菱 舲 聆 翎 羚 绫 綾 紷 笭 竛 秢 祾 砱 皊 瓴 琌 玲 狑 爧 燯 澪 淩 欞 櫺 棂 柃 朎 岺 孁 姈 夌 坽 囹 刢 凌 伶 䴫 䴒 䴇 䰱 䯍 䨩 䧙 䡿 䡼 䠲 䚖 䙥 䖅 䕘 䔖 䍅 䌢 䉖 䉁 䈊 䄥 㾉 㸳 㲆 㱥 㯪 㬡 㪮 㦭 㥄 㡵 㖫 昤 拎 稜 倰 㭩 釘 liu 斿 泖 膢 陸 陆 磟 蔞 六 馏 餾 鐂 澑 畂 鬸 霤 雡 磂 廇 塯 坴 䄂 㽌 㶯 㨨 㙀 铆 鉚 飹 锍 鋶 羀 罶 绺 綹 珋 橮 桺 栁 柳 嬼 䱞 䋷 䭷 镏 鎦 遛 留 畱 䱖 䉧 瀏 嚠 蟉 硫 麍 鹠 鶹 鰡 骝 驑 騮 駵 駠 飗 飅 飀 镠 鏐 鎏 裗 藰 蓅 蒥 癅 瘤 疁 畄 璢 瑬 瑠 琉 浏 流 沠 橊 榴 旒 旈 懰 嵧 媹 劉 刘 䶉 䰘 䬟 䚧 䗜 㽞 㐬 溜 蹓 熘 䉹 蓼 鷚 飂 聊 漻 䝀 㵳 㝋 摎 㧕 㳅 䒥 long 挵 贚 衖 硦 梇 徿 哢 㢅 㟖 㛞 㑝 隴 陇 竉 攏 拢 壠 壟 垅 垄 儱 䡁 㴳 㙙 瀧 滝 泷 䙪 龙 龍 蘢 襱 籠 笼 朧 隆 龓 龒 鸗 靇 霳 鑨 鏧 躘 豅 蠬 蠪 蕯 茏 胧 聾 聋 簼 篭 竜 窿 礲 礱 砻 矓 眬 癃 瓏 珑 爖 漋 湰 櫳 栊 曨 昽 巄 巃 嶐 屸 嚨 咙 䪊 䥢 䏊 䆍 䃧 㰍 㦕 㡣 㝫 㚅 㳥 篢 lou 漊 溇 僂 偻 瘻 瘘 膢 囉 嘍 喽 鏤 漏 陋 镂 瘺 屚 㔷 簍 嶁 嵝 㪹 摟 搂 篓 甊 塿 䱾 鞻 謱 樓 䮫 䣚 䫫 䝏 耬 䅹 蔞 蒌 鷜 髏 髅 遱 軁 螻 蝼 艛 耧 熡 楼 慺 廔 婁 娄 剅 䄛 㺏 㲎 㥪 㟺 瞜 䁖 㡞 窶 窭 寠 lu 绿 綠 氌 輅 辂 録 录 鹿 路 露 碌 陸 陆 磟 簬 逯 𡀔 麓 鹭 鷺 鵱 鵦 鯥 騼 騄 鏴 鏕 錴 錄 醁 辘 轆 蹗 踛 趢 赂 賂 觻 觮 螰 虂 蕗 蔍 菉 膔 粶 籙 簶 簏 箓 穋 稑 禄 祿 硉 睩 盝 甪 璐 琭 熝 潞 漉 渌 淥 淕 樚 椂 摝 戮 彔 廘 峍 娽 垏 圥 勠 勎 剹 僇 侓 䴪 䱚 䩮 䡜 䟿 䚄 䘵 䐂 䎼 䎑 䌒 䃙 㼾 㯟 㯝 㫽 㪖 㪐 㦇 㟤 㜙 㛬 㖨 㓐 魯 䕡 舻 鹵 鲁 镥 鑥 鐪 鏀 虜 虏 蓾 艪 艣 磠 硵 瀂 滷 櫓 橹 樐 擼 擄 撸 掳 塷 卤 䲐 㯭 㢚 㔪 䮉 㢳 臚 芦 艫 黸 鸬 鸕 鲈 鱸 魲 髗 颅 顱 鑪 轳 轤 蠦 蘆 胪 罏 纑 籚 矑 盧 瓐 璷 玈 獹 爐 炉 瀘 泸 櫨 栌 曥 攎 廬 庐 壚 垆 嚧 卢 䰕 䡎 㿖 㱺 㭔 㪭 㠠 嚕 噜 㪹 䍡 蓼 簵 luan 薍 釠 亂 乱 卵 攣 孌 娈 脔 鸾 鸞 鵉 鑾 銮 虊 臠 羉 癵 癴 灤 灓 滦 欒 栾 曫 挛 巒 峦 孿 孪 圞 圝 䜌 䖂 㱍 㡩 㝈 脟 㼑 㰸 䚕 lun 棆 论 論 碖 埨 耣 稐 䈁 菕 淪 惀 抡 纶 綸 鯩 陯 錀 轮 輪 踚 蜦 腀 溣 沦 崙 崘 婨 圇 囵 倫 侖 伦 仑 䑳 㷍 㖮 掄 㕢 luo 橐 漯 擽 䇔 摞 硌 珞 烙 络 絡 落 駱 袼 濼 鵅 鴼 鮥 骆 雒 荦 纙 笿 犖 洛 峈 嗠 䌴 䌱 䈷 䀩 㿚 㴖 㓢 蠃 攞 鎯 砢 躶 裸 蓏 臝 癳 瘰 曪 倮 㱻 㰁 㩡 㦬 㒩 邏 逻 㽋 欏 羅 氌 玀 鸁 骡 驘 騾 饠 镙 锣 鑼 鏍 覼 覶 覙 螺 蘿 蔂 萝 籮 箩 猡 氇 椤 儸 䯁 䊨 㼈 㑩 罗 啰 囉 䈁 躒 跞 礫 䲞 蟸 蠡 䉓 捋 㖀 䃕 㵣 䉿 㮝 蜾 猓 䙨 㕵 腡 脶 鉻 铬 㪾 䎅 詻 lÜ 䢖 㔧 率 绿 綠 鑢 虑 葎 膟 緑 箻 濾 滤 氯 慮 律 嵂 寽 勴 䥨 䔞 㲶 㠥 鋁 漊 溇 僂 偻 铝 郘 褸 褛 膐 膂 缕 縷 絽 穭 穞 稆 祣 梠 旅 捛 挔 履 屢 屡 呂 吕 儢 侶 侣 㾔 㻲 㭚 瘻 瘘 膢 驴 驢 馿 闾 閭 藘 爈 氀 櫚 櫖 榈 攞 魯 䕡 䮉 㢳 臚 鏤 簍 嶁 嵝 鞻 謱 樓 䮫 䣚 䝏 蔞 㡞 捋 lÜe 剠 㔀 稤 掠 擽 锊 鋢 鋝 畧 略 圙 䤣 䛚 䌎 䂮 㨼 㑼 率 ma 孖 麽 嚜 驀 抹 擵 攠 嗎 吗 嘛 㾺 㜫 獁 犸 榪 杩 骂 駡 閁 罵 禡 祃 睰 帓 嘜 唛 傌 䯦 㨸 㑻 㐷 螞 蚂 𥉵 鷌 鰢 马 馬 鎷 碼 码 瑪 玛 溤 䣖 䣕 蟆 㦄 䳸 麻 蟇 蔴 痲 犘 䗫 嬷 嬤 媽 妈 菻 貉 貈 䧞 mai 霡 衇 脉 脈 䘑 䈿 蝐 䨫 麦 麥 霢 邁 迈 賣 眿 売 卖 勱 劢 佅 䮮 䜕 鷶 買 蕒 荬 嘪 买 㜥 埋 薶 霾 䨪 䚑 䁲 㼮 䳸 貍 㦟 man 蹣 鮸 璊 樠 蔓 鄤 䝢 漫 曼 鬗 镘 鏝 蔄 缦 縵 獌 熳 澷 澫 慢 幔 嫚 墁 僈 䡬 䝡 䕕 㵘 㬅 㡢 㗈 滿 满 鏋 襔 蟎 螨 矕 満 屘 䜱 㛧 䑱 蹒 悗 瞞 瞒 㙢 谩 謾 槾 䛲 㗄 颟 顢 鳗 鰻 鬘 馒 饅 蠻 蛮 摱 慲 姏 䰋 䯶 䟂 䐽 䊡 䅼 㒼 䨫 埋 䒥 mang 庬 厖 矒 蠎 蟒 䖟 㙁 㬒 莽 莾 茻 硥 漭 壾 䒎 䁳 㟐 盳 盲 芒 㝑 鼆 尨 氓 䟥 㻊 㟿 牤 茫 駹 铓 鋩 釯 邙 蛖 蘉 笀 硭 痝 狵 牻 浝 汒 杧 杗 恾 忙 娏 哤 吂 䵨 䈍 䅒 䀮 㡛 㟌 䙪 㜃 䓼 奀 mao 毣 牟 瞀 艒 冒 袤 冐 瑁 㡌 芼 鄮 贸 貿 貌 蓩 萺 茂 耄 瞐 眊 皃 毷 楙 柕 暓 懋 帽 媢 䫉 䡚 䓮 䋃 䀤 㿞 㺺 㴘 㮘 㫯 㪞 㧌 㒻 㒵 泖 茆 笷 昴 戼 峁 夘 卯 冇 㧇 㚹 蝥 媌 蟊 㝟 毛 髦 牦 氂 鶜 髳 锚 錨 酕 軞 覒 茅 罞 矛 渵 枆 旄 嫹 堥 兞 䅦 㲠 猫 貓 㬒 铆 鉚 䭷 犛 䖥 㹈 me 么 麽 嚜 麼 mei 侎 穈 袂 䀛 䵢 煝 沬 魅 鬽 韎 跊 蝞 祙 睸 眛 痗 昧 抺 寐 媚 妹 䰪 䰨 䊊 䉋 㭑 䓺 每 黣 镁 鎂 美 燘 渼 浼 毎 挴 嵄 嬍 媺 媄 凂 䜸 䆀 䒽 没 沒 塺 㶬 莓 苺 郿 𪃏 黴 鹛 鶥 霉 镅 鎇 鋂 酶 葿 腜 脢 脄 篃 禖 睂 眉 瑂 珻 玫 猸 煤 湈 湄 槑 楳 楣 梅 栂 枚 攗 徾 嵋 媒 堳 呅 䤂 䍙 䊈 㺳 瑁 㙁 蝐 㜫 膴 䀜 䞼 men 亹 們 们 闷 悶 燜 焖 懣 懑 㵍 㱪 㦖 㥃 暪 㡈 䝧 㨺 穈 璊 樠 门 閅 門 钔 鍆 虋 菛 捫 扪 䫒 䊟 㻊 悗 瞞 瞒 㙢 meng 霧 黾 黽 霿 梦 夢 霥 溕 懜 孟 夣 䥰 䥂 䠢 㝱 㜴 㚞 蜢 懵 鯭 锰 錳 蠓 艋 瓾 猛 勐 䏵 苎 盟 萌 瞢 䓝 獴 幪 蒙 矒 鹲 鸏 鯍 饛 靀 雺 鄸 鄳 蝱 虻 蕄 萠 莔 艨 礞 矇 甿 甍 濛 氋 檬 橗 朦 曚 懞 冡 儚 䵆 䴿 䴌 䲛 䰒 䤓 䙩 䙦 䗈 䒐 䑅 䑃 䉚 䇇 䀄 㩚 㠓 㙹 蟊 䖟 鼆 尨 䟥 㻊 䝢 㽇 mi 獮 狝 禰 麑 擵 鑖 芈 糸 覛 䭩 䤉 䌩 䛉 䌏 㫘 宓 秘 泌 鼏 谧 謐 觅 覔 覓 蠠 蜜 藌 蔤 羃 簚 祕 熐 濗 漞 滵 淿 淧 汨 櫁 樒 榓 幦 幎 幂 峚 密 宻 塓 嘧 冪 冖 䮭 䣾 䛑 䖑 䌐 䉾 䁇 㸓 㵋 㴵 㳴 㨠 㜆 㰽 羋 㥝 濔 沵 靡 眯 侎 渳 銤 蔝 葞 脒 米 眫 灖 洣 敉 弭 孊 䱊 䭧 㳽 㝥 䪾 罙 㣆 祢 㜷 䌕 㩢 瀰 䋛 㠧 迷 谜 謎 糜 攠 𨢥 麛 麋 麊 鸍 镾 釄 醿 醾 醚 詸 蘼 蘪 蒾 縻 籋 瓕 獼 猕 爢 檷 擟 戂 彌 弥 冞 䴢 䥸 䤍 䛧 䕷 䕳 䍘 䌘 䊳 㸏 㟜 瞇 咪 㨺 䈿 㦄 佴 䊫 mian 靦 泯 黾 黽 緡 麺 麵 靣 面 糆 㴐 䤄 絻 娩 㤁 澠 㻰 麫 麪 鮸 葂 腼 缅 緬 眄 湎 沔 汅 愐 喕 勔 勉 冕 免 偭 丏 䀎 㛯 㮌 㬆 眠 醎 蝒 芇 臱 绵 緜 綿 矏 矊 矈 櫋 檰 棉 宀 嬵 媔 婂 䰓 䫵 䏃 䃇 㰃 㝰 㒙 䛉 䌏 㫘 㥝 㨺 㐷 厸 俛 㝃 miao 蜱 缪 繆 竗 玅 廟 庿 庙 妙 藐 眇 邈 缈 緲 篎 秒 渺 淼 杪 劰 䅺 㦝 鹋 鶓 鱙 苗 緢 瞄 描 䖢 䁧 㠺 㑤 喵 媌 mie 烕 眜 㒝 覕 鑖 鴓 鱴 衊 蠛 薎 蔑 篾 礣 灭 滅 櫗 搣 懱 幭 䩏 䘊 䈼 䁾 乜 芈 孭 哶 咩 吀 䌩 羋 㩢 min 賯 閺 䡅 皿 閔 暋 泯 渑 黾 黽 湣 鳘 鰵 闽 闵 閩 簢 笢 潣 敏 敃 抿 憫 慜 愍 悯 勄 刡 冺 僶 㨉 㥸 㞶 珉 玟 㟩 緡 䲄 敯 鍲 錉 鈱 苠 罠 缗 緍 碈 砇 盿 痻 瑉 琘 民 旼 旻 捪 怋 忟 忞 崏 岷 姄 䪸 䡻 䡑 䟨 䋋 䃉 䂥 䁕 㢯 㟭 澠 㮌 㬆 䝧 昬 䞀 ming 詺 命 䒌 眳 慏 姳 凕 㫥 㟰 瞑 溟 酩 茗 暝 鸣 鳴 铭 銘 鄍 覭 螟 蓂 眀 猽 洺 榠 朙 明 嫇 名 冥 佲 䫤 䊅 䆩 䆨 䄙 㝠 皿 䤉 䳟 miu 缪 繆 谬 謬 mo 獏 麽 庅 殁 歾 䜆 莫 縸 䁼 謩 藦 膜 眜 嚜 霡 衇 驀 𠬛 黙 默 魩 鬕 靺 陌 镆 鏌 銆 鄚 貘 貊 貃 袹 蟔 蛨 蓦 莈 茉 耱 纆 絈 粖 秣 礳 砞 瞙 眽 皌 瘼 爅 瀎 漠 湐 洦 沫 歿 枺 末 暯 昩 慔 帞 寞 嫼 妺 墨 塻 圽 嗼 䴲 䳮 䱅 䮬 䬴 䘃 䒬 䏞 䁿 㹮 㷵 㷬 㱳 㱄 抹 懡 䩋 䉑 橅 模 磨 擵 摩 魔 髍 馍 饝 饃 谟 謨 蘑 糢 摹 嫫 嚰 嚤 劘 䯢 䃺 摸 覛 䭩 䤉 䌕 攠 没 沒 塺 冐 脉 脈 䘑 㜥 㾺 䳟 㠢 鞨 貉 貈 mou 桙 敄 厶 鞪 恈 愗 踇 某 䍒 㭌 牟 缪 繆 麰 鴾 鍪 鉾 谋 謀 蟱 蛑 瞴 眸 洠 劺 侔 䱕 䥐 䗋 䏬 哞 霿 瞀 袤 蝥 䋷 㼋 䦈 㖼 mu 㒇 䧔 鞪 毣 鹜 霂 雮 钼 鉬 蚞 莯 苜 穆 睦 目 狇 牧 炑 沐 楘 木 暮 慕 幙 幕 墓 坶 募 仫 䑵 䊾 䀲 㾇 㧅 㣎 㜈 母 鉧 胟 砪 畮 畞 畝 畒 畆 牳 牡 拇 峔 姆 亩 䥈 恈 獏 譕 氁 毪 䱯 牟 莫 縸 䁼 橅 模 艒 㙁 畂 䮸 㫛 n 㐻 na 訤 箬 挐 娜 淰 痆 吶 讷 訥 呐 䱹 㴸 鈉 肭 䀑 䪏 䇣 那 䅞 魶 靹 钠 軜 貀 豽 袦 衲 蒳 纳 納 笝 捺 妠 䟜 䖧 䖓 䎎 䈫 䇱 㨥 㗙 哪 雫 乸 䫱 镎 鎿 誽 拿 拏 嗱 䛔 䏧 㙁 㭯 䞕 nai 儞 㲡 耐 鼐 錼 褦 螚 萘 渿 榒 柰 奈 倷 㮏 㮈 艿 妳 迺 疓 氖 廼 嬭 奶 乃 䍲 䘅 釢 熋 摨 䯮 㾍 䅞 㜷 䱞 佴 㚷 耏 㜨 nan 婻 䁪 䔳 罱 蝻 赧 腩 湳 揇 戁 䈒 㫱 䶲 難 难 䕼 南 諵 萳 莮 畘 男 楠 柟 枬 枏 暔 娚 奻 喃 侽 䛁 䔜 㽖 㓓 囡 䊖 㬮 囝 nang 蠰 孃 㒄 齉 儾 馕 饢 灢 曩 攮 㶞 䂇 欜 囊 嚢 乪 囔 nao 腝 臑 蟯 淖 鬧 闹 閙 腦 𡿺 脑 碯 瑙 惱 悩 恼 嫐 堖 垴 匘 䜧 䜀 㺁 㛴 㑎 䄩 髐 橈 桡 䑋 鐃 𥑪 𢜸 铙 譊 詉 繷 硇 獿 獶 猱 撓 挠 憹 怓 巙 巎 嶩 峱 夒 呶 䴃 䫸 䛝 䃩 㺀 㞪 䙹 孬 㧘 ne 呢 吶 讷 訥 呐 䭆 䎪 䅞 哪 眲 疔 nei 餧 䳖 㨅 內 氝 内 䡾 㘨 㖏 㕯 鯘 鮾 馁 餒 腇 脮 娞 䲎 㼏 䇣 㐻 䜆 nen 㜛 嫰 嫩 𡞾 㶧 㯎 齳 黁 㒄 neng 㲌 薴 能 嬣 䏻 㴰 䘅 䪏 ng 㕶 㐻 ni 晲 掜 嶷 殢 慝 灄 衵 濘 鹢 鹝 鷊 鷁 溺 昵 痆 逆 迡 膩 腻 胒 縌 糑 睨 氼 暱 愵 惄 屰 嬺 嫟 堄 匿 䵒 䵑 䘌 䁥 㲻 㦐 㥾 㠜 㵫 㣇 䭲 䧇 䕥 䰯 鉨 伲 禰 儞 馜 隬 铌 薿 苨 狔 柅 旎 擬 拟 抳 孴 儗 你 伱 䦵 㞾 狋 泥 坭 倪 䘽 鈮 䘦 呢 麑 秜 埿 齯 鲵 鯢 鯓 霓 郳 輗 跜 貎 觬 蜺 蚭 臡 籾 猊 淣 怩 屔 尼 婗 䝚 䛏 㹸 㪒 妮 㲡 妳 䍲 䀑 濔 沵 祢 㮞 䮘 nian 辗 輾 蹍 蔫 棯 齞 㲽 鼰 艌 念 廿 姩 埝 唸 卄 淰 䚓 涊 㘝 捻 碾 跈 辇 輦 躎 蹨 簐 攆 撵 撚 㞋 䩞 䄹 黏 拈 粘 鲶 鲇 鯰 鮎 秥 秊 年 䬯 䄭 䧔 溓 㮟 廾 niang 釀 酿 醸 䖆 孃 嬢 娘 niao 氽 尿 脲 㳮 㞙 䐁 䮍 鳥 鸟 𢸣 𢶑 褭 裊 袅 蔦 茑 樢 嬲 嬝 嫋 䦊 䙚 䃵 㭤 㠡 㜵 㒟 㼭 nie 槷 掜 諗 攝 摂 聶 聂 䜓 䄒 㩶 蘖 齧 颞 顳 隉 陧 闑 镍 镊 钀 鑷 鎳 躡 蹑 踂 蠥 菍 臲 臬 糵 糱 篞 疌 湼 涅 櫱 槸 棿 枿 敜 摰 帇 嵲 孽 孼 圼 囓 囁 嚙 噛 嗫 喦 啮 䯵 䯅 䯀 䌜 䂼 㸎 㴪 㮆 㜸 㚔 㙞 㘿 㖖 苶 㡪 鉩 錜 鑈 鈢 踗 揑 捏 惗 㘝 鉨 乜 㜦 峊 㟧 嶭 䞕 nin 拰 㤛 䛘 䚾 您 囜 䋻 ning 苧 攘 泞 䔭 濘 侫 佞 㿦 㣷 矃 橣 宁 寧 甯 寜 寗 寕 寍 擰 拧 聹 聍 鸋 鬡 鑏 獰 狞 檸 柠 嚀 咛 凝 儜 䭢 䗿 㲰 㝕 㩶 薴 niu 䋴 衂 狃 忸 鈕 靵 钮 莥 纽 紐 炄 扭 䏔 㺲 䀔 牛 䒜 妞 䂇 䤔 拗 nong 譨 弄 挊 䵜 齈 鬞 醲 辳 農 襛 蕽 膿 脓 穠 秾 禯 癑 濃 浓 欁 檂 噥 哝 农 儂 侬 䢉 䁸 㶶 䂇 挵 nou 䅶 䰭 䘫 鐞 鎒 譳 耨 獳 槈 啂 譨 羺 䨲 㝹 穀 䔈 㕢 檽 nu 帑 褥 挐 䢞 搙 抐 怒 胬 砮 弩 努 鴑 驽 駑 蒘 笯 孥 奴 伮 㚢 nuan 偄 煖 暖 㬉 䎡 䙇 餪 煗 渜 nun 黁 nuo 锘 鍩 撋 喏 挼 逽 蹃 诺 諾 糯 糥 穤 稬 搻 搦 掿 懧 懦 愞 䚥 㐡 砹 砈 橠 㡅 㛂 捼 挪 娜 郍 梛 儺 傩 㰙 㔮 㑚 䇔 䎟 nÜ 衄 朒 恧 䶊 䚼 䘐 䖡 㵖 女 钕 釹 籹 衂 狃 忸 肭 㮟 nÜe 乇 瘧 疟 谑 謔 虐 硸 䨋 䖋 䖈 o 噢 喔 哦 ou 㛏 漚 沤 慪 怄 䌔 䌂 䚆 䯚 塸 藕 蕅 腢 耦 吘 偶 㼴 㒖 齵 謳 嘔 呕 甌 歐 欧 毆 鏂 吽 鸥 鷗 鴎 讴 瞘 眍 瓯 熰 殴 櫙 㸸 pa 掱 帕 袙 怕 帊 杷 跁 筢 琶 爬 潖 䶕 䯲 夿 趴 蚆 葩 舥 皅 妑 啪 pai 迫 廹 腗 派 湃 𠂢 鎃 蒎 汖 哌 䖰 㭛 俖 輫 徘 㵺 排 簰 棑 簲 篺 猅 牌 俳 拍 䮘 pan 洀 瀋 爿 㳪 盼 袢 拚 頖 鑻 鋬 詊 襻 畔 牉 炍 溿 泮 沜 叛 判 冸 坢 奤 盤 䰉 䃲 蹣 蟠 磻 鞶 鎜 跘 蒰 縏 磐 盘 瀊 槃 柈 搫 幋 媻 䰔 䈲 䃑 潘 畨 砙 眅 攀 㐴 蹒 䙪 頄 㵗 砏 緐 䋣 番 䙃 pang 㜊 胖 肨 炐 覫 耪 嗙 䒍 篣 霶 庬 厖 逄 彷 旁 髈 螃 龐 龎 騯 雱 舽 胮 徬 庞 嫎 厐 䮾 䨦 䅭 㫄 㥬 㤶 乓 膖 滂 䂇 㝑 尨 倣 㑂 鳑 鰟 房 pao 㘐 泡 炮 麭 髱 靤 礮 礟 砲 皰 疱 奅 䶌 㯡 跑 䛌 炰 鞄 袍 龅 齙 軳 狍 爮 庖 垉 咆 匏 䩝 㚿 脬 拋 抛 刨 pei 錇 锫 淠 馷 霈 配 辔 轡 苝 笩 珮 浿 沛 旆 斾 帔 姵 佩 伂 䊃 㳈 㫲 㧩 㤄 昢 琣 培 㟝 邳 阫 陫 裴 陪 赔 賠 裵 毰 䲹 䫠 䪹 䣙 岯 垺 醅 衃 胚 肧 柸 怌 娝 妚 呸 輫 㣆 胐 艴 肺 朏 䡊 pen 翸 翉 湓 葐 盆 瓫 歕 噴 喷 喯 呠 濆 peng 軿 泙 甏 踫 碰 椪 掽 㼞 𡗗 皏 淎 捧 淜 蓬 膨 硼 澎 鵬 錋 堋 挷 鹏 鬔 鬅 髼 驡 韼 韸 鑝 輣 蟛 蟚 芃 纄 篷 竼 稝 痭 樥 椖 棚 朋 憉 彭 弸 塳 塜 埄 傰 倗 䴶 䰃 䡫 䄘 㥊 㛔 砰 抨 駍 閛 軯 磞 硑 烹 漰 梈 恲 怦 嘭 匉 㘐 㮟 pi 痦 䑄 潎 擗 辟 淠 萆 鸊 濞 鷿 闢 譬 礔 甓 澼 渒 揊 屁 嫓 媲 僻 䴙 䤨 䡟 䠘 䑀 㿙 㨽 䰦 䏘 仳 疋 隦 銢 諀 苉 脴 癖 痞 庀 崥 圮 嚭 噽 匹 䫌 䤏 䚹 䚰 玭 魾 錍 鈚 腗 脾 蜱 壀 芘 陴 纰 枇 螷 埤 犤 鼙 阰 郫 貔 豼 蚽 膍 肶 羆 罴 笓 皮 疲 琵 焷 毘 毗 朇 啤 㯅 㔥 苤 釽 劈 鲏 紕 鮍 駓 铍 鈹 鈈 髲 鴄 髬 霹 銔 鉟 豾 耚 翍 秠 秛 礕 磇 砒 狓 狉 炋 旇 抷 披 批 憵 悂 怶 坯 噼 伾 丕 㳪 㔃 䗄 否 㼰 pian 片 骗 騙 騗 䏒 㸤 㓲 諞 貵 覑 輧 谝 骿 骈 騈 駢 蹁 賆 諚 腁 胼 楩 楄 䮁 㼐 㛹 萹 鶣 頨 翩 篇 犏 媥 囨 偏 玭 piao 顠 篻 剽 票 驃 徱 慓 勡 僄 䏇 㺓 㬓 瞟 缥 縹 蔈 膘 殍 醥 皫 犥 㹾 㵱 㩠 闝 蚫 竂 瓢 淲 䴩 䕯 㼼 嘌 漂 螵 摽 魒 飘 飄 飃 薸 翲 旚 彯 莩 pie 嫳 鐅 丿 䥕 撇 撆 瞥 氕 暼 潎 覕 pin 聘 牝 䀻 榀 品 蘋 琕 频 頻 獱 颦 顰 贫 貧 薲 嬪 嫔 娦 嚬 㰋 礗 涄 拼 姘 玭 拚 ping 荓 甹 苹 軿 泙 鵧 屛 屏 𦚓 𠗦 鲆 鮃 郱 评 評 蛢 蚲 蓱 萍 艵 胓 聠 缾 簈 箳 竮 甁 瓶 玶 洴 枰 憑 慿 平 幈 帲 帡 坪 呯 凴 凭 䶄 䍈 㻂 㺸 頩 砯 焩 娉 俜 乒 聘 蘋 輧 淜 砰 㵗 po 攴 釙 醱 酦 迫 廹 魄 钋 醗 蒪 粕 砶 破 珀 狛 烞 炇 岶 䯙 䪖 䨰 䣮 䣪 䞟 䎊 䄸 㛘 颇 笸 尀 叵 㰴 鄱 皤 蔢 櫇 婆 嘙 㨇 頗 钷 鉕 潑 泼 癹 鏺 溌 坡 濼 䎅 䪙 䘠 嚩 㜑 緐 䮘 泊 pou 堷 咅 㕻 瓿 棓 犃 廍 婄 哣 勏 㧵 抙 錇 锫 掊 抔 裒 捊 剖 㰴 㟝 䯽 涪 pu 舗 舖 瀑 曝 㬥 䲕 檏 圤 溥 埔 誧 氆 镨 鐠 谱 譜 諩 烳 潽 浦 普 圃 㹒 蹼 樸 濮 襆 纀 轐 蒲 菩 葡 镤 鏷 酺 襥 蒱 菐 箁 穙 瞨 璞 獛 毞 匍 僕 䴆 䧤 䗱 䔕 䑑 䈻 䈬 㺪 㲫 㯷 㒒 铺 鋪 墣 攴 仆 擈 扑 陠 痡 撲 抪 噗 朴 莆 脯 鯆 苻 醭 qi 漬 陭 欹 蹊 谿 粞 溪 嵠 溼 趿 挈 緁 䟄 䰴 䙄 㞚 忔 䏌 氣 䚉 㼤 契 䫔 䌌 砌 㓞 鏚 泣 蟿 缉 汽 矵 鼜 迄 讫 諿 訖 葺 罊 綥 礘 磧 磜 碶 碛 盵 甈 炁 湇 湆 汔 気 气 棄 栔 暣 摖 憩 憇 徛 弃 夡 器 噐 咠 呮 䬣 䢀 䚍 䒗 䏠 䏅 䅤 䁉 䁈 䀙 䀈 㮑 㣬 綺 䔇 㾨 綮 䋯 㩩 㫓 㞓 豈 岂 邔 闙 起 諬 裿 芞 芑 绮 盀 槣 棨 杞 晵 敧 屺 婍 啟 啔 啓 唘 呇 启 企 乞 䭬 䭫 䡔 䛴 䒻 䏿 䎢 䉝 䄫 䄎 㥓 㒅 䧘 衹 祁 亝 圻 鮨 䱈 锜 錡 㜎 畦 耆 䧵 跂 颀 頎 荠 骑 騎 蘄 齐 齊 錤 踑 檱 棋 奇 其 祈 祇 芪 畁 麒 鶀 鵸 鳍 鲯 鰭 鯕 鬿 鬐 骐 騏 釮 鄿 迉 軝 蠐 蜞 蜝 蛴 蚚 蚔 蚑 藄 蕲 萕 艩 臍 脐 翗 纃 綨 綦 粸 竒 禥 祺 碕 碁 疷 璂 琪 琦 玂 猉 濝 淇 歧 櫀 棊 旗 旂 斊 斉 掑 懠 愭 忯 帺 崎 岓 岐 墘 埼 剘 亓 䶞 䶒 䳢 䲬 䰇 䭼 䭶 䩓 䡋 䟚 䞚 䓅 䑴 䐡 䉻 䅲 䄢 㯦 㩽 㟢 㟚 㟓 鸂 磎 棲 栖 沏 磩 妻 期 攲 諆 顣 郪 𠀁 鶈 魌 霋 萋 緀 漆 淒 欺 榿 桼 桤 柒 戚 慽 慼 悽 娸 墄 嘁 唭 凄 僛 倛 七 騹 愒 肵 偈 㦢 㓗 䶓 㹄 檵 㠱 䓫 㙨 齌 濟 玘 蟣 踦 焏 亟 㠎 㘍 㖢 㠍 緝 觭 稽 齎 饑 赍 賷 賫 朞 𣪠 虮 䛛 犵 隑 䔾 䠞 槭 刾 刺 䰍 薺 㝄 qia 㤉 䶝 䨐 䜑 㡊 洽 匼 殎 恰 帢 圶 䯊 㓣 卡 酠 跒 䠍 𠜼 掐 㓞 䶗 㰤 疴 髂 䂒 鮚 楬 㓤 葜 䁍 㵄 㦴 qian 葴 鍼 濽 鈆 蕁 燖 嗛 燅 孅 煔 雂 羥 綪 䈴 䫡 䦲 㯠 欠 倩 䥅 慊 茜 嵌 刋 輤 蔳 蒨 芡 篟 篏 皘 歉 槧 椠 棈 悓 壍 塹 堑 儙 傔 䊴 㪠 㟻 㜞 㐸 脥 㧄 遣 䪈 淺 撖 谴 譴 蜸 缱 繾 浅 槏 嵰 䭤 䍉 䨿 燂 鬵 㩮 揵 钱 錢 鈐 漧 鉗 黚 黔 鰬 騚 钳 钤 銭 虔 葥 箝 灊 濳 潜 潛 歬 榩 掮 拑 扲 忴 岒 媊 前 仱 䖍 䕭 䈤 䁮 㸫 㨜 㦮 铅 鉛 肷 鋟 锓 顩 羟 謙 谦 芊 縴 牽 牵 膁 騫 迁 鹐 鵮 鬝 鬜 骞 韆 阡 钎 鐱 釺 遷 谸 譣 諐 褰 蚈 臤 粁 籤 簽 签 汧 汘 欦 櫏 檶 杄 攓 攑 攐 撁 搴 掔 拪 扦 慳 愆 悭 幵 岍 孯 婜 奷 圲 圱 千 兛 僉 佥 仟 㡨 㡊 䆂 䃛 䙺 厱 挳 齦 䔔 䋮 䵖 腱 䭠 䅐 䯡 犍 鶼 唊 乾 乹 㥞 㹂 qiang 啌 艢 羻 熗 炝 唴 䵁 䅚 搶 抢 羥 勥 繦 繈 磢 墏 傸 㛨 㩖 薔 蔷 强 強 彊 爿 軖 蘠 牆 漒 檣 樯 廧 嬙 嫱 墻 墙 丬 鎗 蹡 蹌 跄 戗 嗆 呛 镪 鏹 戕 腔 矼 槍 枪 锵 锖 鏘 錆 謒 蜣 羫 羗 羌 篬 瑲 玱 猐 牄 溬 椌 斨 嶈 羟 弜 嵹 襁 𤕭 qiao 銚 舃 舄 箾 荍 墧 碻 殻 鞘 髚 韒 陗 躈 诮 誚 竅 窍 撽 撬 帩 峭 僺 俏 䇌 䆻 䃝 㴥 㪣 㢗 釥 愀 悄 巧 䲾 㤍 㡑 㚽 䀉 㚁 谯 譙 翹 翘 趬 蕎 荞 顦 鞽 鐈 趫 藮 礄 硚 瞧 癄 燆 橋 樵 桥 憔 嶣 嘺 喬 僑 侨 乔 䱁 䩌 䎗 㝯 骹 橇 蹺 磽 蹻 髜 頝 鞒 锹 鐰 鏒 鍬 鍫 鄥 鄡 郻 踍 跷 繑 硗 敲 幧 嵪 墽 墝 劁 㨽 殼 壳 丂 醮 嶠 峤 㩰 簥 燋 跤 毳 qie 渫 嗛 唼 㥦 䬊 㹤 㤲 㛙 挈 洯 緁 鯜 锲 鍥 踥 蛪 藒 篋 箧 笡 竊 窃 穕 淁 朅 愜 惬 悏 怯 妾 匧 䤿 䟙 㾜 㾀 㰼 㰰 㫸 㛍 㗫 㓶 且 㚗 䦧 茄 癿 切 慊 㼤 䫔 䌌 沏 䶗 趄 蛣 蕺 鰈 脞 qin 蓁 溱 菣 沁 撳 搇 揿 抋 寴 唚 吣 吢 䈜 㤈 㞬 䠴 赾 螼 曋 昑 寢 寝 寑 坅 㾛 㝲 芩 䖌 雂 靲 厪 鵭 鳹 鈙 赺 蠄 螓 蚙 菦 芹 耹 秦 禽 琹 琴 珡 澿 檎 斳 擒 捦 懄 懃 庈 嫀 噙 嗪 勤 䦦 䔷 㮗 㪁 㩒 㢙 㘦 亲 綅 親 欽 瀙 顉 鮼 骎 駸 钦 誛 衾 嶔 嵚 媇 侵 㛙 䥅 鋟 锓 顩 蘄 㓎 㕋 寖 䶖 䥆 槿 廑 菫 䇒 頜 㱽 qing 苘 䌠 謦 磬 鑋 靘 罄 磘 碃 漀 汫 殸 掅 慶 庆 凊 䋜 请 請 顷 頃 檾 廎 庼 䯧 䔛 㷫 䲔 剠 殑 檠 黥 晴 甠 樈 暒 晴 擎 情 夝 勍 䞍 䝼 㯳 鲭 鯖 輕 清 氰 青 蜻 靑 郬 轻 軽 狅 淸 氫 氢 寈 圊 啨 卿 傾 倾 綮 䋯 㩩 㔀 㵾 擏 䵞 㢣 渹 qiong 苘 瓊 䛪 䆳 跫 穹 璚 輁 蛩 邛 赹 藭 藑 茕 筇 笻 竆 窮 穷 瞏 睘 琼 煢 焭 橩 棾 桏 惸 宆 卭 儝 䠻 䓖 䊄 䅃 㼇 㷀 㮪 㧭 㒌 芎 銎 匔 焪 㑋 䧆 蛬 㤨 qiu 氽 螑 殏 䠗 䟬 㼒 糗 搝 䞭 泅 䎿 鰌 遒 艽 蝤 朹 钆 鼽 鰽 鯄 鮂 銶 釚 酋 逑 逎 赇 賕 訅 訄 觩 裘 蛷 虯 虬 莍 苬 脙 肍 絿 紌 盚 皳 璆 球 玌 犰 煪 渞 浗 汓 求 毬 梂 扏 巰 巯 崷 囚 唒 叴 厹 俅 䤛 䣇 䟵 䜪 䊵 㺫 㷕 㭝 㧨 㥢 㤹 㟈 㞗 㕤 㐤 蓲 𩝠 𠀉 龝 鹙 鶖 鳅 鱃 鰍 鞧 鞦 邱 趥 蠤 蟗 蝵 蚯 萩 緧 篍 穐 秌 秋 楸 恘 媝 坵 丠 丘 䆋 㐀 㧄 頄 馗 頯 䊆 捄 鳩 觓 䔔 湫 㲹 龜 釓 仇 qu 騶 诎 湨 趣 鼁 麮 阒 闃 閴 觑 覻 覷 覰 去 厺 刞 䠐 䒧 䁦 㰦 㫢 㧁 取 龋 齲 詓 紶 筁 竬 浀 娶 䶚 蘧 㖆 麴 麯 渠 懅 籧 軥 鴝 𪍸 鼩 麹 鸲 鸜 鑺 躣 豦 衢 蠷 蟝 螶 蕖 葋 菃 臞 胊 翵 翑 磲 癯 璩 璖 灈 淭 氍 欋 朐 斪 戵 忂 匷 劬 佢 䵶 䟊 䞤 䝣 䋧 䂂 䀠 㲘 㯫 㣄 㜹 黢 曲 區 区 镼 鶌 砠 抾 趨 趋 詘 鱋 鰸 魼 髷 驱 驅 駈 駆 阹 軀 躯 誳 袪 蛐 胠 祛 敺 憈 嶇 岴 岖 屈 坥 呿 匤 凵 佉 伹 㠊 㤲 㚁 脥 䌌 㽛 䏣 蠼 苣 䆽 瞿 鐻 遽 蚷 絇 䅓 竘 䗇 鞫 䢗 鉤 䠓 quan 謜 烇 絭 牶 勸 勧 劝 券 䄐 甽 縓 琄 詃 虇 绻 綣 畎 犬 汱 奆 呟 䊎 跧 鷤 啳 婘 蜷 醛 荃 輇 齤 鳈 鰁 鬈 騡 駩 颧 顴 铨 銓 辁 踡 诠 詮 觠 蠸 葲 筌 硂 痊 瑔 犈 牷 湶 洤 泉 權 権 权 搼 拳 惓 恮 巏 峑 孉 全 佺 䠰 䟒 䑏 䀬 㟫 㟨 㒰 棬 圈 鐉 絟 箞 悛 弮 姾 圏 䅚 㩲 腃 劵 桊 獾 䌯 鸛 荈 que 舃 闕 咑 墧 雀 碻 殻 阙 闋 舭 鹊 鵲 阕 趞 礭 礐 確 碏 确 硞 皵 琷 燩 灍 毃 榷 搉 慤 愨 悫 崅 寉 塙 埆 卻 却 䧿 䦬 䇎 㾡 㴶 㱿 㱋 㰌 㩁 㕁 瘸 𩨭 蒛 缺 㹤 䢧 攉 䲵 㹱 觳 炔 䀇 䍳 qun 蝽 裠 裙 群 羣 帬 宭 䭽 㿏 㪊 逡 踆 鰆 峮 夋 囷 麕 麇 䆽 錞 漘 輴 杶 ran 蚒 㯗 呥 苒 珃 橪 染 媣 姌 冉 冄 䤡 䣸 䒣 䎃 㿵 㚩 蛅 蚺 蚦 㾆 𤡮 髯 髥 袡 袇 衻 肰 繎 燃 然 嘫 䫇 䖄 䑙 㸐 㲯 㜣 䰯 㒄 䔳 䶲 䳿 㹱 䇋 rang 纕 蠰 攘 让 讓 譲 懹 嚷 爙 壤 壌 勷 瀼 穰 䉴 鬤 躟 蘘 穣 禳 瓤 獽 儴 㚂 孃 䑋 rao 挐 遶 绕 繞 顤 隢 擾 扰 嬈 娆 㑱 蕘 荛 蟯 饶 饒 襓 蛲 䫞 㹛 橈 桡 繚 re 爇 焫 渃 熱 热 喏 惹 㻰 ren 䀼 鵀 紝 任 饪 餁 飪 韧 韌 靱 靭 轫 軠 軔 讱 认 認 訒 袵 衽 肕 纫 紉 牣 梕 杒 扨 恁 屻 姙 妊 刄 刃 仭 仞 䋕 䇮 㸾 㶵 㠴 䏕 腍 棯 荵 荏 稔 秹 栣 栠 忍 䭃 䏰 㣼 䴦 纴 絍 鴹 魜 銋 鈓 芢 秂 朲 忎 忈 壬 仁 亻 人 䌾 䀔 㤛 䛘 䚾 䄒 㲽 涊 賃 reng 芿 䄧 陾 辸 礽 仍 䚮 㺱 㭁 扔 穰 艿 ri 衵 日 驲 馹 鈤 釰 氜 囸 䒤 rong 傛 滽 瀜 訟 縟 鴧 䢇 軵 氄 搑 宂 冗 傇 㲝 鷛 鰫 駥 茸 䩸 䡆 䇀 肜 髶 镕 鎔 褣 蠑 螎 融 蝾 蓉 荣 茙 羢 绒 縙 絨 穁 瑢 狨 爃 熔 烿 溶 毧 榵 榮 榕 栄 曧 戎 嶸 嵘 容 媶 䤊 䡥 䠜 䘬 䈶 䇯 㼸 㺎 㲨 㲓 㭜 㣑 㝐 㘇 䄧 䋴 隔 rou 肉 宍 䄾 糅 粈 煣 䐓 輮 鶔 鰇 騥 韖 鞣 鍕 鍒 蹂 蝚 葇 腬 脜 禸 瓇 瑈 渘 沑 楺 柔 揉 媃 䰆 䧷 㽥 㖻 䢇 擾 扰 䋴 䥆 㮟 ru 鑐 蝡 鄏 洳 縟 褥 蓐 缛 溽 媷 嗕 入 傉 擩 辱 㦺 铷 肗 汝 侞 乳 蠕 㨎 㹘 孺 銣 濡 挐 臑 鴽 鱬 颥 顬 醹 邚 襦 袽 薷 蕠 茹 筎 燸 渪 桇 曘 帤 如 嚅 儒 䰰 䋈 䐓 䰭 䘫 䋴 䫱 䤉 㾒 㼋 㨌 䞕 ruan 蝡 阮 腝 软 輭 軟 耎 緛 礝 碝 盶 瓀 瑌 朊 媆 䪭 䞂 㽭 㼱 䓴 撋 壖 堧 蠕 㨎 䎡 䙇 㜛 㓴 䪀 㮕 䆓 䙃 rui 㛱 䓲 芮 锐 銳 鋭 蜹 蚋 睿 瑞 汭 枘 壡 叡 䌼 㲊 㪫 㓹 惢 蕊 蘃 蘂 蕋 繠 橤 桵 䅑 蕤 緌 甤 㮃 擩 㹘 㨅 鈉 㕙 䞩 䍴 㻔 䇤 䂱 䳠 run 闰 閠 閏 膶 潤 润 橍 䦞 㠈 瞤 犉 䏕 㝄 ruo 爇 焫 若 箬 婼 鶸 鰯 鰙 鄀 蒻 篛 楉 弱 叒 偌 䐞 渃 挼 捼 㬉 蠚 sa 躠 闟 潵 㳐 㪪 趿 䘮 颯 鎝 馺 飒 薩 萨 脎 櫒 攃 摋 卅 䬃 䙣 㽂 靸 㒎 灑 洒 䊛 𥋌 撒 仨 钑 鈒 䑥 sai 毸 噻 赛 賽 簺 嗮 僿 䈢 㗷 鳃 鰓 塞 顋 腮 毢 揌 愢 san 蔘 㪔 散 潵 閐 俕 䫅 㪚 㤾 鏾 糣 糝 馓 饊 繖 糤 糂 傘 伞 仐 䫩 䊉 䉈 䀐 㧲 攕 弎 三 糁 鬖 犙 毿 毵 嘇 叁 参 參 叄 sang 颡 顙 鎟 褬 磉 搡 嗓 䫙 䡦 喪 丧 桒 桑 䘮 sao 䖣 埽 矂 氉 喿 䐹 㿋 掃 扫 嫂 䕅 㛮 搔 缫 繅 鰺 𦞣 臊 瘙 騷 骚 慅 鳋 鱢 鰠 騒 颾 溞 掻 se 漬 鎩 㻭 㴔 㮦 色 翜 歰 飋 雭 铯 銫 轖 趇 譅 繬 穡 穑 璱 瑟 瀒 濇 澁 澀 涩 歮 懎 嗇 啬 䨛 䔼 䉢 㱇 㥶 㒊 㻎 㺩 㽇 槭 sen 槮 椮 襂 蔘 篸 穼 甧 森 曑 seng 鬙 僧 sha 霅 檆 閷 㚫 䮜 唼 廈 厦 歃 䵘 箑 啑 𠚺 霎 閯 萐 翣 帹 喢 啥 倽 䶎 䝊 䈉 㰱 㛼 訯 儍 傻 莎 髿 鎩 沙 𧜁 煞 殺 杀 紗 帴 鲨 鯋 鯊 鮻 魦 铩 裟 蔱 纱 粆 硰 砂 痧 猀 樧 榝 桬 唦 乷 翜 歰 䬊 䀉 擑 䯫 㵤 剎 刹 shai 釃 酾 纚 閷 曬 晒 㬠 繺 篩 筛 㩄 䵘 shan 樿 椫 橏 鳣 鱣 掺 陜 鯅 煔 摲 䦅 掞 鱓 䱇 汕 钐 釤 扇 蟺 赡 贍 鳝 鱔 骟 騸 饍 鐥 銏 鄯 赸 讪 譱 謆 訕 蟮 膳 缮 繕 磰 疝 熌 灗 擅 嬗 墡 墠 善 僐 傓 䴮 䱉 䦂 䥇 䚲 䆄 䄠 㪨 㣌 陿 㶒 䠾 㣣 鿃 陝 陕 闪 閃 醦 覢 睒 晱 㪎 㨛 㚒 彡 芟 苫 煽 烻 檆 杉 脠 穇 𠚹 邖 軕 跚 衫 舢 羶 羴 縿 笘 珊 狦 澘 潸 搧 挻 幓 山 姗 姍 剼 刪 删 襂 㾆 㴸 㬭 痁 㚲 潬 膻 掸 單 单 shang 曏 丄 蠰 尚 尙 鑜 銄 姠 上 赏 賞 晌 扄 䬕 鬺 謪 觴 觞 螪 蔏 熵 漡 滳 殤 殇 慯 墒 商 傷 伤 垧 愓 裳 shao 燿 笤 苕 䏴 睄 紹 颵 邵 袑 绍 綤 潲 娋 哨 卲 劭 佋 䬰 䙼 㷹 少 䔠 䒚 㪢 勺 芍 㸛 杓 韶 竰 玿 牊 㲈 蛸 梢 艄 稍 燒 髾 輎 莦 筲 焼 烧 旓 捎 弰 she 讋 畲 畬 歙 摵 鉇 鉈 釶 懾 慴 慑 䀅 射 䁯 㢵 䵥 䄕 舍 猞 攝 摄 摂 灄 渉 涉 赦 麝 韘 设 設 蠂 蔎 社 滠 欇 弽 厙 厍 䤮 䠶 䌰 㴇 㒤 騇 捨 䬷 蛇 虵 㰒 揲 䂠 鍦 舌 𧵳 蛥 佘 䞌 䁋 赊 賒 奓 輋 賖 譇 檨 奢 䏴 聶 䜓 䜆 蛞 䀹 䰥 䕣 阇 闍 䠟 shen 襳 搷 黮 什 椹 㥲 葚 滲 渗 鋠 蜃 腎 脤 肾 眘 眒 瘮 瘎 瘆 涁 昚 慎 愼 侺 䆦 㵕 㰮 㵊 吲 㰂 諗 瀋 魫 頥 頣 邥 谉 谂 讅 訠 覾 矧 矤 瞫 渖 弞 審 宷 审 嬸 婶 哂 㾕 㜤 㔤 甚 神 神 䰠 身 莘 姺 甡 胂 鉮 鵢 鲹 鯵 駪 诜 詵 訷 裑 薓 葠 绅 紳 籸 籶 砷 申 珅 燊 深 氠 柛 扟 峷 屾 娠 妽 呻 兟 侁 伸 䄕 㶒 槮 椮 襂 蔘 鰺 㛙 䧵 淰 䚓 罙 㚞 罧 綝 伔 沈 参 參 叄 sheng 琞 胜 勝 圣 晟 盛 賸 貹 蕂 聖 榺 嵊 墭 剰 剩 䞉 䎴 䚇 箵 䪿 省 眚 偗 䁞 㾪 㼳 㗂 繩 绳 鱦 譝 畻 溗 晠 憴 䱆 狌 鼪 鵿 陞 阩 鉎 苼 聲 笙 甥 生 珄 牲 焺 湦 泩 殅 昇 斘 声 呏 升 甡 澠 䋲 shi 跱 檡 醳 繹 埶 釃 酾 纚 佀 識 氏 謚 釋 释 昰 鳀 鯷 忕 㮶 识 示 叓 适 適 飾 翨 栻 𢂑 𠀍 齛 饰 餝 餙 铈 銴 鉽 鉃 鈰 釈 遾 逝 轼 軾 贳 貰 谥 试 諡 諟 誓 試 视 視 襫 舓 舐 簭 筮 礻 睗 眎 眂 烒 澨 柿 柹 枾 是 揓 拭 戺 戠 恃 弒 弑 式 市 崼 室 嬕 奭 士 噬 嗜 呩 卶 卋 勢 势 冟 侍 仕 事 亊 丗 世 䰄 䭄 䩃 䤱 䟗 䛈 䏡 䊓 䁺 㹝 㸷 㱁 㔺 㒾 㹷 屎 使 驶 駛 鉂 豕 笶 矢 宩 始 史 兘 乨 䦠 䒨 㹬 㕜 㫑 䶡 㖷 食 䂖 蒔 莳 蝕 拾 石 𥐘 鼭 鼫 鲥 鰣 饣 飠 鉐 遈 蚀 祏 炻 溡 湜 湁 榯 時 旹 时 峕 實 寔 実 实 塒 埘 十 乭 䦹 䖨 㵓 鉇 施 鉈 釶 濕 溼 湿 呞 鸤 鶳 鳾 鳲 鲺 鰤 鯴 鈟 邿 诗 詩 襹 褷 蝨 虱 蓍 蒒 葹 絁 箷 獅 狮 溮 湤 浉 師 师 屍 尸 失 䴓 䂠 鍦 篩 鎩 灑 耆 䤭 咶 赫 遰 䲽 䄷 匙 shou 璹 鏉 绶 綬 瘦 痩 獸 狩 涭 授 寿 夀 壽 售 受 兽 䛵 㥅 㖟 䭭 守 掱 首 艏 手 垨 㝊 荍 收 収 shu 鐲 杼 术 鷸 腧 兪 鄃 俆 翛 涑 籔 藪 庻 澍 朮 䎉 潄 漱 數 数 曙 鮛 𠲿 鶐 鏣 錰 鉥 述 豎 裋 袕 術 蒁 荗 絉 竪 竖 濖 沭 樹 樜 树 束 戍 恕 庶 尌 墅 凁 侸 䩱 䢤 䝂 䜹 䘤 䉀 䆝 㾁 㽰 㷂 㶖 㣽 㜐 㛸 屬 属 钃 䠱 盨 㳆 䩳 㟬 𡱆 鼡 鼠 黍 襩 蜀 藷 薯 薥 署 癙 潻 暑 婌 䞖 䑕 㻿 㯮 㒔 䃞 贖 秫 鸀 襡 䝪 菽 淑 虪 熟 跾 赎 焂 掓 尗 孰 塾 埱 䴰 舒 毹 蔬 輸 疏 疎 鵨 陎 输 軗 踈 纾 綀 紓 殳 殊 橾 樞 梳 枢 杸 書 攄 摴 摅 抒 姝 叔 儵 倐 倏 书 璹 䭭 疋 䢞 䙱 䠼 㫹 蜍 樗 shua 誜 耍 刷 唰 shuai 帥 帅 蟀 繂 咰 卛 䢦 甩 衰 缞 摔 孈 率 縗 shuan 揎 涮 䧠 闩 閂 栓 拴 shuang 䡯 灀 㦼 騻 爽 縔 樉 慡 塽 䫪 䗮 㼽 鹴 鸘 鷞 骦 驦 霜 雙 艭 礵 欆 孇 孀 双 瀧 滝 泷 䔪 淙 shui 脽 挩 税 稅 裞 蜕 祱 瞓 睡 涚 涗 帨 娷 䭨 㽷 水 谁 誰 䲧 㥨 㝽 shun 眴 鬊 顺 順 蕣 舜 瞬 瞚 橓 䑞 䀵 䀢 㥧 賰 楯 揗 吮 㯗 䴄 䞐 輴 shuo 濯 爚 燿 溯 鑠 箾 揱 獡 碩 硕 爍 烁 铄 鎙 蒴 矟 洬 欶 槊 朔 搠 妁 䌃 䈾 䀥 説 說 说 哾 㮶 㸛 䁻 si 苡 飴 菥 鼶 锶 㾅 㹑 㐌 䎣 䇃 肆 佀 似 俟 伺 飼 驷 駟 饲 飼 飤 鈻 釲 貄 蕼 肂 耜 笥 竢 禩 祀 牭 瀃 涘 洍 泤 泗 汜 柶 杫 巳 寺 孠 娰 姒 四 嗣 兕 儩 亖 䦙 䏤 㸻 㭒 㣈 㚶 㕽 死 虒 澌 撕 嘶 鍶 思 覗 厶 鸶 鷥 騦 飔 颸 鐁 鋖 鉰 蟴 蟖 螄 蜤 蛳 蕬 罳 缌 纟 緦 絲 糹 籭 簛 私 禠 禗 磃 燍 泀 榹 楒 斯 廝 媤 噝 咝 司 厮 凘 偲 丝 䂖 糸 梩 㜦 䃽 賜 祠 song 縱 忪 颂 頌 讼 訟 餸 送 诵 誦 宋 䢠 䛦 㮸 㕬 䜬 駷 聳 耸 竦 楤 捒 慫 愯 悚 怂 嵷 傱 䉥 㩳 㨦 㧐 淞 凇 锶 鬆 蜙 菘 硹 濍 檧 梥 柗 枀 松 憽 庺 嵩 崧 娀 倯 漎 鏓 樬 sou 涑 膄 瘶 嗽 㵻 㛐 滫 擻 擞 籔 藪 𥈟 薮 瞍 櫢 嗾 叟 叜 傁 䮟 䏂 䉤 䈹 㖩 溲 𢲷 騪 馊 餿 飕 颼 锼 鎪 醙 鄋 螋 蒐 獀 摉 搜 捜 廋 廀 嗖 㟬 艘 su 䘻 蓿 宿 溹 窣 涑 愬 栜 鹔 鷫 鱐 骕 驌 餗 鋉 遬 遡 速 趚 谡 诉 謖 誎 訴 觫 蜶 藗 蔌 膆 肅 肃 縤 素 粟 粛 簌 碿 璛 珟 玊 潥 溸 泝 殐 橚 樕 榡 憟 愫 嫊 夙 塑 塐 嗉 僳 傃 䥔 䛾 䔎 䑿 䏋 䎘 䌚 䅇 䃤 㴼 㴑 㴋 㯈 㬘 㪩 㩋 㨞 㝛 㜚 㕖 㔄 㓘 㑛 㑉 俗 蘇 酥 蘓 苏 穌 稣 甦 櫯 囌 䩳 㥛 䇤 suan 篹 選 蒜 算 筭 笇 祘 㔯 匴 狻 酸 痠 㱹 sui 雟 𡑞 隧 㒸 遂 繐 鐩 鐆 邃 賥 谇 譢 誶 襚 繸 繀 穟 穗 穂 禭 祟 碎 砕 睟 瓍 璲 燧 煫 澻 歳 歲 檖 檅 旞 嵗 岁 嬘 埣 亗 䥙 䡵 䠔 䔹 䍁 䉌 䅗 㻽 㻪 㴚 㞸 巂 髓 髄 膸 瀡 䯝 䭉 隋 隨 随 遀 䢫 䜔 㻟 㵦 芕 荽 绥 綏 毸 眭 鞖 雖 虽 荾 睢 熣 濉 滖 浽 攵 夊 哸 倠 䅑 䆳 尿 䜆 䤭 葰 靃 蔧 篲 彗 䲀 㥞 縗 sun 鶽 隼 栒 跣 潠 愻 㡄 㦏 鎨 簨 箰 筍 笋 榫 損 损 䁚 㔼 孫 孙 飱 飧 薞 蕵 蓀 荪 猻 狲 槂 搎 㰂 䐣 suo 獻 犧 牺 逤 䗢 䣔 㪽 摵 𧴪 锁 鏼 鏁 鎻 鎖 鎍 褨 索 瘷 璅 瑣 琐 溑 洓 暛 擌 所 嗩 唢 䵀 䞽 䞆 䖛 䐝 䈗 䅴 䂹 羧 梭 蹜 缩 縮 蓑 趖 莏 簔 簑 樎 桫 摍 挲 挱 娑 嗦 嗍 唆 傞 溹 髿 㮦 逡 睃 䌇 ta 闟 牠 傝 䍝 䂿 鳎 鰨 獭 踏 溻 漯 遝 躂 跶 羍 沓 搨 龘 龖 鮙 鞳 鞜 阘 闼 闥 闒 鑉 鎉 錔 遢 躢 蹹 蹋 譶 誻 狧 濌 澾 涾 毾 橽 榻 撻 挞 崉 嚺 嚃 嗒 亣 䶁 䶀 䵬 䜚 䓠 䑜 䎓 䍇 䌈 䈳 䈋 㿹 㹺 㳫 㳠 㯓 㭼 㧺 㣵 㣛 㛥 㒓 獺 榙 墖 塔 㺚 㗳 它 禢 祂 她 塌 他 鉈 铊 趿 靸 䠅 鞈 䪚 達 韃 䳴 䑽 tai 㑷 曃 钛 鈦 酞 舦 肽 燤 溙 泰 汰 態 态 忲 夳 太 䣭 㥭 臺 台 䢰 䑓 苔 駘 鲐 鮐 骀 颱 邰 跆 薹 菭 籉 炲 炱 檯 旲 擡 抬 嬯 坮 冭 儓 䈚 㸀 㷘 㬃 㣍 㙵 㘆 㒗 胎 孡 囼 忕 奤 斄 tan 蟫 蕈 蕁 赕 賧 探 傝 碳 炭 湠 歎 埮 嘆 叹 僋 䜖 䐺 襢 袒 禫 黮 贉 醓 菼 璮 毯 憻 憳 忐 坦 嗿 䦔 䞡 䏙 䆱 㲭 潭 镡 鐔 錟 锬 㷋 㲜 檀 覃 艢 驔 餤 惔 醰 醈 郯 貚 谭 谈 譚 談 藫 罎 罈 痰 榃 曇 昙 憛 婒 壜 壇 墵 墰 坛 嘾 倓 䕊 䊤 䉡 䃪 㽑 舚 緂 橝 灘 嘽 啴 贪 貪 譠 舑 癱 瘫 滩 攤 擹 摊 抩 怹 坍 㶒 㪔 㒎 漢 舕 㵅 钽 鉭 㫜 彈 弹 膻 䨢 癉 撢 㽎 㛶 tang 餳 鐋 燙 趟 𨌩 铴 烫 摥 䟖 帑 偒 淌 𢠵 戃 倘 镋 钂 鎲 躺 耥 矘 爣 曭 儻 傥 伖 㿩 㒉 膛 樘 闛 鶶 饄 餹 隚 鎕 醣 鄌 踼 赯 螳 螗 薚 蓎 膅 糛 糖 糃 篖 禟 磄 瑭 煻 漟 溏 橖 榶 棠 摚 搪 塘 堂 啺 唐 傏 䧜 䣘 䌅 䉎 䅯 㼺 㲥 㭻 㜍 㙶 㑽 湯 汤 鏜 𧼮 鼞 镗 蹚 蝪 羰 坣 嘡 劏 㼒 逿 蕩 攩 擋 鐺 tao 套 㚐 䚯 讨 討 䵚 䚵 洮 绹 綯 錭 陶 檮 梼 鼗 騊 駣 饀 鞉 鞀 鋾 醄 逃 迯 裪 萄 祹 淘 桃 啕 咷 匋 䬞 㹗 韜 濤 涛 轁 饕 飸 韬 鞱 謟 詜 蜪 翢 绦 縧 縚 絛 瑫 滔 槄 搯 掏 慆 弢 嫍 䱇 䛌 燾 焘 te 職 犆 慝 鴏 铽 鋱 貣 蟘 蚮 脦 特 棏 忒 忑 㧹 㥂 teng 蕛 螣 鰧 驣 騰 駦 邆 謄 誊 藤 腾 縢 籘 籐 疼 漛 滕 幐 儯 䲢 䲍 䠮 䕨 䒅 鼟 膯 ti 擿 躍 洟 苐 鮧 錫 裼 趯 䧅 锑 殢 揥 鬄 髢 籊 𡲕 鬀 髰 鐟 逷 逖 迏 褅 薙 睼 涕 歒 替 掦 惖 惕 悐 悌 屜 屉 嚔 嚏 剃 倜 俤 䶑 䯜 䙗 䎮 㯩 㬱 㗣 䶏 體 骵 体 軆 躰 挮 䪆 䣽 䌡 䝰 禔 荑 䣡 绨 綈 䚣 醍 鵜 鼶 题 題 蹏 蹄 媞 提 鹈 鶙 鶗 鮷 騠 鍗 遆 趧 謕 褆 蝭 罤 缇 緹 稊 禵 碮 瑅 漽 惿 崹 媂 嗁 啼 厗 偍 䬾 䨑 䛱 䔶 䅠 㣢 㡗 㖒 銻 梯 踢 鷉 鷈 剔 䴘 䢰 鳀 鯷 適 㖷 䣠 弟 䶍 䞶 谛 諦 珶 䱱 睇 詆 隄 堤 達 tian 鎭 紾 磌 頲 颋 瑱 煔 掭 㶺 㮇 䐌 㐁 舔 锘 鍩 靦 餂 錪 賟 觍 覥 腆 睓 淟 殄 晪 悿 忝 唺 䩄 䣯 䠄 䄽 䄼 㥏 㙉 㖭 鷏 鷆 盷 搷 𧰊 阗 闐 菾 胋 窴 畑 畋 田 甜 甛 璳 湉 沺 恬 屇 填 塡 䥖 䡘 䡒 䟧 䑚 㧂 添 黇 靝 靔 酟 沗 婖 天 兲 倎 緂 㑷 䄕 苫 蚺 蚦 䩞 䄹 㤁 䣶 䏦 栝 钿 鈿 tiao 踔 铫 銚 脩 脁 窱 朓 跳 覜 絩 糶 粜 眺 嬥 窕 誂 晀 宨 䠷 㸠 䩦 䖺 㑿 鯈 䒒 笤 苕 蜩 龆 齠 鲦 鰷 髫 鞗 鎥 鋚 迢 趒 萔 芀 祒 樤 條 条 岹 岧 䳂 䱔 䯾 䟭 䎄 㟘 鮡 挑 蓨 聎 祧 旫 恌 庣 佻 頫 㕮 调 䂪 蓧 䧂 tie 餮 飻 蛈 䵿 䴴 銕 鴩 锇 鋨 鐵 驖 铁 鐡 鉄 䥫 帖 呫 贴 貼 萜 怗 䂿 揲 䩞 跕 ting 䋼 梃 町 頲 鋌 铤 誔 艇 脡 甼 珽 烶 涏 挺 侹 䵺 䦐 庭 鯅 莛 朾 葶 蜓 鼮 霆 閮 邒 諪 蝏 聤 筳 渟 榳 楟 廷 嵉 婷 停 亭 䱓 䗴 㹶 桯 听 聽 聼 圢 綎 汀 艼 耵 鞓 聴 耓 廳 廰 庁 厛 厅 颋 烴 烃 䅍 濎 㼗 tong 赨 衕 蘣 痛 憅 慟 恸 㪌 筩 筒 统 綂 統 桶 捅 姛 䆹 㛚 僮 鲖 鮦 穜 䳋 鼨 童 䮵 同 仝 㣚 蚒 酮 峝 峒 硐 蕫 爞 艟 潼 罿 餇 铜 銅 鉵 鉖 迵 詷 茼 膧 絧 粡 秱 砼 瞳 獞 犝 燑 烔 浵 氃 桐 朣 曈 晍 彤 庝 峂 哃 勭 佟 䶱 䴀 䆚 䂈 㼿 㼧 㸗 㮔 㤏 㣠 㠽 㠉 通 侗 恫 蓪 痌 狪 熥 炵 樋 嗵 洞 垌 鼕 tou 諭 透 䟝 䞬 㖣 黈 紏 斢 妵 䱏 㪗 牏 頭 头 酘 投 坄 匬 亠 䵉 㢏 㡏 㓱 媮 婾 鍮 偸 偷 㳆 㕻 㤟 䡩 䕱 tu 腞 悇 鵌 菟 鵵 堍 兔 兎 吐 芏 钍 釷 圡 土 唋 鼵 葖 怢 荼 𨑒 鷵 鷋 鶟 鵚 駼 馟 鍎 鈯 酴 途 跿 蒤 腯 筡 稌 瘏 瑹 潳 湥 涂 梌 揬 捈 徒 庩 嵞 峹 屠 宊 塗 圗 圖 图 図 凃 䳜 䤅 䣝 䣄 䠈 䖘 䅷 㻯 㻬 㻠 㻌 㭸 突 鋵 秃 禿 痜 涋 捸 廜 嶀 堗 凸 䭭 䴛 䩣 跌 tuan 鱄 篿 褖 彖 黗 疃 畽 䵯 䜝 摶 抟 剸 鷻 鏄 糰 漙 槫 慱 團 団 团 䊜 㩛 湍 貒 猯 煓 䳪 剬 tui 褪 蛻 㦌 駾 退 煺 娧 㷟 僓 骽 蹆 腿 俀 㾼 㱣 㞂 㾽 䍾 㾯 魋 颓 頽 頺 頹 隤 蹪 蘈 穨 橔 弚 尵 䫋 䅪 䀃 㿗 㿉 㢑 㢈 藬 蓷 推 饋 墤 㰐 萑 䩣 㥆 tun 迍 窀 肫 氽 㖔 忳 屯 飩 饨 豚 芚 鲀 魨 霕 軘 豘 訰 臋 臀 坉 㼊 㹠 㩔 㞘 噋 焞 涒 朜 暾 旽 啍 呑 吞 㧷 囤 燉 tuo 棁 乇 扡 酏 舃 槖 拓 跅 蘀 萚 籜 箨 毻 毤 柝 唾 鰖 䓕 媠 軃 橢 鵎 楕 椭 撱 彵 庹 嫷 妥 䲊 㟎 阤 陁 佗 魠 牠 馱 沱 驮 陀 沲 橐 鞁 𥓿 鼧 鼍 鼉 鸵 鴕 鮀 驼 驒 騨 駞 駝 駄 酡 迱 跎 詑 袉 紽 碢 砤 砣 狏 岮 堶 坨 䴱 䰿 䭾 䪑 䡐 䍫 㾃 㼠 㸱 㸰 脫 挩 驝 馲 饦 飥 讬 託 脱 矺 涶 沰 汑 杔 捝 拖 拕 扥 托 咃 侻 侂 仛 鉈 铊 鱓 蟺 㰐 㯐 柁 舵 莌 wa 啘 𩋘 鞋 汚 汙 䎳 婠 袜 淴 韤 韈 襪 膃 腽 嗢 䠚 䚴 瓦 邷 咓 佤 㼘 㧚 娃 㰪 哇 蛙 洼 鼃 聉 窪 窊 穵 畖 漥 溛 攨 搲 挖 徍 媧 娲 嗗 劸 㒝 䍪 鮭 鲑 窐 wai 懀 外 䠿 歪 喎 咼 㖞 呙 㨤 wan 魭 杬 箢 翫 万 鎫 綄 𦙵 贎 貦 蟃 萬 腕 捥 忨 卐 卍 仴 䥑 㸘 菀 畹 䝹 䖤 宛 䩊 䂺 錽 鋄 脕 睕 鞔 鲩 鯇 皖 浣 鋔 輓 踠 萖 绾 綰 綩 碗 睌 盌 琬 椀 梚 晼 晩 晚 挽 惋 婉 埦 倇 䳃 䛷 䘼 䗕 䅋 㿸 㽜 㜶 玩 抏 頑 顽 芄 纨 紈 琓 烷 汍 完 刓 丸 䯈 㝴 蜿 豌 灣 潫 湾 彎 弯 帵 剜 婠 䵥 蔓 鄤 䑱 薍 䈮 䯛 輐 捖 䏦 贯 貫 脘 関 莞 㽹 㼝 㝃 wang 忘 迋 朢 望 旺 妄 䤑 䛃 暀 徃 往 罔 魍 迬 辋 輞 誷 蝄 蛧 菵 罒 网 網 瀇 棢 枉 惘 忹 䰣 䋞 䋄 㴏 㳹 㲿 㓁 亾 亡 王 蚟 莣 彺 兦 仼 汪 㑌 尫 尪 尩 尣 琞 䒽 盳 㔞 wei 鷕 觹 阢 㷉 蔚 罻 尉 蜼 魏 犩 爲 為 为 畏 餧 薉 磑 硙 鳚 鮇 餵 霨 鏏 錗 轊 軎 躛 躗 贀 谓 讏 讆 謂 褽 衞 衛 螱 蝟 蘶 藯 菋 苿 胃 緭 猬 犚 熭 煟 渭 未 慰 徻 嬒 媦 喂 味 叞 卫 位 䵳 䲁 䮹 䭳 䬑 䪋 䡺 䜜 䙿 䘙 䗽 㦣 㥜 尾 猥 嵔 僞 偽 伪 䬿 委 亹 磈 煒 蘤 隗 濻 鲔 鮪 骫 骪 骩 颹 頠 韪 韡 韙 韑 鍡 踓 诿 諉 蜲 薳 蓶 葦 荱 苇 芛 艉 腲 纬 緯 硊 痿 痏 瑋 玮 炜 浘 洧 椲 梶 暐 斖 愇 徫 崣 寪 娓 喡 儰 偉 伟 䵋 䬐 䪘 䞔 䈧 䃬 㱬 㭏 㬙 㨊 㢻 㠕 㟪 㞑 㞇 㖐 圩 維 䑊 蒍 壝 唯 㧑 㕒 薇 韋 違 鮠 韦 霺 闱 闈 鍏 醀 鄬 违 覹 蔿 维 矀 癓 琟 瀢 濰 潿 潍 溦 湋 涠 洈 沩 欈 桅 惟 幃 帷 帏 嵬 峞 峗 圍 围 囲 囗 䧦 䥩 䝐 䜅 䔺 䉠 㣲 煨 萎 碨 渨 微 巍 危 鳂 鰄 鰃 隈 隇 逶 詴 覣 蝛 葳 葨 燰 烓 溾 楲 椳 揋 愄 崴 媙 媁 威 喴 偎 鰖 䓕 㾯 芕 荽 眭 芟 㛱 䛪 䩞 㻰 䵢 䓺 薶 䱞 䫥 䦱 㨒 㟴 䥆 䩈 彙 䅏 䇻 濊 廆 㺔 䍷 㸵 䣀 潙 溈 䗆 䲘 䙟 䍴 㥨 wen 舋 紊 抆 莬 汶 问 璺 渂 搵 揾 妏 問 伆 㗃 脗 肳 穩 穏 稳 桽 呡 吻 刎 㳷 㝧 㖧 㒚 闻 聞 紋 文 䘇 䎽 閺 鼤 鴖 鴍 鳼 魰 馼 雯 阌 闦 闅 閿 蟁 螡 蚊 蚉 芠 纹 瘒 琝 珳 炆 彣 䰚 䎹 温 昷 瘟 鳁 鰮 鰛 馧 辒 轀 輼 豱 瞃 瑥 溫 殟 塭 殁 歾 珉 玟 㟩 㡈 笏 㼂 㵮 weng 𦧅 齆 罋 甕 瓮 䤰 㜲 蓊 滃 聬 瞈 浻 暡 奣 塕 勜 䐥 㘢 翁 鹟 鶲 霐 鎓 螉 嵡 嗡 䨴 wo 撾 挝 蒦 涴 渥 擭 斡 龌 齷 臥 肟 焥 濣 沃 楃 握 捾 幄 卧 偓 䠎 䁊 㱧 㠛 捰 我 婑 䰀 㧴 㦱 渦 涡 踒 萵 莴 窩 窝 猧 涹 唩 倭 䩊 䂺 喔 䀑 薶 䙠 䁷 䮸 濄 蝸 蜗 緺 硪 婐 wu 齬 峿 陓 垭 迕 钨 阢 痦 鶩 敄 沕 霧 芴 遻 蘁 兀 齀 骛 騖 靰 霚 雾 隖 鋈 逜 误 誤 粅 窹 矹 物 熃 焐 溩 杌 晤 扤 戊 悮 悟 悞 忢 嵍 岉 屼 寤 婺 奦 塢 坞 卼 勿 務 务 兀 俉 䳱 䦍 䛩 䑁 䎸 䃖 㽾 㡔 㐳 廡 庑 熓 鹉 鵡 躌 舞 碔 甒 珷 玝 潕 武 橆 旿 摀 捂 憮 怃 忤 嵨 嫵 娬 娒 妩 墲 啎 午 儛 倵 侮 伍 仵 五 䳇 䡧 䟼 䒉 㵲 㬳 㑄 㐅 麌 铻 鋙 梧 䦜 蕪 牾 䍢 诬 毋 無 无 鋘 鼯 鹀 鷡 鵐 鯃 郚 誈 蜈 莁 茣 芜 禑 祦 璑 珸 浯 洖 娪 唔 呉 吾 吴 吳 䮏 䫓 㻍 㹳 㷻 污 汚 汙 鎢 烏 乌 誣 巫 鼿 鴮 鰞 鄔 邬 螐 腛 箼 窏 瑦 洿 歍 杇 弙 屋 媉 圬 嗚 呜 剭 亾 䜑 䅶 㒇 䉑 䀛 瞀 蝥 㝟 矻 扝 䚈 㱱 笏 膴 惡 恶 䓊 噁 xi 褶 晢 濦 羛 緆 襾 訢 脅 攜 獻 銑 铣 䚷 㹫 㙾 㭡 㞒 䩤 䙽 謑 戱 戯 戏 肸 穸 矽 汐 晳 戲 闟 郄 舃 舄 繫 系 墍 鬩 齂 黖 饩 餼 隟 隙 阋 鎎 釸 釳 鄎 郤 赩 赥 覤 衋 虩 蕮 翖 翕 绤 细 繋 綌 細 稧 禊 磶 盻 犔 熂 澙 潟 滊 椞 恄 怬 忥 屭 屓 屃 嚱 嚊 喺 呬 卌 係 䲪 䮎 䨳 䧍 䜁 䛥 䓇 䐼 䊠 䈪 㸍 㥡 㤸 㣟 㚛 㑶 洗 霼 禧 狶 釃 酾 纚 鱚 躧 蹝 諰 蟢 蓰 葸 葈 縰 簁 矖 璽 玺 漇 枲 暿 敼 憙 憘 徙 屣 壐 囍 喜 匸 䢄 㦻 隰 䏮 䀘 㩗 㿇 錫 钖 郋 蒠 熄 裼 锡 鳛 鰼 騽 飁 霫 鎴 趘 謵 觋 覡 襲 袭 薂 蓆 習 瘜 獥 焬 焟 漝 欯 檄 槢 椺 棤 席 嶍 媳 习 䫣 㽯 㵿 㳧 㤴 㠄 㔒 熙 焈 潝 夕 擕 蒵 傒 鼷 豀 蠵 徯 奚 觹 犧 牺 雟 菥 歙 蹊 谿 粞 溪 嵠 鑴 昔 螅 糦 扱 肹 娭 𥋟 𠔃 凞 黊 鵗 驨 騱 隵 鏭 醯 酅 貕 豯 豨 譆 觿 觽 覀 西 蟋 螇 蜥 莃 舾 膝 羲 繥 縘 窸 稀 硒 瞦 睳 睎 皙 瓗 琋 犀 爔 燨 熻 熺 熹 熈 煕 烯 淅 浠 氥 歖 欷 橀 樨 榽 桸 析 曦 晰 晞 捿 扸 惜 惁 悕 悉 息 恓 怸 怷 忚 徆 希 巇 嶲 屖 嬉 嬆 媐 噏 嘻 唽 唏 吸 厀 卥 凞 兮 僖 僁 俙 䂀 㗩 㪪 䘮 灑 䦧 䚉 䫔 㜎 畦 鸂 磎 棲 栖 鉩 鉨 攦 釐 腊 䴛 蔇 檕 旣 既 塈 䒁 嵇 擊 㗲 㱱 赫 䵱 䚂 㳀 扢 摡 誒 郗 xia 霅 睱 夏 芐 吓 欱 𨻲 鶷 鏬 罅 疜 懗 夓 下 丅 㙤 㗿 閜 𡨄 䦖 暇 䫗 鰕 舺 搳 轄 敮 黠 魻 騢 霞 鎋 遐 辖 赮 蕸 舝 翈 縖 縀 筪 笚 祫 磍 碬 硤 硖 瑕 珨 狹 狭 狎 烚 炠 峽 峡 匣 冾 俠 侠 䪗 䛅 䘥 䖖 䖎 㽠 㰺 㘡 㗇 閕 煆 鍜 蝦 虾 颬 谺 瞎 疨 煵 呷 傄 昰 陿 廈 厦 歃 㥦 䶝 䨐 瘕 叚 郃 䒩 㿣 㭱 譹 諕 㙈 䒠 䯟 㵤 毳 xian 黹 葴 撏 挦 癬 晅 鶱 軐 脅 㩈 羨 羡 䞁 袨 䧟 㔵 縣 县 蜆 蚬 咞 限 獻 餡 莧 苋 𠜎 麲 馅 霰 陷 陥 錎 鋧 轞 豏 誢 臽 臔 腺 缐 线 線 綫 絤 糮 粯 睍 県 現 现 献 瀗 涀 橌 晛 撊 憲 峴 岘 宪 娊 姭 垷 哯 僴 僩 俔 伣 䶟 䵇 䱤 䨷 䨘 䤼 䏹 䉯 䃸 䃱 䁂 䀏 㺌 㬗 㪇 㦓 㡾 齴 險 险 㯀 癣 㿅 㧋 䧮 跣 銑 铣 獮 狝 礆 燹 鼸 顯 顕 韅 険 鍌 赻 蘚 藓 箲 筅 禒 玁 獫 猃 烍 灦 毨 櫶 显 攇 搟 幰 嶮 崄 尠 尟 冼 䧋 䥪 䢾 䜢 䚚 䘆 䗾 䉳 㶍 㭠 㬎 㫫 㧥 㜪 衘 涎 唌 㡉 䒸 嗛 燅 瞷 瞯 閒 鹹 鹇 鷼 鷴 鷳 闲 閑 銜 輱 贤 贒 賢 諴 衔 蛝 蚿 藖 舷 胘 羬 絃 礥 癎 癇 痫 痃 甉 憪 弦 嫻 嫺 嫌 婱 娹 娴 啣 咸 䶢 䲗 䦥 䝨 䕔 㵪 㳭 㳄 㮭 㭹 㢺 㛾 㘋 㘅 祆 蘐 鲜 鮮 襳 孅 纤 纖 鱻 馦 韱 韯 锨 铦 鍁 銛 酰 躚 蹮 跹 訮 褼 蓒 苮 纎 籼 秈 珗 澖 氙 枮 杴 暹 掀 憸 忺 廯 屳 嬐 奾 嘕 先 僊 仚 仙 錟 锬 姺 钐 釤 彡 鏾 攕 灑 㯗 綅 㥦 㯠 㩮 㲽 禰 䡅 㜷 蘞 㦑 薟 濂 螊 㱹 闞 塪 䇒 䙹 䵛 覸 䵖 檻 䄯 㔓 䶠 肩 㦥 䐄 㽉 xiang 蠁 蚃 曏 塂 巷 鱌 项 項 闂 闀 鐌 象 襐 蟓 萫 珦 橡 恦 嚮 向 像 䢽 䐟 㟟 鮝 鲞 鱶 鯗 饷 饟 饗 餉 飨 響 晑 想 嶑 奛 响 亯 享 䖮 䊑 㗽 详 詳 祥 跭 翔 絴 祥 栙 庠 佭 䜶 䔗 㟄 相 鄕 鄉 乡 薌 芗 镶 鑲 纕 啌 麘 骧 驤 香 鄊 郷 襄 葙 膷 缃 緗 箱 瓖 湘 欀 忀 廂 厢 㐮 攘 勷 降 䒂 䙹 䤔 缿 銗 鬨 䴂 䦳 䣈 䇨 舡 䛠 xiao 獟 殽 淆 猇 謞 澩 削 㤊 娎 肖 藠 校 斆 斅 嘨 鞩 誟 笑 熽 涍 歗 敩 效 恔 孝 嘯 啸 咲 効 傚 俲 䕧 䊥 㹲 㗛 㔅 謏 篠 筿 筱 皢 曉 暁 晓 小 䥵 䒕 㑾 訤 郩 誵 笅 洨 䒝 㬵 㚣 烋 霄 簫 簘 箫 翛 綃 硝 嘐 藃 呺 嚣 鸮 鴞 鮹 魈 髇 骁 驍 销 銷 逍 踃 蠨 蟰 蟏 虓 虈 蕭 萷 萧 膮 绡 窙 穘 硣 痟 痚 獢 焇 灲 灱 瀟 潚 潇 消 毊 歊 櫹 梟 枵 枭 撨 憢 彇 庨 宵 宯 婋 囂 嚻 嘵 嘋 啋 哮 哓 䇃 箾 揱 騷 骹 髐 皛 䠛 絞 䴛 䒁 嗃 xie 靾 䚳 㴽 绁 絏 紲 泄 㔎 揳 械 廨 獬 骱 渫 褻 齥 齘 駴 韰 鞢 邂 躞 谢 謝 衸 蠏 蟹 薤 缷 緤 絬 糏 禼 祄 疶 爕 燮 焎 灺 瀣 瀉 澥 洩 泻 榭 榍 暬 斺 懈 徢 嶰 屧 屟 屑 媟 妎 塮 卸 卨 偰 伳 亵 䵦 䲒 䩧 䦑 䦏 䢡 䚸 䙝 䙊 䕈 䊝 䉣 䉏 㽊 㸉 㴮 㴬 㳿 㳦 㰡 㰔 㨝 㦪 㣰 㣯 㞕 㙰 㖑 㓔 㒠 躠 藛 寫 冩 写 䥾 䥱 㝍 㕐 䭎 鋣 䔑 㭨 邪 㩪 䕵 脅 斜 攜 𩋘 鞋 搚 𩋧 絜 偕 挾 挟 籺 龤 鞵 谐 諧 襭 衺 蝢 膎 脇 胁 翓 缬 纈 緳 綊 燲 熁 旪 擷 撷 拹 慀 愶 恊 奊 垥 嗋 協 协 勰 劦 䡡 䙎 㩦 㩉 㨙 㥟 㙝 㖿 歇 楔 猲 些 褉 蠍 娎 䦖 㞒 䩤 䙽 隰 䏮 䀘 㩗 擕 携 歙 眭 䁯 㢵 㚗 脥 䬅 潰 跬 㨒 苴 檞 颉 頡 薢 擑 觟 㷎 蝎 㽳 㜦 䇋 鮭 鲑 溉 䍖 炧 䪥 䞕 xin 桪 尋 㛛 焮 軐 舋 信 馸 顖 阠 釁 訫 衅 脪 煡 孞 囟 卂 伩 䜗 䛨 䚱 䒖 㭄 㐰 伈 鄩 㚯 襑 樳 攳 䰼 鋅 鑫 馨 芯 訢 䜣 噷 骍 锌 鈊 辛 薪 盺 炘 歆 欣 杺 昕 新 惞 忻 心 廞 妡 兓 俽 㩪 㭡 镡 鐔 䎣 㹷 䪿 鬵 款 㜦 xing 莕 荇 臖 緈 涬 杏 悻 性 幸 嬹 婞 姓 倖 䰢 䛭 䓷 䂔 䁄 㼬 㓑 醒 渻 睲 擤 䳙 㮐 㨘 㝭 濴 滎 硎 餳 陘 钘 銒 鈃 胻 行 筕 邢 饧 雽 铏 鋞 鉶 郉 烆 洐 形 娙 型 坓 刑 侀 䤯 䣆 㼛 㣜 㓝 㐩 鯹 興 兴 𢜫 鮏 騂 馫 鍟 觲 觪 蛵 腥 篂 皨 瑆 猩 煋 曐 星 惺 垶 桯 箵 狌 䮍 㴆 㬐 㒷 xiong 诇 詗 敻 夐 赨 雄 熊 䧺 賯 讻 詾 訩 胸 胷 洶 汹 恟 忷 哅 匈 凶 兇 兄 㐫 䎿 芎 xiu 褏 褎 綉 齅 锈 鏽 鏥 銹 袖 绣 繡 繍 秀 琇 珛 溴 峀 岫 嘼 嗅 㾋 㗜 糔 綇 朽 㱙 咻 脩 茠 𦟤 鸺 鵂 髹 髤 馐 饈 鏅 鎀 銝 貅 蓚 臹 羞 烌 樇 庥 修 俢 休 烋 滫 䜬 㩰 臭 xu 芌 豫 獝 淢 籲 矞 嶼 屿 祤 芧 藇 㰲 㦽 㤢 㚜 魣 䬔 㕛 洫 䣱 䜡 瞲 魆 絮 槒 鱮 顼 頊 銊 酗 賉 訹 藚 蓄 聟 续 绪 續 緖 緒 窢 稸 瞁 盢 珬 烅 潊 漵 溆 沀 汿 殈 朂 旭 敘 敍 慉 恤 怴 序 婿 壻 垿 叙 卹 勗 勖 侐 伵 䳳 䱛 䦽 䦗 䣴 䢕 䛙 䙒 䘏 䋶 䂆 㾥 㺷 㷦 㵰 㞊 㜿 㜅 㘧 㗵 㖅 㐨 煦 昫 湑 姁 许 許 醑 鄦 谞 诩 諝 詡 糈 珝 栩 喣 冔 䔓 䅡 㥠 㞰 㑯 㑔 俆 蒣 徐 䍱 吁 訏 胥 鑐 繻 虚 需 晇 呴 欻 歘 魖 鬚 驉 须 須 譃 蝑 虛 虗 蕦 縃 稰 盱 疞 歔 欰 欨 楈 旴 揟 戌 幁 嬬 嬃 媭 墟 噓 嘘 偦 咻 圩 㦌 蓿 盨 蓲 肷 謳 嘔 掝 砉 㽳 馘 䂸 㒷 畜 xuan 籑 萲 蜎 洵 珣 壎 塤 埙 楥 絢 䘩 泫 鏇 駽 眴 鞙 眩 颴 镟 铉 鉉 贙 讂 衒 蔙 绚 繏 縼 碹 炫 渲 楦 昡 怰 埍 䩰 䩙 䧎 䝮 䍗 㳙 㧦 䠣 咺 癬 選 选 烜 暅 䍻 㾌 䲻 㘣 玄 漩 旋 㹡 鹮 誸 蜁 璿 璇 琁 玹 檈 暶 懸 悬 嫙 妶 伭 䴋 䴉 䲂 䮄 䗠 䁢 㳬 諠 愃 喧 軒 晅 鶱 揎 鋗 鍹 轩 谖 譞 諼 蠉 蝖 藼 蕿 萱 翾 翧 禤 矎 睻 瑄 煊 梋 暄 昍 愋 弲 宣 媗 塇 吅 儇 佡 袨 䧟 㔵 㯀 㿅 㧋 蘐 盷 潠 㦏 㔯 㛐 瓊 煖 暖 喛 擐 䥧 懁 讙 xue 狘 䬂 䎀 䭥 謞 烕 泬 趐 桖 岤 坹 吷 䫼 䤕 㞽 鳕 鱈 雪 䨮 㡜 㧒 䫻 澩 穴 𦥯 𥄴 鸴 鷽 雤 觷 茓 燢 泶 斈 嶨 峃 學 学 乴 䱑 㿱 㶅 㖸 薛 鞾 靴 辥 蒆 屵 吙 䜡 瞲 血 䒸 㙾 㰒 駥 㔧 䖼 噱 䋉 㦜 矆 䩈 䛎 㷤 炔 䀜 䠼 xun 窨 蟫 韗 狥 徇 爋 蕈 鵕 顨 鑂 遜 逊 迿 迅 賐 讯 训 訙 訓 訊 汛 殉 巽 巺 奞 埈 噀 侚 伨 䭀 䞊 䛜 㢲 䙉 潯 驯 馴 洵 珣 桪 尋 寻 撏 挦 栒 蕁 荨 燖 郇 橁 鲟 鱘 鱏 駨 询 詢 蟳 荀 紃 畃 璕 灥 潃 浔 毥 槆 枔 杊 旬 恂 循 廵 巡 峋 噚 偱 䖲 䋸 㽦 㰬 㰊 㨚 㝁 㜄 𤑕 熏 壦 坃 壎 塤 埙 焄 醺 蘍 薰 薫 蔒 臐 纁 矄 獯 燻 曛 勳 勲 勛 勋 絢 䘩 鄩 㚯 燅 潠 愻 㡄 狻 逡 㯠 燂 䡅 浚 葷 㟧 䃀 ya 閘 御 浥 琊 猒 睚 䵝 䝟 亞 亚 襾 轧 軋 齾 铔 鐚 錏 迓 讶 訝 聐 窫 稏 砑 玡 猰 氬 氩 揠 掗 挜 婭 娅 埡 圠 嚈 俹 亜 䰲 䯉 䦪 䢝 䅉 㰳 㝞 雅 啞 哑 雃 蕥 瘂 痖 庌 唖 厊 䪵 㿿 䄰 衙 䊦 崖 崕 厓 牙 枒 齖 蚜 芽 笌 猚 犽 漄 涯 桠 岈 堐 伢 㧎 呀 壓 压 鴉 椏 押 鸭 鸦 鵶 鴨 庘 孲 圧 劜 丫 歇 垭 䧅 䖌 㤉 㼤 疋 輅 辂 㝦 䀹 䂒 㮞 䒁 䍓 yai 睚 yan 芫 縯 黫 歅 靨 㛪 䭘 䑍 鷰 燕 厭 厌 爓 焱 鷃 鴳 鴈 鳫 验 驠 驗 騴 騐 饜 餍 雁 隁 闫 釅 醼 酽 赝 贗 贋 豔 豓 谳 谚 讞 讌 諺 觾 觃 覎 艷 艶 艳 硯 砚 牪 燄 焰 焔 灩 灧 灔 灎 滟 椻 曣 曕 暥 晏 敥 恹 彦 彥 宴 嬿 嬊 婩 姲 妟 墕 堰 嚥 喭 唁 傿 偐 䴏 䳺 䳛 䨄 䢭 䜩 䅧 䂩 㷼 㷳 㷔 㬫 㦔 㢛 戭 蝘 演 䁙 㕣 衍 郾 渰 弇 奄 眼 剡 龑 鼹 鼴 黶 黤 黡 鶠 鰋 魘 魇 験 隒 酓 遃 躽 褗 裺 萒 罨 硽 甗 琰 渷 沇 檿 椼 棪 曮 揜 掩 抁 扊 愝 巚 巘 嶖 嵃 姶 夵 噞 厴 厣 匽 兗 兖 儼 偃 俨 乵 䲓 䣍 䗺 䎦 䊻 䄋 㭺 㫃 㢂 㚧 㓧 䕾 言 閻 研 炎 蜒 鹽 阎 盐 沿 䢥 䖗 閆 䶮 䤷 㘙 顔 顏 埏 鈆 檐 麣 麙 颜 顃 郔 讠 詽 虤 蔅 葕 莚 綖 簷 筵 礹 碞 硏 琂 狿 湺 櫩 楌 昖 揅 延 巗 巖 巌 嵓 嵒 岩 孍 娮 娫 姸 妍 壧 壛 塩 嚴 厳 严 䱲 䗡 䓂 䌪 䊙 䇾 䂴 䀽 䀋 㿼 㿕 㶄 㳂 㫟 㘖 㗴 菸 烟 焉 咽 嬮 黭 淹 猒 蔫 腌 阉 閹 醃 酀 鄢 臙 胭 篶 珚 煙 漹 懨 懕 崦 嫣 啱 剦 偣 硎 䞁 齴 唌 㡉 䍾 錟 掞 烻 䌠 䦧 䫡 䦲 铅 鉛 顩 齞 㰽 薟 䶫 趼 䛳 豣 䘶 淊 㺂 閼 阏 阽 㺗 䉷 yang 瀁 漾 樣 詇 羕 様 恙 怏 䵮 䭐 䬺 㿮 㺊 㨾 仰 養 养 蝆 痒 鞅 駚 餋 癢 炴 氱 氧 攁 抰 懩 慃 岟 坱 勨 傟 䬬 䒋 䑆 䇦 㔦 样 煬 烊 炀 蛘 洋 瘍 瑒 玚 鸉 鰑 飏 颺 霷 陽 阳 阦 鐊 鍚 輰 諹 羏 羊 禓 眻 疡 珜 楊 杨 暘 昜 旸 敭 揚 扬 徉 崵 垟 劷 佯 䬗 䖹 䁑 㬕 㟅 泱 鸯 鴦 鉠 胦 紻 秧 眏 殃 柍 姎 央 咉 佒 䭥 䞁 飬 yao 鎐 瀹 㿢 藥 钥 鑰 葯 药 䋤 㵸 㔽 鹞 鷂 要 獟 燿 趭 靿 讑 覞 袎 薬 艞 耀 筄 穾 矅 熎 曜 䙅 䑬 㿑 㞁 㝔 㢓 抭 窔 窈 宎 殀 鷕 齩 咬 鼼 騕 闄 蓔 苭 舀 窅 眑 溔 榚 柼 杳 崾 岆 婹 偠 仸 䶧 䴠 䆞 䁘 䁏 㴭 㫐 㫏 㟱 繇 䍃 䌊 䂚 爻 殽 淆 猇 铫 銚 𨍳 軺 鳐 鰩 餚 餆 飖 颻 邎 遥 遙 轺 谣 謡 謠 蘨 肴 窰 窯 窑 瑶 瑤 珧 猺 烑 榣 暚 摇 搖 揺 愮 徭 嶤 嶢 崤 峣 尭 尧 媱 姚 堯 垚 嗂 傜 倄 䬙 䢣 䚻 䚺 䖴 䔄 䌛 䋂 䉰 䆙 㮁 㨱 祅 夭 鴁 邀 訞 葽 腰 楆 枖 幺 妖 喓 吆 䭥 㤊 㑾 祆 䒒 嬈 蕘 荛 㓞 䚆 䯚 㺒 瞭 㬭 徼 儌 䠛 䳬 ye 璍 餘 腋 抴 拽 煠 液 曳 㸣 㥷 㝣 㙪 掖 靨 葉 頁 啘 殜 鸈 鵺 驜 馌 饁 餣 页 靥 鐷 鎑 鍱 鄴 邺 谒 譺 謁 瞸 瞱 皣 爗 燁 烨 澲 殗 業 枽 枼 曵 曗 曅 曄 擫 擪 擛 忦 嶫 嶪 夜 墷 僷 偞 亱 业 䲜 䭟 䧨 䥡 䥟 䤶 䤳 䈎 㱉 㪑 㩎 㗼 㖶 㖡 㐖 野 漜 壄 埜 嘢 吔 冶 也 㙒 耶 椰 琊 铘 鎁 釾 瑘 爺 爷 擨 揶 捓 峫 䥺 䓉 晔 蠮 噎 倻 䝟 叶 䭎 鋣 䔑 㭨 㩪 揲 䖣 聶 䳖 㴸 㜇 暍 擖 㡋 閼 堨 㷸 䴾 yi 昱 秇 臆 誼 悥 医 腋 抴 浥 靾 羛 緆 蜴 肄 醳 繹 埶 槷 仡 睪 鞥 邑 斁 軼 轶 佚 嗌 𥜥 逸 益 齸 黓 鷾 鷧 鶃 鶂 鯣 骮 驿 驛 駅 饐 顡 霬 隿 阣 镱 镒 鐿 鎰 鈠 釴 醷 逸 跇 豷 豛 豙 诣 译 议 讛 議 譯 詣 詍 訳 訲 襼 褹 裛 裔 袣 螠 蛡 虉 蘙 藝 藙 薏 蓺 苅 芅 艺 艗 膉 肊 翼 翳 翌 翊 羿 義 缢 绎 繶 縊 竩 穓 瞖 益 癔 瘱 瘞 瘗 痬 疫 異 玴 獈 燱 燡 熼 熤 熠 焲 炈 瀷 澺 潩 溢 湙 浳 浂 洂 毅 殹 殪 殔 歝 欭 檍 榏 棭 栧 枻 枍 杙 曎 曀 晹 易 敡 撎 捙 挹 抑 懿 懌 憶 意 悒 怿 怈 忆 役 弋 弈 异 廙 幆 帠 帟 嶧 峄 屹 寱 嬟 嬑 嫕 奕 墿 埸 垼 圛 囈 唈 呹 呭 呓 勩 勚 劮 劓 刈 兿 億 俋 佾 伿 伇 亿 亦 亄 义 乂 䴬 䱒 䯆 䭿 䭞 䭇 䭂 䬥 䦴 䣧 䢃 䝯 䝘 䘸 䘝 䗷 䗟 䗑 䖁 䕍 䔬 䓹 䓈 䓃 䎈 䌻 䋵 䋚 䉨 䇩 䆿 䄿 䄁 㽈 㹭 㹓 㶠 㵩 㵝 㴒 㴁 㳑 㲼 㱲 㱅 㦤 㦉 㣻 㣂 㢞 㡼 㡫 㜒 㜋 㛕 㚤 㙯 㙠 㘊 㘁 㖂 㔴 㓷 㑥 㑜 㑊 㐹 鳦 衪 迆 栘 铱 椅 矣 迤 苡 晲 掜 蟻 扡 胣 齮 顗 钇 鉯 釔 逘 轙 輢 螘 蚁 苢 艤 舣 肔 笖 礒 檥 旖 旑 攺 扆 庡 已 崺 偯 倚 以 乙 䰙 䧧 䝝 㰻 㰝 㫊 㩘 㠯 㕥 沂 㝖 貤 谊 袘 䖊 遺 遗 洟 苐 鮧 枱 饴 飴 嶷 疑 酏 柂 訑 詒 移 杝 謻 𩸨 鸃 鴺 颐 顊 頤 頉 鏔 鈶 迻 跠 贻 貽 诒 讉 觺 袲 螔 蛦 萓 胰 羠 簃 眱 眤 痍 瓵 珆 熪 沶 歋 椸 桋 暆 扅 恞 怡 彞 彝 彜 彛 弬 巸 嶬 峓 寲 宧 宜 宐 姨 夷 圯 咦 匜 凒 冝 儀 侇 仪 乁 䴊 䲑 䱌 䮊 䬮 䬁 䩟 䞅 䐖 䐅 䇵 䄬 㺿 㰘 㦾 㥴 㞔 㚦 夁 衣 泆 壹 銥 依 陭 欹 揖 猗 𣘦 黳 黟 鹥 鷖 饻 餏 醫 郼 譩 蛜 繄 稦 禕 祎 瑿 燚 漪 溰 洢 毉 檹 悘 弌 嫛 壱 噫 咿 吚 伊 一 㘈 曳 㸣 㥷 㝣 㙪 䵝 洫 䣱 绁 絏 紲 㔎 渫 䚷 㹫 焈 維 銕 䧅 荑 䣡 臺 㹑 㐌 虒 䃞 釋 释 鉇 施 鉈 虵 㴔 䖌 忔 䏌 綺 䔇 㾨 鮨 䱈 锜 錡 攲 䑄 鹢 鹝 鷊 鷁 㵫 㣇 䭲 䧇 䕥 䰯 㞾 狋 䄩 䇣 袂 䤭 㠖 踦 㔕 犄 㕈 䐙 疙 阝 䛖 䳬 誒 㼢 蛾 硪 昳 㲲 䂽 䧝 佁 yin 㼉 㣧 檼 朄 蔭 荫 廕 窨 堷 鮣 酳 茚 胤 癊 猌 濥 湚 懚 憗 憖 慭 垽 印 䲟 䤃 䡛 䚿 䕃 㴈 㪦 纼 紖 饮 飲 隱 隐 㧈 磤 縯 濦 馻 飮 靷 隠 鈏 趛 讔 螾 蚓 蘟 癮 瘾 淾 櫽 檃 引 廴 嶾 尹 乚 䨸 䤺 䒡 䌥 䇙 㾙 㱃 㦩 㥼 㥯 㡥 㐆 冘 䖜 訡 㹞 滛 淫 蟫 釿 鳏 鷣 霪 银 銀 鈝 鄞 誾 訚 訔 蔩 荶 苂 碒 璌 狺 犾 烎 泿 殥 檭 斦 崯 崟 寅 婬 夤 垠 圁 嚚 噖 唫 吟 䪩 䓄 㹜 㸒 㞤 㝙 㙬 㖗 㕂 陰 阴 阥 音 喑 峾 氤 殷 洇 黫 湮 歅 隂 韽 骃 駰 韾 鞇 霠 霒 陻 闉 铟 銦 諲 裀 蒑 茵 緸 絪 筃 秵 禋 瘖 溵 洕 摿 慇 愔 婣 姻 堙 垔 因 囙 噾 凐 侌 㝖 夁 戭 䕾 訢 㴽 㗃 㥲 吲 䴦 䌠 䠴 欽 圻 狋 㸧 齦 龈 龂 齗 䖐 䴛 鰥 ying 禜 鎣 譍 蓥 滢 应 瀅 硬 𤇾 鞕 鐛 賏 膡 暎 映 摬 媵 噟 䤝 䙬 䁐 㑞 瀴 梬 郢 颖 颕 颍 頴 穎 矨 癭 瘿 璄 潁 浧 影 巊 䭗 䭊 䨍 䀴 㲟 㯋 迎 濙 㶈 瑩 㢍 熒 謍 營 赢 贏 覮 蠅 螢 蝿 蝇 蛍 藀 萾 萦 营 萤 莹 荧 荥 茔 縈 籯 籝 盈 盁 瀯 瀠 瀛 濚 潆 溁 櫿 楹 攍 廮 巆 嬴 塋 営 僌 䪯 䕦 䑉 䃷 䁝 㿘 㹚 㹙 㵬 㴄 㨕 應 英 鹰 鹦 鸚 鸎 鷹 鷪 鶯 鶧 鴬 韺 霙 锳 鑍 鍈 譻 褮 蠳 蝧 蘡 莺 膺 罌 罃 罂 缨 绬 纓 緓 礯 碤 甖 甇 瓔 璎 瑛 煐 渶 櫻 樱 楧 桜 朠 攖 撄 応 孾 孆 嬰 嫈 媖 婴 嚶 嘤 偀 䭘 䑍 濴 滎 䤰 㜲 䋼 䵥 䚆 㚞 䔔 㬐 㕲 䀰 yo 育 唹 喲 哟 唷 yong 銿 醟 佣 苚 用 㶲 㞲 臃 拥 禜 硧 傛 甬 涌 鲬 鯒 踴 踊 詠 蛹 湧 泳 永 栐 柡 搈 慂 愹 愑 惥 悀 恿 彮 嵱 塎 埇 咏 勈 勇 俑 䞻 㽫 㷏 㦷 㙲 喁 鳙 鱅 滽 颙 顒 牅 槦 嫞 嫆 䗤 㝘 邕 擁 壅 鄘 慵 庸 墉 傭 蕹 𠆌 饔 雝 雍 镛 鏞 郺 癰 癕 痈 灉 澭 廱 噰 嗈 㐯 㣧 䮵 鷛 鰫 㑙 you 揄 㺠 柚 幼 牰 鼬 鴢 釉 酭 迶 貁 诱 誘 糿 祐 狖 峟 宥 姷 囿 右 又 侑 佑 亴 䞥 䛻 䆜 䀁 㹨 㤑 㕗 㓜 栯 䳑 㮋 蚴 有 槱 庮 泑 懮 黝 莠 禉 铕 銪 酉 蜏 苃 聈 羑 羐 牖 湵 梄 岰 唀 友 卣 偤 丣 䱂 䬀 䒴 䅎 㾞 㰶 蚰 鈾 㻀 疣 油 櫾 猶 由 游 斿 滺 浟 郵 𡈙 鲉 鱿 鮋 魷 駀 铀 邮 遊 逰 逌 輶 輏 訧 蝣 蕕 莸 莤 肬 秞 猷 犹 沋 楢 怣 峳 尤 䢟 䢊 䚃 䖻 䑻 㽕 㳺 㫍 㛜 㚭 㘥 㕱 㒡 麀 鄾 耰 纋 瀀 櫌 攸 憂 悠 怮 忧 幽 嚘 呦 優 优 冘 㔽 抭 䌊 䂚 㕛 褏 褎 尢 鯈 䒒 泅 蝤 㶭 囮 莜 yu 惌 鬻 黦 嫗 妪 芌 喻 育 昱 御 豫 獝 淢 籲 悇 諭 鷸 矞 繘 芋 蜮 隩 燠 圫 龥 鹬 鹆 鵒 鴪 鴥 鳿 魊 鬱 鬰 驭 驈 騟 馭 饫 饇 飫 预 預 霱 阈 閾 钰 鐭 錥 鋊 銉 鈺 醧 郁 遹 遇 逳 輍 軉 谕 譽 誉 裕 蜟 薁 蕷 蓣 蒮 萮 茟 肀 聿 罭 緎 籞 穥 稶 稢 秗 禦 礜 礖 礇 硲 砡 癒 瘉 琙 玉 獄 狱 爩 燏 煜 焴 灪 澦 滪 淯 浴 毓 欲 欥 欝 欎 櫲 棫 棜 棛 戫 慾 愈 惐 悆 忬 彧 庽 嶎 峪 寓 堉 域 噊 喩 喐 喅 哊 俼 䵫 䴁 䮙 䮇 䬄 䨒 䢩 䛕 䘱 䘘 䖇 䍞 䋖 䉛 䈅 䆷 䂊 䁌 㽣 㳚 㠨 㒁 與 与 雨 语 語 䨞 㲾 㣃 窳 懙 嶼 屿 祤 齬 峿 萭 楀 偊 羽 羽 龉 酑 鄅 貐 螤 蘌 蓹 聥 篽 禹 瘐 瑀 斞 斔 敔 庾 寙 宇 圉 圄 噳 傴 俣 俁 伛 䥏 䣁 㼌 㺄 㡰 㠘 㝢 㙑 㔱 㑨 雩 鸒 輿 㥔 予 䄨 㦛 㤤 㒜 於 揄 臾 餘 隃 余 于 鵌 愉 腧 兪 俞 鄃 畲 畬 禺 桙 窬 逾 鸆 鷠 鱼 鰅 鮽 魚 髃 骬 馀 雓 隅 鍝 釪 邘 轝 踰 谀 謣 諛 觎 覦 褕 衧 螸 蝓 虞 蘛 蕍 萸 茰 艅 舆 舁 腴 羭 緰 籅 竽 硢 睮 盂 畭 璵 瑜 玙 玗 狳 澞 漁 湡 渝 渔 歶 歟 歈 欤 榆 楰 楡 杅 旟 扵 愚 嵛 嵎 崳 嬩 媀 娱 娯 娛 妤 堬 堣 伃 亐 䲣 䱷 䰻 䩒 䢓 䜽 䗨 䔡 䐳 䏸 䍂 䄏 䃋 䂛 䁩 㼶 㺮 㺞 㷒 㶛 㳛 㬰 㬂 㪀 㥥 㥚 㚥 迂 紆 纡 唹 陓 迃 虶 箊 穻 盓 瘀 淤 毺 扜 㺠 䳑 㮋 㻀 喁 菸 衙 㧒 䫻 藇 㰲 㦽 㤢 㚜 魣 䬔 䜡 吁 衘 麌 铻 汚 汙 㷉 圩 煨 菀 牏 媮 婾 㪌 䘻 䎉 毹 䵥 齵 㭌 㻰 䢖 䱾 丂 鱊 潏 㤜 㧕 或 䋭 䰥 䛎 㽳 㵄 䤋 蟈 汩 閼 阏 䓊 䞕 㫹 蜍 yuan 苑 媛 夗 謜 瑗 願 院 褤 褑 裫 衏 禐 掾 愿 怨 傆 䬼 䬇 䏍 䅈 㭇 㥐 㤪 遠 逺 远 妴 䩩 䛇 䛄 員 员 贠 貟 缘 緣 原 芫 萲 魭 杬 獂 圜 鼋 黿 鶰 鶢 騵 鎱 邧 邍 辕 轅 袁 螈 蝯 蝝 蚖 薗 蒝 羱 縁 笎 猿 猭 猨 爰 溒 源 湲 沅 櫞 橼 榬 榞 援 岏 嫄 媴 妧 塬 垣 圓 園 圎 圆 园 厵 厡 元 䳣 䳒 䲮 䬧 䖠 㹉 㥳 㟶 惌 蜎 箢 悁 裷 鼝 鼘 鹓 鸳 鸢 鵷 鴛 鳶 駌 鋺 蜵 蒬 葾 肙 眢 灁 渕 渊 渆 渁 淵 棩 寃 嬽 囦 噮 剈 冤 㛪 楥 䲻 㘣 菀 畹 䝹 㟲 䣰 喛 䭴 豲 䝠 㼂 yue 瀹 狘 躍 爚 越 钺 鉞 龠 鸙 鸑 阅 閲 閱 鈅 軏 跃 跀 蚏 蚎 蘥 粵 粤 籰 籥 籆 篗 禴 礿 玥 泧 樾 枂 月 捳 抈 戉 悦 悅 恱 嶽 岳 岄 妜 刖 䶳 䥃 䤦 䢲 䢁 䡇 䠯 䟠 䖃 䋐 㹊 㰛 㬦 㜰 㜧 噦 哕 約 约 箹 曱 曰 黦 鑰 䋤 㵸 䬂 䎀 㧒 䒸 䎳 趯 鑠 躒 櫟 樂 乐 䟑 㭾 㯞 蠖 矱 yun 䵴 熅 枟 熨 愠 韞 蘊 蕰 鶤 韻 韵 韫 醞 醖 酝 鄆 郓 運 运 藴 薀 蕴 腪 緷 慍 惲 恽 孕 夽 囩 䲰 䩵 䚋 㟦 㞌 㚺 隕 陨 霣 阭 鈗 輑 賱 褞 磒 玧 狁 殞 殒 抎 喗 允 傊 䪳 䨶 䦾 䤞 䡝 䞫 䇖 䆬 㚃 荺 芸 筠 饂 雲 鋆 鄖 郧 蕓 蒷 耺 耘 纭 縜 紜 篔 筼 秐 眃 畇 熉 澐 溳 涢 沄 橒 榲 榅 昀 愪 妘 匀 勻 云 䢵 䉙 㜏 煴 缊 縕 暈 晕 赟 贇 蝹 蒕 蒀 緼 氳 氲 奫 贠 貟 㒁 韗 㩈 㷉 菀 齳 㚞 頵 餫 煾 za 紥 摣 臢 臜 濽 拶 咱 倃 鲝 鮺 囐 偺 魳 韴 雥 雜 雑 襍 磼 砸 杂 嶻 䪞 䞙 䕹 紮 鉔 迊 沞 抸 帀 咂 匝 唼 䨿 㳨 䦈 籴 zai 菑 甾 酨 載 载 扗 在 再 儎 傤 侢 䵧 㞨 縡 崽 宰 䮨 䣬 䏁 㴓 㱰 栽 𢦏 賳 烖 灾 災 渽 哉 zan 饡 蹔 臢 臜 鏨 酇 酂 鄼 濽 錾 赞 贊 賛 讚 讃 襸 穳 瓚 瓒 瓉 灒 欑 暫 暂 囋 㣅 㟛 㜺 㤰 趲 拶 寁 攢 昝 趱 禶 礸 沯 桚 攒 攅 撍 噆 儹 儧 糌 咱 倃 喒 簮 簪 兂 鐕 囐 偺 䙉 䍝 淺 䟅 䭕 濺 㳨 湔 䥄 zang 弉 奘 銺 葬 臟 臓 塟 㘸 驵 駔 脏 髒 臢 臜 臧 蔵 匨 赃 贜 贓 賘 賍 羘 牂 藏 zao 䜊 燥 造 慥 髞 躁 趮 譟 艁 竈 竃 皂 皁 灶 梍 噪 唣 唕 㿷 㲧 蚤 缲 繰 澡 藻 薻 璪 棗 枣 早 䲃 鑿 凿 醩 䥣 傮 𡮦 遭 蹧 糟 䗢 䖣 缫 繅 簉 ze 柞 謫 礋 咋 贼 賊 戝 稄 汄 昗 昃 庂 夨 仄 㳁 迮 㣱 笮 䇥 责 責 簀 擇 择 䃎 㖽 崱 澤 泽 萴 荝 溭 鲗 鰂 赜 賾 謮 諎 蠌 蠈 舴 耫 箦 瞔 皟 沢 捑 択 幘 帻 嘖 啧 則 则 䶦 䰹 䕪 䕉 㳻 睪 䶡 㻭 䅚 㟙 唶 䂝 滜 㮣 䔾 襗 齰 齚 zei 贼 賊 戝 鱡 zen 谮 譖 譛 䫈 怎 zeng 綜 锃 鋥 赠 贈 甑 䰝 䙢 㽪 繒 缯 驓 譄 罾 磳 矰 璔 熷 橧 憎 增 増 䵴 曾 zha 柞 虴 拃 乍 砟 䞢 膪 炸 溠 咋 咤 吒 痄 栅 柵 醡 诈 詐 蚱 簎 灹 榨 搾 宱 䖳 苲 鲊 鮓 㡸 眨 厏 䵙 䛽 䕢 䋾 㷢 㒀 䵵 紥 閘 霅 箚 劄 闸 铡 鍘 譗 蠿 蚻 甴 牐 札 䥷 㴙 㱜 扎 摣 柤 觰 皶 楂 喳 齇 齄 皻 猹 渣 樝 揸 挓 抯 哳 剳 偧 㽪 笮 䃎 紮 煠 轧 䄰 渫 㚫 䮜 㳐 䙄 㞚 䱹 奒 齟 苴 䀹 謯 㑵 㔍 䄍 䢱 喋 㩹 鰈 zhai 瘵 砦 寨 債 债 㩟 飵 窄 鉙 礋 宅 㡯 摘 齋 榸 斎 斋 捚 膪 駘 虒 䍉 亝 㟙 祭 翟 zhan 站 蹔 椾 湛 颤 顫 轏 輚 覱 虦 虥 蘸 菚 绽 綻 棧 桟 栈 戰 戦 战 嶘 偡 佔 䱠 䪌 䘺 䗃 䋎 㻵 㺘 㟞 䟋 㠭 拃 樿 椫 橏 輾 蹍 魙 飐 颭 醆 盞 盏 皽 琖 榐 斬 斩 搌 嶄 嶃 崭 展 嫸 䱼 䩅 䡀 䎒 䁴 㞡 薝 占 沾 詹 鳣 鱣 詀 覘 觇 鹯 鸇 驙 饘 飦 霑 邅 趈 谵 讝 譫 瞻 氊 氈 毡 栴 旜 旃 嶦 厃 㣶 襢 摲 䦅 蛅 䈴 㜊 䁪 醮 䩆 餰 湔 點 噡 䵣 zhang 障 脹 账 賬 胀 緔 瞕 瘴 瘬 痮 涱 杖 扙 幛 帳 帐 嶂 仗 丈 㽴 㙣 㕩 漲 涨 鞝 绱 礃 掌 仉 鄣 章 張 张 𤍤 麞 鱆 騿 餦 遧 蟑 蔁 粻 璋 獐 漳 樟 暲 慞 彰 嫜 墇 傽 㢓 黨 长 長 zhao 濯 鸼 鵃 啁 櫂 䃍 詔 炤 趙 赵 召 鵫 雿 诏 肈 肇 肁 羄 罩 箌 笊 瞾 狣 燳 照 枛 曌 旐 垗 兆 䮓 䍮 䍜 䈇 㷖 㨄 㡽 菬 瑵 沼 找 䝖 䈃 㺐 㕚 着 巶 招 盄 窼 朝 駋 钊 鍣 鉊 釗 柖 昭 妱 䖺 㑿 鮡 搔 㹿 鳭 䧂 zhe 陬 淛 鷙 蛰 慹 䠦 這 这 檡 鹧 鷓 蟅 蔗 烢 浙 柘 䵭 䩾 䗪 䏳 䂞 者 鍺 踷 赭 啫 蟄 㯰 褶 襵 晢 蜇 虴 謫 讋 折 乇 摺 𧋍 鸅 鮿 銸 辄 輙 輒 谪 讘 讁 謺 詟 耴 籷 磔 砓 瓋 歽 悊 埑 嚞 喆 啠 哲 厇 䝕 䝃 䓆 䐲 䐑 䎲 䊞 㪿 㞏 晣 遮 嫬 嗻 着 㦻 庻 螫 適 㵊 懾 慴 䀅 㭙 聶 䜆 䂝 㡇 锗 㫼 㭯 䊮 䙷 䮰 zhen 振 鎮 鎭 震 𨸬 鸩 鴆 陣 阵 镇 赈 賑 誫 蜄 眹 栚 朕 敶 敒 揕 挋 塦 圳 侲 䳲 䲴 䨯 䟴 䝩 䏖 䊶 㴨 㯢 㮳 㣀 㓄 絼 晸 裖 枕 稹 袗 紾 抌 疹 黰 鬒 辴 轸 軫 诊 診 聄 縥 笉 眕 畛 昣 抮 弫 䫬 䪴 䑐 䂧 䂦 㪛 㐱 遉 禎 祯 楨 桢 偵 侦 甄 胗 缜 磌 蓁 溱 葴 鍼 箴 瑊 蒧 桭 鱵 駗 靕 针 錱 鉁 針 酙 轃 贞 貞 薽 蒖 臻 籈 禛 碪 砧 真 眞 珎 珍 獉 澵 潧 樼 榛 栕 斟 搸 揁 帪 寊 嫃 媜 堻 㼉 纼 紖 㛛 鮝 瑱 鷏 鷆 䚯 椹 䀼 甽 䠴 䧵 䡅 䪾 䡩 鼑 鐤 酖 䴾 㭫 zheng 䦛 症 正 政 锃 鋥 𠔻 鴊 鄭 郑 证 證 証 幀 帧 䦶 䥭 䥌 䛫 䈣 䂻 㽀 㱏 㡧 㡠 撜 糽 氶 整 掟 拯 抍 愸 䡕 徵 诤 諍 爭 掙 挣 争 鬇 铮 钲 鏳 錚 鉦 踭 蒸 聇 篜 箏 筝 睜 睁 眐 癥 猙 狰 烝 炡 怔 徴 徰 征 崢 崝 峥 姃 埩 佂 晸 遉 鯹 綪 zhi 扻 致 擲 贄 質 桎 郅 躓 觶 觯 智 淛 鷙 跱 峙 雉 楖 螲 至 窒 疐 陟 迣 滯 治 胵 鸷 鴙 鯯 骘 驇 騺 騭 駤 锧 铚 鑕 鋕 銍 轾 輊 踬 贽 豸 豒 豑 誌 觗 覟 製 袠 袟 蛭 芖 臸 膣 腟 翐 置 緻 紩 筫 穉 稺 稚 秲 秩 祑 礩 痣 痔 畤 璏 猘 狾 熫 炙 潌 滞 洷 櫍 梽 旘 摯 搱 挚 挃 懥 憄 忮 志 徝 徏 彘 廌 庤 庢 幟 帜 帙 崻 寘 娡 垁 厔 制 傂 偫 䱨 䭁 䬹 䫕 䦯 䥍 䡹 䞃 䝷 䚦 䕌 䓌 䑇 䐭 䏯 䏄 䉜 䉅 䇽 䆈 䄺 㴛 㨖 㣥 㝂 㛿 㘉 㗧 㗌 㕄 㧻 滍 䎺 䇛 只 黹 阯 酯 轵 軹 趾 訨 襧 藢 芷 纸 紙 祉 砋 疻 淽 洔 沚 止 栺 晊 旨 指 抧 扺 恉 帋 夂 坁 址 咫 厎 劧 䳅 䛗 䌤 䅩 㲛 㮹 膱 職 质 职 聀 懫 值 䱥 㨁 㜼 掷 跖 慹 摭 擿 犆 殖 柣 馽 釞 軄 躑 蹠 踯 貭 褁 蟙 蘵 縶 絷 稙 秷 禃 直 瓡 瓆 漐 樴 植 执 姪 妷 執 埴 劕 儨 値 侄 䵂 䟈 䐈 㙷 吱 织 織 知 脂 秖 胑 枳 汁 肢 枝 胝 鵄 鼅 鸱 鴲 鳷 馶 隻 衼 蜘 芝 綕 秪 秓 祬 祗 疧 汥 榰 椥 梔 栀 支 搘 巵 嬂 墌 坧 卮 之 䦛 徵 絼 䠦 蟄 㯰 晢 晣 秇 䚳 䝰 㾅 識 㫑 䶡 䚇 䰴 衹 祁 鮨 耆 祇 酈 郦 鳩 櫛 栉 䪒 㡶 瘈 䤠 剬 㜱 䞇 䘭 㬪 㫼 䲀 䑭 䏑 䀸 䧝 䱃 砥 䂡 氐 蹢 㥁 蹛 㿃 䩢 zhong 㲴 衶 祌 湩 重 諥 衆 蚛 茽 緟 筗 眾 狆 媑 妕 堹 偅 众 仲 乑 䱰 㐺 種 踵 种 塚 腫 肿 瘇 歱 尰 塚 喠 冢 㣫 衷 中 銿 忪 盅 鴤 锺 钟 鐘 鍾 鈡 蹱 衳 螽 蔠 舯 终 終 籦 煄 炂 潨 泈 汷 柊 忠 彸 幒 妐 刣 伀 穜 䳋 鼨 zhou 骤 驟 騶 驺 謅 諏 注 舳 噣 䇠 皺 縐 𤏲 駎 酎 詋 葤 荮 胄 绉 纣 紂 粙 籕 籒 籀 皱 甃 晝 昼 宙 咮 咒 呪 冑 僽 伷 䶇 䩜 䛆 䐍 䋓 䈙 㾭 㼙 㥮 㔌 㑳 㑇 鯞 菷 肘 箒 睭 疛 晭 帚 䖞 䎻 軸 轴 妯 㛩 鸼 鵃 啁 粥 脽 洀 盩 婤 騆 銂 週 辀 輖 輈 赒 賙 诪 譸 舟 矪 珘 烐 淍 洲 徟 州 喌 周 侜 㲴 鬻 鈾 䭥 鲖 鮦 䐌 䔭 㝌 碡 㥁 㫶 zhu 騶 櫡 著 箸 柱 祝 注 杼 苧 麆 驻 駐 馵 飳 霔 铸 鑄 鋳 鉒 軴 跓 諔 註 蛀 莇 翥 羜 纻 紸 紵 筯 竚 眝 疰 炷 殶 樦 柷 嵀 坾 助 住 佇 伫 䭖 䬡 䝬 䝒 䐢 䎷 䍆 䇧 䇡 㿾 㾻 㺛 㹥 㫂 㧣 㤖 㝉 㑏 贮 貯 砫 欘 斸 陼 麈 詝 罜 矚 瞩 煮 煑 濐 渚 拄 宔 孎 壴 囑 嘱 主 丶 䰞 䘢 㵭 躅 築 筑 瘃 䌵 舳 窋 竺 逐 鱁 趉 蠾 蠋 蓫 茿 篫 笜 笁 竹 爥 燭 烛 炢 灟 劚 䮱 䥮 䟉 䘚 䕽 㔉 朱 諸 諸 猪 鼄 鴸 鯺 鮢 铢 銖 邾 跦 豬 诸 诛 誅 袾 蠩 蝫 蛛 茱 絑 秼 祩 硃 珠 猪 瀦 潴 洙 櫫 櫧 橥 槠 株 劯 侏 䇠 軸 轴 膱 胑 鬻 蚰 芧 牏 庻 澍 屬 属 钃 䠱 鸀 泞 苎 䪒 䘄 枓 䠼 䳠 䎝 zhua 爪 抓 撾 挝 髽 膼 檛 簻 zhuai 跩 𨋯 拽 zhuan 贃 賺 馔 饌 籑 撰 篹 腞 𧸖 赚 譔 襈 蒃 縳 篆 瑑 灷 堟 囀 啭 僎 䉵 转 轉 転 竱 孨 䡱 磚 砖 鱄 篿 叀 耑 膞 鷒 颛 顓 鄟 蟤 甎 瑼 專 専 嫥 塼 专 摶 抟 剸 湍 㑷 䧘 䤄 䚈 䏝 傳 zhuang 撞 狀 状 焋 壵 壯 壮 樁 桩 裝 装 莊 荘 糚 粧 梉 庄 娤 妝 妆 僮 戇 戆 戅 贛 幢 zhui 錣 鵽 缀 綴 餟 鑆 赘 贅 譵 諈 膇 缒 縋 笍 窡 礈 硾 甀 惴 墜 坠 䄌 沝 追 隹 椎 鵻 鴭 骓 騅 锥 錐 娺 䃍 㿢 㾽 魋 𡑞 萑 䨺 腏 䋘 醊 埀 㝽 zhun 稕 鶽 綧 準 埻 准 谆 諄 迍 窀 棆 肫 衠 宒 胗 忳 飩 湻 zhuo 蕞 劅 丵 琢 焯 鐯 槕 拙 錣 櫡 茁 啄 濯 汋 棁 鐲 灂 踔 鷟 镯 鋜 酌 诼 謶 諑 蠗 罬 籱 籗 篧 禚 硺 琸 烵 炪 灼 濁 浞 浊 泎 椓 棳 梲 晫 斵 斲 斱 斮 斫 斀 擢 擆 撯 彴 妰 圴 啅 叕 剢 䶂 䕴 䅵 㺟 㭬 㪬 㣿 涿 棹 𠭴 穱 穛 桌 捉 卓 倬 㑁 肫 噣 㧻 櫂 䵵 鸀 䐁 㒂 䟾 䏐 㓸 㠚 㹿 䙯 㲋 畷 絀 zi 漬 扻 恣 茡 自 胾 胔 眦 眥 牸 渍 字 剚 倳 䐉 䅆 㱴 㰷 㰣 子 芓 訾 訿 仔 胏 茈 𠂔 釨 虸 耔 紫 籽 笫 秭 秄 矷 滓 榟 梓 杍 姊 姉 啙 呰 吇 䘣 䔂 㺭 㧗 㜽 觜 輺 輜 資 椔 孶 孳 菑 甾 孖 稵 粢 秶 鹚 鷀 鶿 茊 滋 兹 玆 茲 齜 龇 齍 鼒 鶅 鴜 鲻 鯔 髭 頿 頾 镃 锱 鎡 鍿 錙 鈭 鄑 辎 趦 资 赀 貲 谘 諮 葘 缁 緇 紎 禌 澬 湽 淄 栥 嵫 孜 姿 姕 嗞 咨 呲 㞨 鋅 㾅 亝 瘠 㑵 䴾 㧘 㢀 䦻 餈 糍 疵 趑 zong 縱 纵 综 縦 糭 糉 粽 碂 瘲 疭 猔 昮 倊 䝋 䍟 總 縂 摠 揔 总 蓗 総 熜 搃 捴 愡 惣 傯 偬 䰌 㹅 㷓 㢔 綜 緵 鯼 鯮 鬷 鬉 鬃 骔 騣 騌 鑁 蹤 踪 踨 豵 蝬 葼 艐 腙 翪 緃 稯 磫 猣 熧 椶 棕 朡 惾 嵸 嵕 嵏 宗 堫 倧 㯶 䡯 䁓 憁 緫 樅 zou 揍 奏 䠫 㵵 㔿 赱 走 騶 驺 謅 诌 諏 陬 鄹 鄒 齱 齺 黀 鲰 鯫 郰 邹 诹 菆 緅 箃 棸 棷 掫 媰 㞫 䲀 楱 zu 唨 阻 組 祖 靻 诅 詛 组 珇 爼 俎 䖕 䔃 捽 䯿 族 鎐 足 踤 崪 崒 蹵 卒 鏃 镞 踿 稡 哫 卆 䱣 䚝 䅸 㲞 㰵 㞺 租 蒩 㧻 柤 驵 駔 趲 菹 葅 苴 謯 紣 淬 㵀 蹴 䬨 㲋 zuan 钻 鑚 饡 攥 揝 䤸 纂 𤎱 缵 纘 纉 繤 籫 䌣 䂎 鑽 躦 躜 贃 篹 䡅 㷪 zui 蕞 錊 鋷 醉 酻 酔 辠 襊 罪 絊 祽 檌 檇 槜 栬 最 晬 䘹 㰎 㠑 㝡 璻 濢 洅 嶵 嶊 噿 嘴 䮔 脧 蟕 纗 樶 嶉 厜 觜 酨 蕝 㭰 zun 鳟 鱒 銌 燇 捘 譐 撙 噂 僔 繜 樽 墫 壿 鷷 鐏 遵 罇 嶟 尊 䔿 臶 zuo 作 柞 侳 酢 阼 袏 葄 胙 糳 祚 怍 座 岞 岝 夎 坐 唑 做 䔘 䋏 㭮 㛗 㘴 㘀 㑅 唨 毑 繓 左 咗 佐 㝾 㸲 鈼 葃 筰 稓 秨 椊 昨 䞰 䝫 䎰 嘬 捽 䯿 琢 飵 砟 䞢 苲 迮 㣱 笮 㤰 䩦 䟄 莋 䦈 㶡 䟶 撮 cmigemo-1.8.0/dict/optimize-dict.pl000077500000000000000000000025511524447636500172270ustar00rootroot00000000000000#!/usr/bin/env perl # vim:set ts=8 sts=4 sw=4 tw=0 et: # # optimize-dict.pl - Optimize migemo-dict to load by C/Migemo. # # Author: MURAOKA Taro use strict; use warnings; binmode STDOUT, ':utf8'; binmode STDIN, ':utf8'; my %migemo; my @migemo; # Extract the midpoint from a sorted array using DFS and rearrange the # elements. sub balance_array { my (@arr) = @_; my @result; my $dfs; $dfs = sub { my ($low, $high) = @_; return if $low > $high; my $mid = int(($low + $high) / 2); push @result, $arr[$mid]; $dfs->($low, $mid - 1); $dfs->($mid + 1, $high); }; $dfs->(0, $#arr); return @result; } # Read migemo-dict file. while (<>) { chomp; next if /^;/; my ($label, @word) = split /\t/; $label = lc($label); # Key must be lower case push @migemo, $label; push @{$migemo{$label}}, @word; } @migemo = balance_array(sort {$a cmp $b} @migemo); # Write migemo-dict file. my $i; for ($i = 0; $i < @migemo; ++$i) { my $label = $migemo[$i]; if (exists $migemo{$label}) { my @values = uniq_array($migemo{$label}); @values = balance_array(@values); print "$label\t" . join("\t", @values) . "\n"; delete $migemo{$label}; } } sub uniq_array { my %array = map {$_, 1} @{$_[0]}; return sort keys %array } cmigemo-1.8.0/dict/roma2hira.dat000066400000000000000000000060411524447636500164620ustar00rootroot00000000000000# vim:set ts=8 sts=8 sw=8 tw=0 noet: # # roma2hira.dat - Table to convert ROMAJI to HIRAGANA in Japanese. # # Format: {INPUT}\t{EMIT}[\t{REMAIN}] a あ i い u う e え o お ka か ki き ku く ke け ko こ sa さ si し su す se せ so そ ta た ti ち tu つ te て to と na な ni に nu ぬ ne ね no の ha は hi ひ hu ふ he へ ho ほ ma ま mi み mu む me め mo も ya や yi い yu ゆ ye いぇ yo よ ra ら ri り ru る re れ ro ろ wa わ wi ゐ wu う we ゑ wo を ga が gi ぎ gu ぐ ge げ go ご za ざ zi じ zu ず ze ぜ zo ぞ da だ di ぢ du づ de で do ど ba ば bi び bu ぶ be べ bo ぼ pa ぱ pi ぴ pu ぷ pe ぺ po ぽ la ぁ li ぃ lu ぅ le ぇ lo ぉ lya ゃ lyi ぃ lyu ゅ lye ぇ lyo ょ xa ぁ xi ぃ xu ぅ xe ぇ xo ぉ xya ゃ xyi ぃ xyu ゅ xye ぇ xyo ょ kya きゃ kyi きぃ kyu きゅ kye きぇ kyo きょ gwa ぐぁ gwi ぐぃ gwu ぐぅ gwe ぐぇ gwo ぐぉ gya ぎゃ gyi ぎぃ gyu ぎゅ gye ぎぇ gyo ぎょ sha しゃ shi し shu しゅ she しぇ sho しょ swa すぁ swi すぃ swu すぅ swe すぇ swo すぉ sya しゃ syi しぃ syu しゅ sye しぇ syo しょ tha てゃ thi てぃ thu てゅ the てぇ tho てょ tsa つぁ tsi つぃ tsu つ tse つぇ tso つぉ twa とぁ twi とぃ twu とぅ twe とぇ two とぉ tya ちゃ tyi ちぃ tyu ちゅ tye ちぇ tyo ちょ dha でゃ dhi でぃ dhu でゅ dhe でぇ dho でょ nya にゃ nyi にぃ nyu にゅ nye にぇ nyo にょ hya ひゃ hyi ひぃ hyu ひゅ hye ひぇ hyo ひょ bya びゃ byi びぃ byu びゅ bye びぇ byo びょ pya ぴゃ pyi ぴぃ pyu ぴゅ pye ぴぇ pyo ぴょ mya みゃ myi みぃ myu みゅ mye みぇ myo みょ rya りゃ ryi りぃ ryu りゅ rye りぇ ryo りょ ca か ci し cu く ce せ co こ cha ちゃ chi ち chu ちゅ che ちぇ cho ちょ fa ふぁ fi ふぃ fu ふ fe ふぇ fo ふぉ fwa ふぁ fwi ふぃ fwu ふぅ fwe ふぇ fwo ふぉ fya ふゃ fyi ふぃ fyu ふゅ fye ふぇ fyo ふょ ja じゃ ji じ ju じゅ je じぇ jo じょ jya じゃ jyi じぃ jyu じゅ jye じぇ jyo じょ qa くぁ qi くぃ qu く qe くぇ qo くぉ qwa くぁ qwi くぃ qwu くぅ qwe くぇ qwo くぉ qya くゃ qyi くぃ qyu くゅ qye くぇ qyo くょ va ヴぁ vi ヴぃ vu ヴ ve ヴぇ vo ヴぉ vya ヴゃ vyi ヴぃ vyu ヴゅ vye ヴぇ vyo ヴょ nn ん n' ん xn ん ltu っ xtu っ lwa ゎ xwa ゎ lka ヵ xka ヵ lke ヶ xke ヶ kwa くぁ - ー ~ ~ mba んば mbi んび mbu んぶ mbe んべ mbo んぼ mpa んぱ mpi んぴ mpu んぷ mpe んぺ mpo んぽ mma んま mmi んみ mmu んむ mme んめ mmo んも tcha っちゃ tchi っち tchu っちゅ tche っちぇ tcho っちょ bb っ b cc っ c dd っ d ff っ f gg っ g hh っ h jj っ j kk っ k ll っ l mm っ m pp っ p qq っ q rr っ r ss っ s tt っ t vv っ v ww っ w xx っ x yy っ y zz っ z nb ん b nc ん c nd ん d nf ん f ng ん g nh ん h nj ん j nk ん k nl ん l nm ん m np ん p nq ん q nr ん r ns ん s nt ん t nv ん v nw ん w nx ん x nz ん z cmigemo-1.8.0/dict/skk2migemo.pl000077500000000000000000000020771524447636500165210ustar00rootroot00000000000000#!/usr/bin/env perl # vim:set ts=8 sts=4 sw=4 tw=0 et: # # conv.pl - Convert SKK-JISYO to migemo-dict # # Author: MURAOKA Taro use strict; use warnings; binmode STDOUT, ':utf8'; binmode STDIN, ':utf8'; while (<>) { chomp; if (m/^;/) { print "$_\n"; next; } m/^([^ ]+) +(.*)$/; my ($key, $value) = ($1, $2); # Skip special key next if $key =~ m/^[<>?]/ or $key =~ m/[<>?]$/; # key have number expansion my $have_number = ($key =~ m/#/) ? 1 : 0; # Remove "okuri" if ($key =~ m/[a-z]$/ and $key !~ m/^[ -~]+$/) { $key =~ s/.$//; } $value =~ s{^/}{}; $value =~ s{/$}{}; my @values = grep { # Remove lisp expressions. $_ !~ m/^\([a-zA-Z].*\)$/; } grep { # Remove values have number expression !$have_number || $_ !~ m/#/; } map { # Remove annotation s/;.*$//; $_; } split(/\s*\/\s*/, $value); # Output if ($key ne '' and @values) { print "$key\t" . join("\t", sort @values) . "\n"; } } cmigemo-1.8.0/dict/zen2han.dat000066400000000000000000000027231524447636500161460ustar00rootroot00000000000000# vi:set ts=8 sts=8 sw=8 tw=0 noet: # # zen2han.dat - 全角→半角変換表 # # Author: MURAOKA Taro ! ! ” " # # $ $ % % & & ’ ' ( ( ) ) * * + + , , - - . . / / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 : : ; ; < < = = > > ? ? @ @ A A B B C C D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z Z [ [ ¥ \ ] ] ^ ^ _ _ ‘ ` a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z { { | | } } ~ ~ 。 。 「 「 」 」 、 、 ・ ・ ヲ ヲ ァ ァ ィ ィ ゥ ゥ ェ ェ ォ ォ ャ ャ ュ ュ ョ ョ ッ ッ ー ー ア ア イ イ ウ ウ エ エ オ オ カ カ キ キ ク ク ケ ケ コ コ サ サ シ シ ス ス セ セ ソ ソ タ タ チ チ ツ ツ テ テ ト ト ナ ナ ニ ニ ヌ ヌ ネ ネ ノ ノ ハ ハ ヒ ヒ フ フ ヘ ヘ ホ ホ マ マ ミ ミ ム ム メ メ モ モ ヤ ヤ ユ ユ ヨ ヨ ラ ラ リ リ ル ル レ レ ロ ロ ワ ワ ン ン ゛ ゙ ゜ ゚ ヴ ヴ ガ ガ ギ ギ グ グ ゲ ゲ ゴ ゴ ザ ザ ジ ジ ズ ズ ゼ ゼ ゾ ゾ ダ ダ ヂ ヂ ヅ ヅ デ デ ド ド バ バ ビ ビ ブ ブ ベ ベ ボ ボ パ パ ピ ピ プ プ ペ ペ ポ ポ cmigemo-1.8.0/doc/000077500000000000000000000000001524447636500137255ustar00rootroot00000000000000cmigemo-1.8.0/doc/README_ja.txt000066400000000000000000000551601524447636500161040ustar00rootroot00000000000000C/Migemoライブラリ説明書 Since: 15-Aug-2001 Version: 1.4.0rc Author: MURAOKA Taro (KoRoN) 注意: 本ドキュメントの内容は更新されていません。そのため実体とズレているところ があります。 説明 C/MigemoはMigemo(Ruby/Migemo)をC言語で実装したものです。C/Migemoライブラリを 利用するソフトウェアは「ローマ字のまま日本語を(インクリメンタルに)検索する」 機能を持つことが可能になります。C言語で実装したことにより、本家Ruby/Migemoに 比べ、C言語で書かれた多くのソフトウェアからの利用が容易になること、及び(たぶ ん)実行速度の向上が期待できます。 またC/Migemoを利用するためには別途辞書ファイル(dict/migemo-dict)を作成もしく は入手する必要があります。自分でまったくのゼロから辞書を作成することもできま すが、Ruby/Migemoのmigemo-dictを流用したり、SKKの辞書からコンバートすること も可能です。詳しくは下記の「辞書について」のセクションを参照してください。 Ruby/Migemoは高林 哲さんが考案した「ローマ字入力を日本語検索のための正規表現 に変換する」ツールです。Emacs上でローマ字のまま日本語をインクリメンタル検索 するために、RubyとEmacs LISPで実装されていました。 - 本家Ruby/Migemoサイト (Migemoに関する詳細情報) http://migemo.namazu.org/ - C/Migemo製作・配布サイト (C/Migemoの情報) http://www.kaoriya.net/ ファイル構成 C/Migemoのパッケージは現在のところ次のようなファイル・ディレクトリから構成さ れています。 (ディレクトリ) compile/ :各プラットホーム用のメイクファイル置き場 compile/vs6 :VS6用プロジェクト compile/vs2003 :VS2003用プロジェクト doc/ :ドキュメント置き場 dict/ :辞書置き場 tools/ :各種ツール src/ :ソースファイル (ファイル) Makefile :統合メイクファイル README.txt :各ドキュメントへのポインタ VERSION :バージョン番号 config.mk :デフォルトコンフィギュレーション (ソースコード) src/内 depend.mak :構成ファイルと依存関係 migemo.h :ライブラリを利用するのためのインクルードファイル main.c :ライブラリを利用するサンプルプログラム(cmigemo) *.c :ライブラリのソース *.h :ライブラリのソース用インクルードファイル コンパイル方法 コンパイルには以下の3段階の手順があります。 1. ライブラリとプログラムのビルド 2. 辞書ファイルのビルド 3. インストール 「辞書ファイルのビルド」には別途以下の4種が必要になります。 1. Perl 2. インターネットアクセスプログラム(cURL, wget, fetchの内どれか1つ) 3. 解凍伸長プログラムgzip 4. エンコード変換プログラム(nkf, qkc) これらを含むC/Migemoのビルドに必要な外部プログラムはconfig.mkを編集すること で変更可能です。また以下のプラットホーム別のビルド方法で利用しているように UNIXライクな環境では自動的にconfig.mkを修正する仕組み(configure)を利用できま す。config.mkのオリジナルファイルはcompile/config_default.mkとして収録してあ るのでいつでも復元可能です。 各プラットホームでのビルド方法の具体例は以下を参照してください。 1. Windows + VisualC++ 2. Windows + Cygwin 3. Windows + Borland C++ 4. MacOS X + Developer Tools 5. GNU/gcc:Linux他 現在のところ以上5環境で動作の確認をしています。5.のGNU/gccについてはFreeBSD 5.0です。 (Windows + VisualC++) 次のコマンドでRelease/内にmigemo.dllとcmigemo.exeが作成されます。 > nmake msvc 必要な外部プログラム、ネットワーク接続が揃っていれば > nmake msvc-dict で辞書ファイルをビルドできます。migemo.dswをVC++6.0で開き、ビルドする方法も あります。以上が終了すれば次のコマンドでテストプログラムが動作します。 > .\build\cmigemo -d dict/migemo-dict (Windows + Cygwin) 必要な外部プログラム、ネットワーク接続を揃えて以下を実行することでテストプロ グラムcmigemoと辞書ファイルがビルドされます: $ ./configure $ make cyg $ make cyg-dict 実行はcp932(Shift-JIS)で利用するならば: $ ./build/cmigemo -d dict/migemo-dict euc-jpで利用するならば: $ ./build/cmigemo -d dict/euc-jp.d/migemo-dict を実行します。インストールとアンインストールはroot権限で次のコマンドを実行す ることで行なえます。インストール場所についてはconfig.mkを参照してください。 # make cyg-install # make cyg-uninstall (Windows + Borland C++) 次のコマンドでmigemo.dllとcmigemo.exeが作成されます。 > make bc 必要な外部プログラム、ネットワーク接続が揃っていれば > nmake bc-dict で辞書ファイルをビルドできます。以上が終了すれば次のコマンドでテストプログラ ムが動作します。 > .\build\cmigemo -d dict/migemo-dict (MacOS X + Developer Tools) 必要な外部プログラム、ネットワーク接続を揃えて以下を実行することでテストプロ グラムcmigemoと辞書ファイルがビルドされます: % ./configure % make osx % make osx-dict 実行はcp932(Shift-JIS)で利用するならば: % ./build/cmigemo -d dict/migemo-dict euc-jpで利用するならば: % ./build/cmigemo -d dict/euc-jp.d/migemo-dict を実行します。インストールとアンインストールはroot権限で次のコマンドを実行す ることで行なえます。インストール場所についてはconfig.mkを参照してください。 # make osx-install # make osx-uninstall インストールにより辞書ファイルは /usr/local/share/migemo/{エンコード名} に置かれます。 (GNU/gcc:Linux他) 必要な外部プログラム、ネットワーク接続を揃えて以下を実行することでテストプロ グラムcmigemoと辞書ファイルがビルドされます: $ ./configure $ make gcc $ make gcc-dict 実行はcp932(Shift-JIS)で利用するならば: $ ./build/cmigemo -d dict/migemo-dict euc-jpで利用するならば: $ ./build/cmigemo -d dict/euc-jp.d/migemo-dict を実行します。インストールとアンインストールはroot権限で次のコマンドを実行す ることで行なえます。インストール場所についてはconfig.mkを参照してください。 # make gcc-install # make gcc-uninstall インストールにより辞書ファイルは /usr/local/share/migemo/{エンコード名} に置かれます。 利用許諾条件 C/MigemoはMITライセンスと独自ライセンスのデュアルライセンスとして配布されて います。利用者は都合に応じて、より適合するライセンスを選択して利用してくださ い。 MITライセンスについてはdoc/LICENSE_MIT.txtを参照してください。 独自ラインセンスについてはdoc/LICENSE_j.txtを参照してください。 辞書の著作権・利用許諾条件 C/Migemoで利用する辞書の諸権利、利用許諾条件及び著作権等はその辞書の定めると ころに従います。C/MigemoはSKK辞書を用いるように初期設定されていますが、SKK辞 書の利用許諾条件はC/Migemoのそれとは法的に別であることに注意してください。 質問・連絡先 C/Migemoに関する質問・要望等は村岡(下記アドレス参照)まで連絡してください。ソ フトウェアからC/Migemoを使用したい場合の問い合わせも受け付けます。 謝辞 Migemoを発案されRuby/Migemoを作成され、C/Migemoについての相談にMLで親切に答 えていただいた高林 哲さんに感謝いたします。また、この配布パッケージには以下 の方々によるドキュメントやアイデアが含まれています。ありがとうございます。 (アルファベット順) - AIDA Shinra CygwinとLinux用Makefileの基礎 - FUJISHIMA Hiroshi Solaris用Makefileの提供 - MATSUMOTO Yasuhiro Borland C++用Makefileの基礎 migemo.vimをcmigemoに対応 VB用サンプル - SUNAOKA Norifumi Solaris用Makefileの不具合報告 - TASAKA Mamoru MITライセンス版のリリースに協力 - gageas (https://twitter.com/gageas) Migemo.csの修正&改良 付録 辞書について {{{1 C/Migemoではローマ字を日本語へ変換するのに辞書ファイルdict/migemo-dictを必要 とします。ファイルdict/migemo-dictはこのアーカイブに含まれていませんが、辞書 ファイルのビルド時にインターネットを通じて自動的にダウンロードする仕組みにな っています。また大変ですが自分で0から作成することも可能です。 辞書に関するツール、その使用法はdict/Makefileを参照してください。 C/Migemoでは 1. dict/migemo-dict以外にも、 2. ローマ字を平仮名に変換するためのファイル(dict/roma2hira.dat)や、 3. 平仮名を片仮名に変換するためのファイル(dict/hira2kata.dat)や、 4. 半角文字を全角文字に変換するためのファイル(dict/han2zen.dat) 5. 全角文字を半角文字に変換するためのファイル(dict/zen2han.dat) を使用しています。これらの全てのファイルは単にデータテーブルとして機能してい るだけでなく、システムのエンコード(漢字コード)の違いを吸収する役割も担ってい ます。つまり先に挙げた4ファイルをWindowsで使う場合にはcp932に、UNIXやLinuxで 使う場合にはeuc-jpに変換する必要があるのです。変換が必要だと予想される場合に は、辞書ファイルのビルドと同時に自動的に行なわれるようになっています。 - Migemo DLL配布ページ (cp932のmigemo-dictが入手可能) http://www.kaoriya.net/ - Ruby/Migemo (euc-jpのmigemo-dictが入手可能) http://migemo.namazu.org/ - SKK Openlab (最新のSKK-JISYO.Lが入手可能) http://openlab.ring.gr.jp/skk/index-j.html 型リファレンス {{{1 C/Migemoで利用される型について述べる。 - migemo*; Migemoオブジェクト。migemo_open()で作成され、migemo_close()で破棄される。 - int (*MIGEMO_PROC_CHAR2INT)(const unsigned char*, unsigned int*); バイト列(unsigned char*)を文字コード(unsigned int)に変換するプロシージャ 型。Shift-JISやEUC-JP以外のエンコードの文字列を扱うとき、もしくは特殊文字 の処理を行いたいときに定義する。戻り値は文字列のうち処理したバイト数で、0 を返せばデフォルトのプロシージャが実行される。この仕組みで必要な文字だけに 処理を施すことが出来る。 - int (*MIGEMO_PROC_INT2CHAR)(unsigned int, unsigned char*); コード(unsigned int)をバイト列(unsigned char*)に変換するプロシージャ型。 Shift-JISやEUC-JP以外のエンコード文字列を扱うとき、もしくは特殊文字の処理 を行いたいときに定義する。戻り値は出力された文字列のバイト数で、0を返せば デフォルトのプロシージャが実行される。この仕組みで必要な文字だけに処理を施 すことが出来る。 関数リファレンス {{{1 C/Migemoライブラリで提供されるAPIを以下で解説する。実際の使用例はアーカイブ に含まれるmain.cを参照のこと。 - migemo* migemo_open(const char* dict); Migemoオブジェクトを作成する。作成に成功するとオブジェクトが戻り値として返 り、失敗するとNULLが返る。dictで指定したファイルがmigemo-dict辞書としてオ ブジェクト作成時に読み込まれる。辞書と同じディレクトリに: 1. roma2hira.dat (ローマ字→平仮名変換表) 2. hira2kata.dat (平仮名→カタカナ変換表) 3. han2zen.dat (半角→全角変換表) 3. zen2han.dat (全角→半角変換表) という名前のファイルが存在すれば、存在したものだけが読み込まれる。dictに NULLを指定した場合には、辞書を含めていかなるファイルも読み込まれない。ファ イルはオブジェクト作成後にもmigemo_load()関数を使用することで追加読み込み ができる。 - void migemo_close(migemo* object); Migemoオブジェクトを破棄し、使用していたリソースを解放する。 - unsigned char* migemo_query(migemo* object, const unsigned char* query); queryで与えられた文字列(ローマ字)を日本語検索のための正規表現へ変換する。 戻り値は変換された結果の文字列(正規表現)で、使用後はmigemo_release()関数へ 渡すことで解放しなければならない。 - void migemo_release(migemo* object, unsigned char* string); 使い終わったmigemo_query()関数で得られた正規表現を解放する。 - int migemo_load(migemo* obj, int dict_id, const char* dict_file); Migemoオブジェクトに辞書、またはデータファイルを追加読み込みする。 dict_fileは読み込むファイル名を指定する。dict_idは読み込む辞書・データの種 類を指定するもので以下のうちどれか一つを指定する: MIGEMO_DICTID_MIGEMO mikgemo-dict辞書 MIGEMO_DICTID_ROMA2HIRA ローマ字→平仮名変換表 MIGEMO_DICTID_HIRA2KATA 平仮名→カタカナ変換表 MIGEMO_DICTID_HAN2ZEN 半角→全角変換表 MIGEMO_DICTID_ZEN2HAN 全角→半角変換表 戻り値は実際に読み込んだ種類を示し、上記の他に読み込みに失敗したことを示す 次の価が返ることがある。 MIGEMO_DICTID_INVALID - int migemo_is_enable(migemo* obj); Migemoオブジェクトにmigemo_dictが読み込めているかをチェックする。有効な migemo_dictを読み込めて内部に変換テーブルが構築できていれば0以外(TRUE)を、 構築できていないときには0(FALSE)を返す。 - int migemo_set_operator(migemo* object, int index, const unsigned char* op); Migemoオブジェクトが生成する正規表現に使用するメタ文字(演算子)を指定する。 indexでどのメタ文字かを指定し、opで置き換える。indexには以下の値が指定可能 である: MIGEMO_OPINDEX_OR 論理和。デフォルトは "|" 。vimで利用する際は "\|" 。 MIGEMO_OPINDEX_NEST_IN グルーピングに用いる開き括弧。デフォルトは "(" 。vimではレジスタ\1~\9 に記憶させないようにするために "\%(" を用いる。Perlでも同様のことを目 論むならば "(?:" が使用可能。 MIGEMO_OPINDEX_NEST_OUT グルーピングの終了を表す閉じ括弧。デフォルトでは ")" 。vimでは "\)" 。 MIGEMO_OPINDEX_SELECT_IN 選択の開始を表す開き角括弧。デフォルトでは "[" 。 MIGEMO_OPINDEX_SELECT_OUT 選択の終了を表す閉じ角括弧。デフォルトでは "]" 。 MIGEMO_OPINDEX_NEWLINE 各文字の間に挿入される「0個以上の空白もしくは改行にマッチする」パター ン。デフォルトでは "" であり設定されない。vimでは "\_s*" を指定する。 デフォルトのメタ文字は特に断りがない限りPerlのそれと同じ意味である。設定に 成功すると戻り値は1(0以外)となり、失敗すると0になる。 - const unsigned char* migemo_get_operator(migemo* object, int index); Migemoオブジェクトが生成する正規表現に使用しているメタ文字(演算子)を取得す る。indexについてはmigemo_set_operator()関数を参照。戻り値にはindexの指定 が正しければメタ文字を格納した文字列へのポインタが、不正であればNULLが返 る。 - void migemo_setproc_char2int(migemo* object, MIGEMO_PROC_CHAR2INT proc); Migemoオブジェクトにコード変換用のプロシージャを設定する。プロシージャにつ いての詳細は「型リファレンス」セクションのMIGEMO_PROC_CHAR2INTを参照。 - void migemo_setproc_int2char(migemo* object, MIGEMO_PROC_INT2CHAR proc); Migemoオブジェクトにコード変換用のプロシージャを設定する。プロシージャにつ いての詳細は「型リファレンス」セクションのMIGEMO_PROC_INT2CHARを参照。 コーディングサンプル {{{1 C/Migemoを利用したコーディング例を示す。以下のサンプルは一切のエラー処理を行 なっていないので、実際の利用時には注意が必要。 #include #include "migemo.h" int main(int argc, char** argv) { migemo *m; /* C/Migemoの準備: 辞書読込にはエラー検出のためloadを推奨 */ m = migemo_open(NULL); migemo_load(m, MIGEMO_DICTID_MIGEMO, "./dict/migemo-dict"); /* 必要な回数だけqueryを行なう */ { unsigned char* p; p = migemo_query(m, "nezu"); printf("C/Migemo: %s\n", p); migemo_release(m, p); /* queryの結果は必ずreleaseする */ } /* 利用し終わったmigemoオブジェクトはcloseする */ migemo_close(m); return 0; } 更新箇所 {{{1 ● (1.3 開発版) VC9(VisualStudio2008)での64bit版のコンパイルに対応 VC9(VisualStudio2008)でのコンパイルに対応 ローマ字が子音で終わる際に「xtu{子音}{母音}」を加えるように変更 configureの--prefixが機能していなかった問題の修正 生queryでの辞書検索をignore caseに 英単語のエントリを小文字で正規化 VB用サンプル(tools/clsMigemo.cls)を追加 パターンの生成を高速化(rxget.c:rxgen_add) VS2003用プロジェクトファイル追加 全角→半角変換を追加 全角→半角辞書を追加 ローマ字変換でマルチバイト文字を考慮(Vim掲示板:1281) CP932/EUCJP/UTF8のエンコード自動判別機能を追加 migemo.vimをcmigemo.exe対応の改良版に差し替え ヘルプメッセージ内の余分な空白を削除 ● 29-Dec-2003 (1.2 正式版) 半角大文字を全角大文字に変換できないバグを修正 リリース用にドキュメントを修正 configureスクリプトを導入 Doxygenを導入する queryそのもので辞書を引くのを忘れていたのを修正 tools/Migemo.cs:体裁修正 ビルドディレクトリを変更(動作確認済:mvc,cyg,gcc,bc5) (1.1.023)migemo.c:EXPORTSの削除他 (1.1.022)dict/roma2hira.datに~→~の変換を追加 (1.1.021)Windows用Makefileを修正 (1.1.020)romaji.cのテストコードを分離 (1.1.019)辞書読み込み時のエラーを不完全ながら厳密化 (1.1.018)roma2hira.datにヘボン式のm[bmp]及びtch[aiueo]を追加 (1.1.017)利用許諾条件を整理 (1.1.016)cmigemoをサブ辞書(ユーザ辞書)に対応 (1.1.015)cmigemo出力後にfflush()を追加 (1.1.014)MSVC用プロジェクトファイルをmsvc/以下へ移動 (1.1.013)cmigemoに--emacs/-e及び--nonewline/-nを追加 (1.1.012)mkpkgを改良 (1.1.011)dict/roma2hira.datに[bp]y[aiueo]のエントリを追加 (1.1.010)migemo.vimをcmigemoに対応(by.まっつんさん) (1.1.009)Solarisでコンパイルできるようにするための変更 (1.1.008)SKK辞書の配布形態変更に追従 (1.1.007)デバッグメッセージをコメントにより削除 (1.1.006)config.mkに設定例をコメントとして追加 (1.1.005)C#用サンプルtools/*.csを追加 (1.1.004)連文節に対応(β版扱い) (1.1.003)Solaris用メイクファイルMake_sun.makを追加、未動作チェック (1.1.002)辞書の1行に複数エントリを出力できなくなっていた問題を修正 (1.1.001)migemo.vimをUNIX系に対応 ● 27-May-2002 (1.1 正式版) 正式版リリース ドキュメントブラッシュアップ Makefile修正:releaseが./Releaseのためにビルドできなかった問題 ● 16-May-2002 (1.1-beta2) BC5対応のためブチ切れ寸前…(_ _;;; Makefileの構造変更(BC5対応のため) 謝辞追加 パッケージ作成用スクリプトの追加 cmigemoをプログラムから使いやすく。 ● 15-May-2002 (1.1-beta1) migemo_set_operator()の戻り値の意味を変更 ドキュメントブラッシュアップ Cygwin/MacOS X/Linux用にMakefileを作成 strip.plとlensort.plをtool/optimize-dict.plに統合 tool/conv.plをtool/skk2migemodict.plに名称変更 ドキュメント修正 cacheを最適化して高速化 (mnode_load()) wordbuf_add()を最適化して高速化 (wordbuf.c) migemo辞書読み込み失敗を検出できなくなっていたバグ修正 mnodeをまとめて確保することで高速化 (mnode.c他) 辞書を長さ降順にソート (tools/lensort.pl) 起動を1割から2割高速化 (mnode.c) ● 21-Aug-2001 main.cのgets()をfgets()に変更 }}} ------------------------------------------------------------------------------- 生きる事への強い意志が同時に自分と異なる生命をも尊ぶ心となる MURAOKA Taro/村岡太郎 vi:set ts=8 sts=2 sw=2 tw=78 et fdm=marker ft=memo: cmigemo-1.8.0/doc/doxygen.conf000066400000000000000000001251041524447636500162540ustar00rootroot00000000000000# Doxyfile 1.3.4 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = C/Migemo # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = 1.4 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doc # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, # Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en # (Japanese with English messages), Korean, Norwegian, Polish, Portuguese, # Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = Japanese # This tag can be used to specify the encoding used in the generated output. # The encoding is not always determined by the language that is chosen, # but also whether or not the output is meant for Windows or non-Windows users. # In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES # forces the Windows encoding (this is the default for the Windows binary), # whereas setting the tag to NO uses a Unix-style encoding (the default for # all platforms other than Windows). USE_WINDOWS_ENCODING = YES # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited # members of a class in the documentation of that class as if those members were # ordinary class members. Constructors, destructors and assignment operators of # the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. It is allowed to use relative paths in the argument list. STRIP_FROM_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explict @brief command for a brief description. JAVADOC_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # reimplements. INHERIT_DOCS = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources # only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = src # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp # *.h++ *.idl *.odl *.cs *.php *.php3 *.inc FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories # that are symbolic links (a Unix filesystem feature) are excluded from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. EXCLUDE_PATTERNS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. INPUT_FILTER = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output dir. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = YES # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimised for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assigments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_PREDEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse the # parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::addtions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or # super classes. Setting the tag to NO turns the diagrams off. Note that this # option is superceded by the HAVE_DOT option below. This is only a fallback. It is # recommended to install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similiar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found on the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_WIDTH = 1024 # The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_HEIGHT = 1024 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes that # lay further from the root node will be omitted. Note that setting this option to # 1 or 2 may greatly reduce the computation time needed for large code bases. Also # note that a graph may be further truncated if the graph's image dimensions are # not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). # If 0 is used for the depth value (the default), the graph is not depth-constrained. MAX_DOT_GRAPH_DEPTH = 0 # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::addtions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO cmigemo-1.8.0/include/000077500000000000000000000000001524447636500146035ustar00rootroot00000000000000cmigemo-1.8.0/include/migemo.h.in000066400000000000000000000125021524447636500166360ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // migemo.h - // // Written By: MURAOKA Taro #pragma once #if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN32__) # define MIGEMO_CALLTYPE __stdcall #else # define MIGEMO_CALLTYPE #endif // clang-format off #define MIGEMO_VERSION "@PROJECT_VERSION@" #define MIGEMO_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ #define MIGEMO_VERSION_MINOR @PROJECT_VERSION_MINOR@ #define MIGEMO_VERSION_PATCH @PROJECT_VERSION_PATCH@ #define MIGEMO_VERSION_PRERELEASE "@PROJECT_VERSION_PRERELEASE@" // clang-format on #define MIGEMO_DICT_FILENAME "migemo-dict" // for migemo_load() #define MIGEMO_DICTID_INVALID 0 #define MIGEMO_DICTID_MIGEMO 1 #define MIGEMO_DICTID_ROMA2HIRA 2 #define MIGEMO_DICTID_HIRA2KATA 3 #define MIGEMO_DICTID_HAN2ZEN 4 #define MIGEMO_DICTID_ZEN2HAN 5 #define MIGEMO_DICTID_MIGEMO_SDICT 6 // for migemo_set_operator()/migemo_get_operator(). see: rxgen.h #define MIGEMO_OPINDEX_OR 0 #define MIGEMO_OPINDEX_NEST_IN 1 #define MIGEMO_OPINDEX_NEST_OUT 2 #define MIGEMO_OPINDEX_SELECT_IN 3 #define MIGEMO_OPINDEX_SELECT_OUT 4 #define MIGEMO_OPINDEX_NEWLINE 5 // see: rxgen.h typedef int (*MIGEMO_PROC_CHAR2INT)(const unsigned char *, unsigned int *); typedef int (*MIGEMO_PROC_INT2CHAR)(unsigned int, unsigned char *); /// Migemo object. Created by migemo_open() and destroyed by migemo_close. typedef struct migemo migemo; #ifdef __cplusplus extern "C" { #endif ////////////////////////////////////////////////////////////////////////////// // Information /// Get version string of C/Migemo library. /// @return Pointer to a static version string (e.g. "1.6.1"). const char *MIGEMO_CALLTYPE migemo_version(void); ////////////////////////////////////////////////////////////////////////////// // Life cycle management /// Create a Migemo object. /// /// Automatically loads standard conversion tables if present in the same /// directory as the specified dictionary. Failure to load sub-dictionaries is /// ignored. /// /// @param dict Path to dictionary file. If NULL, no dictionary is loaded. /// @return Pointer to created object, or NULL on failure. migemo *MIGEMO_CALLTYPE migemo_open(const char *dict); /// Destroy a Migemo object and free its resources. /// @param mo Object to destroy. void MIGEMO_CALLTYPE migemo_close(migemo *mo); ////////////////////////////////////////////////////////////////////////////// // Query /// Generate a regular expression pattern from a Romaji query. /// /// NOTE: The returned string is dynamically allocated. You MUST release it /// using migemo_release() after use to avoid memory leaks. /// @param mo Migemo object. /// @param query Query string in Romaji. /// @return Generated regex pattern string. unsigned char *MIGEMO_CALLTYPE migemo_query( migemo *mo, const unsigned char *query); /// Free memory allocated by migemo_query(). /// @param mo Migemo object. /// @param used_pattern Pointer to pattern string to free. void MIGEMO_CALLTYPE migemo_release(migemo *mo, unsigned char *used_pattern); ////////////////////////////////////////////////////////////////////////////// // Static dictionary (sdict) related // // sdict (Static Dictionary) is a flattened, highly-optimized binary // representation of the standard dynamic dictionary (mtree). It offers // significant performance advantages: // // - Fast Startup: Bypasses dictionary parsing during load. // - Memory Efficiency: Reduces pointer overhead by using flat array storage. // - High Performance: Improves CPU cache locality during query execution. // // You can convert an in-memory dictionary to sdict using // migemo_switch_sdict(), or save/load pre-compiled sdict files directly. /// Preserve migemo-dict to load incrementally, and rebuild. #define MIGEMO_SDICT_PRESERVE_MDICT 0 /// Release migemo-dict to memory compaction. #define MIGEMO_SDICT_RELEASE_MDICT 1 /// Convert current dictionary to sdict and switch active search engine. /// @param mo Migemo object. /// @param flags Option flags (e.g. MIGEMO_SDICT_PRESERVE_MDICT or /// MIGEMO_SDICT_RELEASE_MDICT). /// @return Non-zero on success, 0 on failure. int MIGEMO_CALLTYPE migemo_switch_sdict(migemo *mo, int flags); /// Save converted sdict data to a file. /// @param mo Migemo object. /// @param dict Output file path. /// @return Non-zero on success, 0 on failure. int MIGEMO_CALLTYPE migemo_save_sdict(migemo *mo, const char *dict_file); /// Open Migemo object directly with an sdict file. /// @param dict Path to sdict dictionary file. /// @return Pointer to created object, or NULL on failure. migemo *MIGEMO_CALLTYPE migemo_open_sdict(const char *dict_file); ////////////////////////////////////////////////////////////////////////////// // Configurations int MIGEMO_CALLTYPE migemo_set_operator( migemo *mo, int index, const unsigned char *op); const unsigned char *MIGEMO_CALLTYPE migemo_get_operator(migemo *mo, int index); void MIGEMO_CALLTYPE migemo_set_escape_chars( migemo *mo, const unsigned char *chars); void MIGEMO_CALLTYPE migemo_setproc_char2int( migemo *mo, MIGEMO_PROC_CHAR2INT proc); void MIGEMO_CALLTYPE migemo_setproc_int2char( migemo *mo, MIGEMO_PROC_INT2CHAR proc); int MIGEMO_CALLTYPE migemo_load(migemo *mo, int dict_id, const char *dict_file); int MIGEMO_CALLTYPE migemo_is_enable(migemo *mo); #ifdef __cplusplus } #endif cmigemo-1.8.0/index.md000066400000000000000000000056641524447636500146240ustar00rootroot00000000000000--- type: Directory Index title: "cmigemo Index" description: "C/Migemo regexp generator library: a CMake C11 project bundling the migemo shared library, dictionary sources, CTest suite, benchmarks, console tools, and a WebAssembly port." tags: [index] --- # Overview C/Migemo is a C-language implementation of Migemo, a regexp pattern generator/expander that converts Romaji input into regular expressions for incremental Japanese text searches. This root directory contains the CMake build, the shared library sources, dictionary sources, the CTest suite, benchmarking, console driver tools, and a WebAssembly port. # Directory Contents | File / Path | Type | Description | | :--- | :--- | :--- | | [CMakeLists.txt](./CMakeLists.txt) | Build Script | Top-level CMake build definition for the C/Migemo project. | | [Makefile](./Makefile) | Build Script | Convenience make targets wrapping the CMake build (build, test, profile, package). | | [README.md](./README.md) | Documentation | Project overview and usage documentation for the C/Migemo library. | | [AGENTS.md](./AGENTS.md) | Agent Guide | AI-agent guidance covering build, test, dictionary, and project conventions. | | [LICENSE](./LICENSE) | Legal | License text for C/Migemo. | | [.clang-format](./.clang-format) | Config | clang-format configuration for the C sources. | | [.cmakefmt.yaml](./.cmakefmt.yaml) | Config | cmakefmt configuration for CMake formatting. | | [.gitignore](./.gitignore) | Config | Git ignore rules for build outputs and generated files. | | [src/](./src/index.md) | Directory Index | C sources and headers for the migemo shared library core (dictionary tree, romaji, regexp, charset), with CMake build rules and Windows build support files. | | [dict/](./dict/index.md) | Directory Index | Dictionary sources for C/Migemo: build script, Perl conversion/optimization tools, static Japanese conversion tables, and a Chinese dictionary. | | [test/](./test/index.md) | Directory Index | CTest test suite (test1) for the cmigemo migemo library, with C sources, CMake build rules, and a static dictionary fixture. | | [bench/](./bench/index.md) | Directory Index | Benchmark and profiling tools for measuring migemo dictionary load and query performance. | | [tools/](./tools/index.md) | Directory Index | Console driver tools and their CMake build rules for the cmigemo project. | | [wasm/](./wasm/index.md) | Directory Index | WebAssembly port of cMigemo with its Emscripten build, JavaScript wrapper API, and browser demo. | | [include/](./include/) | Directory | Public C API header template (migemo.h.in) for the migemo library. | | [doc/](./doc/) | Directory | Japanese README and Doxygen configuration for API documentation generation. | | [misc/](./misc/) | Directory | Reference C# wrapper and vim plugin (not part of the build). | | [.github/](./.github/) | Directory | GitHub CI workflows and Dependabot configuration. | # References - [Agent Guidelines](./AGENTS.md) - [Project Readme](./README.md) cmigemo-1.8.0/misc/000077500000000000000000000000001524447636500141135ustar00rootroot00000000000000cmigemo-1.8.0/misc/csharp/000077500000000000000000000000001524447636500153735ustar00rootroot00000000000000cmigemo-1.8.0/misc/csharp/Migemo.cs000066400000000000000000000122021524447636500171340ustar00rootroot00000000000000// vim:set ts=4 sts=4 sw=4 tw=0: using System; using System.Runtime.InteropServices; using System.Text.RegularExpressions; namespace KaoriYa.Migemo { public class Migemo : IDisposable { #region Enumerations (from migemo.h) #region enum DictionaryIndex public enum DictionaryId { Invalid = 0, Migemo = 1, RomaToHira = 2, HiraToKata = 3, HanToZen = 4, } #endregion #region enum OperatorIndex public enum OperatorIndex { Or = 0, NestIn = 1, NestOut = 2, SelectIn = 3, SelectOut = 4, NewLine = 5, } #endregion #endregion #region Link to migemo.dll [DllImport("migemo.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private static extern IntPtr migemo_open(string dict); [DllImport("migemo.dll", CallingConvention = CallingConvention.Cdecl)] private static extern void migemo_close(IntPtr obj); [DllImport("migemo.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private static extern IntPtr migemo_query(IntPtr obj, string query); [DllImport("migemo.dll", CallingConvention = CallingConvention.Cdecl)] private static extern void migemo_release(IntPtr obj, IntPtr result); [DllImport("migemo.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private static extern int migemo_set_operator(IntPtr obj, OperatorIndex index, string op); [DllImport("migemo.dll", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr migemo_get_operator(IntPtr obj, OperatorIndex index); [DllImport("migemo.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private static extern DictionaryId migemo_load(IntPtr obj, DictionaryId id, string file); [DllImport("migemo.dll", CallingConvention = CallingConvention.Cdecl)] private static extern int migemo_is_enable(IntPtr obj); #endregion private IntPtr migemoObject = IntPtr.Zero; public IntPtr MigemoObject { get { return this.migemoObject; } } public bool SetOperator(OperatorIndex index, string op) { return migemo_set_operator(this.migemoObject, index, op) != 0; } public string GetOperator(OperatorIndex index) { IntPtr result = migemo_get_operator(this.migemoObject, index); if (result != IntPtr.Zero) return Marshal.PtrToStringAnsi(result); else return ""; } #region Operator properties public string OperatorOr { get { return GetOperator(OperatorIndex.Or); } set { SetOperator(OperatorIndex.Or, value); } } public string OperatorNestIn { get { return GetOperator(OperatorIndex.NestIn); } set { SetOperator(OperatorIndex.NestIn, value); } } public string OperatorNestOut { get { return GetOperator(OperatorIndex.NestOut); } set { SetOperator(OperatorIndex.NestOut, value); } } public string OperatorSelectIn { get { return GetOperator(OperatorIndex.SelectIn); } set { SetOperator(OperatorIndex.SelectIn, value); } } public string OperatorSelectOut { get { return GetOperator(OperatorIndex.SelectOut); } set { SetOperator(OperatorIndex.SelectOut, value); } } public string OperatorNewLine { get { return GetOperator(OperatorIndex.NewLine); } set { SetOperator(OperatorIndex.NewLine, value); } } #endregion public bool LoadDictionary(DictionaryId id, string file) { DictionaryId result = migemo_load(this.migemoObject, id, file); return result == id; } public bool IsEnable() { return migemo_is_enable(this.migemoObject) != 0; } public Regex GetRegex(string query) { return new Regex(Query(query)); } public string Query(string query) { IntPtr result = migemo_query(this.migemoObject, query); if (result != IntPtr.Zero) { string retval = Marshal.PtrToStringAnsi(result); migemo_release(this.migemoObject, result); return retval; } else return ""; } public void Dispose() { //Console.WriteLine("HERE ("+this.migemoObject+")"); if (this.migemoObject != IntPtr.Zero) { //Console.WriteLine("migemo_close() is called"); migemo_close(this.migemoObject); this.migemoObject = IntPtr.Zero; } GC.SuppressFinalize(this); } public Migemo(string dictpath) { this.migemoObject = migemo_open(dictpath); this.OperatorNestIn = "(?:"; //this.OperatorNewLine = "\\s*"; } public Migemo() : this(null) { } ~Migemo() { this.Dispose(); } #region Test entrypoint #if TEST_MIGEMO // eXg֐ public static int Main(string[] args) { Migemo m; if (args.Length > 0) { m = new Migemo(args[0]); Console.WriteLine("Migemo object is initialized with " +args[0]); } else { m = new Migemo(); Console.WriteLine("Migemo object is initialized"); } Console.WriteLine("MigemoObject="+m.MigemoObject); string result = m.Query("ao"); Console.WriteLine("ai="+result); OperatorIndex[] opall = { OperatorIndex.Or, OperatorIndex.NestIn, OperatorIndex.NestOut, OperatorIndex.SelectIn, OperatorIndex.SelectOut, OperatorIndex.NewLine }; foreach (OperatorIndex index in opall) Console.WriteLine("OperatorIndex[{0}]={1}", index, m.GetOperator(index)); return 0; } #endif #endregion } } cmigemo-1.8.0/misc/csharp/Test.cs000066400000000000000000000004111524447636500166350ustar00rootroot00000000000000// vim:set ts=4 sts=4 sw=4 tw=0: using System; using KaoriYa.Migemo; public class Test { public static int Main(string[] args) { Migemo m = new Migemo("../dict/migemo-dict"); string res = m.Query("kaki"); Console.WriteLine("kaki->"+res); return 0; } } cmigemo-1.8.0/misc/vim/000077500000000000000000000000001524447636500147065ustar00rootroot00000000000000cmigemo-1.8.0/misc/vim/migemo.vim000066400000000000000000000045371524447636500167110ustar00rootroot00000000000000" vim:set ts=8 sts=2 sw=2 tw=0: " " migemo.vim " Direct search for Japanese with Romaji --- Migemo support script. " " Maintainer: MURAOKA Taro " Modified: Yasuhiro Matsumoto scriptencoding utf-8 " Japanese Description: if exists('plugin_migemo_disable') finish endif let s:save_cpo = &cpo set cpo&vim function! s:SearchDict2(name) let path = $VIM . ',' . &runtimepath let dict = globpath(path, "dict/".a:name) if dict == '' let dict = globpath(path, a:name) endif if dict == '' for path in [ \ '/usr/local/share/migemo/', \ '/usr/local/share/cmigemo/', \ '/usr/local/share/', \ '/usr/share/cmigemo/', \ '/usr/share/', \ ] let path = path . a:name if filereadable(path) let dict = path break endif endfor endif let dict = matchstr(dict, "^[^\]*") return dict endfunction function! s:SearchDict() let dict = '' if dict == '' let dict = s:SearchDict2('migemo/'.&encoding.'/migemo-dict') endif if dict == '' let dict = s:SearchDict2(&encoding.'/migemo-dict') endif if dict == '' let dict = s:SearchDict2('migemo-dict') endif return dict endfunction if has('migemo') if &migemodict == '' || !filereadable(&migemodict) let &migemodict = s:SearchDict() endif " Test function! s:SearchChar(dir) let input = nr2char(getchar()) let pat = migemo(input) call search('\%(\%#.\{-\}\)\@<='.pat) noh endfunction nnoremap f :call SearchChar(0) else " non-builtin version let g:migemodict = s:SearchDict() command! -nargs=* Migemo :call MigemoSearch() nnoremap mi :call MigemoSearch('') function! s:MigemoSearch(word) if executable('cmigemo') == '' echohl ErrorMsg echo 'Error: cmigemo is not installed' echohl None return endif let retval = a:word != '' ? a:word : input('MIGEMO:') if retval == '' return endif let retval = system('cmigemo -v -w "'.retval.'" -d "'.g:migemodict.'"') if retval == '' return endif let @/ = retval let v:errmsg = '' silent! normal n if v:errmsg != '' echohl ErrorMsg echo v:errmsg echohl None endif endfunction endif let &cpo = s:save_cpo unlet s:save_cpo cmigemo-1.8.0/misc/vim/vimigemo.txt000066400000000000000000000123721524447636500172700ustar00rootroot00000000000000Migemo DLL説明書/Vimにおける使用方法 Since: 14-Aug-2001 Version: 1.0 Author: MURAOKA Taro (KoRoN) 説明 Migemo DLLはローマ字入力を日本語検索の正規表現に変換するライブラリです。これ によりライブラリのクライアント(ソフトウェア)は「ローマ字のまま日本語を(イン クリメンタルに)検索する」機能を持つことが可能になります。 元々MigemoとはEmacs用にRubyとLispで書かれたモジュールでした(Ruby/Migemo)。こ れをVimに組み込むにあたり、より汎用性を持たせるために、村岡がライブラリの形 でC言語により再実装しました(C/Migemo)。このC/MigemoをDLLとしてコンパイルした ものがMigemo DLLです。 このDLLをVim(6.0ar以降)で使用してVim上で「ローマ字のまま日本語を(インクリメ ンタルに)検索する」方法を解説します。 - 本家Ruby/Migemo (Migemoに関する詳細) http://migemo.namazu.org/ - Vim日本語版情報 (C/Migemo情報有) http://www.kaoriya.net/ - Vim掲示板 http://www.kaoriya.net/bbs/bbs.cgi インストール手順 以下の説明ではVimをインストールした(gvim.exeの置いてある)ディレクトリを$VIM と表記しています。必要ならば各自の環境に読み替えてください。 1. migemo.dllをインストールする migemo.dllをgvim.exeと同じディレクトリに置きます。同じディレクトリでなくて も環境変数PATHに含まれる場所のどれかであれば構いません。 2. スクリプト(migemo.vim)をインストールする runtime/plugin/migemo.vimを$VIM/runtime/plugin/に置きます。この作業は同梱 のruntimeディレクトリを$VIMへ上書きコピーすれば完了できます。関係の無い ファイルはまったく触らず上書きできますので安心して上書きコピーしてくださ い。その他、個人ディレクトリvimfiles/pluginに置くこともできます。 ※ $VIM/runtime/plugin/ はVimのバージョンにより、$VIM/vimfiles/plugin/に変 更されてる可能性があります。set runtimepath?で読み込み先を確認して下さい。 3. 辞書ファイルをインストールする $VIM/dictというディレクトリを作り、migemo-dict、roma2hira.dat、han2zen.dat そしてhira2kata.datを置きます。この作業は同梱のdictディレクトリを$VIMへ上 書きコピーすれば完了できます。関係の無いファイルはまったく触らず上書きでき ますので安心して上書きコピーしてください。その他、個人ディレクトリ vimfiles/dictに置く事もできます。 使用方法 ライブラリ(DLL)と辞書それにスクリプトをインストールすれば(この時'incsearch' はもちろん有効になっているものと考えています) g/がMigemoによる検索の開始に マップされます。ただし初回の検索時に限り、結果が出るのに少々時間がかかりま す。これは大きな辞書の読み込みに時間がかかっているためです。 g?についてはVimの:help rot13の機能と衝突するため、デフォルトの状態では利用で きません。g?をMigemoによる拡張検索にマップしたい場合は :set migemo してください。 利用許諾条件 doc/LICENSE_j.txt 辞書の著作権・利用許諾条件 Migemo DLLで利用する辞書の諸権利、利用許諾条件及び著作権等はその辞書の定める ところに従います。Migemo DLLはSKK辞書を用いるように初期設定されていますが、 SKK辞書の利用許諾条件はMigemo DLLのそれとは法的に別であることに注意してくだ さい。 質問・連絡先 Migemo DLLに関する質問・要望等は村岡(下記アドレス参照)まで連絡してください。ソ フトウェアからMigemo DLLを使用したい場合の問い合わせも受け付けます。 謝辞 Migemoを発案されRuby/Migemoを作成され、C/Migemoについての相談にMLで親切に答 えていただいた高林 哲さんに感謝いたします。また、この配布パッケージには以下 の方々によるドキュメントやアイデアが含まれています。ありがとうございます。 (アルファベット順) - MATSUMOTO Yasuhiro migemo.vimをcmigemoに対応 更新箇所 ● 26-Apr-2019 ドキュメント修正 ● 16-Dec-2003 C/Migemo 1.2 ドキュメント修正 ● 27-May-2002 C/Migemo 1.1と再パッケージ ● 08-Sep-2001 プラグインでhas('migemo')をチェックするように変更 ● 14-Aug-2001 初版リリース ------------------------------------------------------------------------------- 生きる事への強い意志が同時に自分と異なる生命をも尊ぶ心となる Muraoka Taro/村岡太郎 vim:set ts=8 sts=2 sw=2 tw=78 et ft=memo: cmigemo-1.8.0/src/000077500000000000000000000000001524447636500137475ustar00rootroot00000000000000cmigemo-1.8.0/src/CMakeLists.txt000066400000000000000000000037411524447636500165140ustar00rootroot00000000000000configure_file( "${PROJECT_SOURCE_DIR}/include/migemo.h.in" "${CMAKE_CURRENT_BINARY_DIR}/include/migemo.h" @ONLY) configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/migemo.rc.in" "${CMAKE_CURRENT_BINARY_DIR}/migemo.rc" @ONLY) #------------------------------------------------------------------------------ add_library( migemo_objects charset.c filename.c migemo.c mtree.c stree.c romaji.c rxgen.c trie.c strbuf.c wordlist.c) target_include_directories( migemo_objects PUBLIC $ $) set_target_properties(migemo_objects PROPERTIES POSITION_INDEPENDENT_CODE ON) #------------------------------------------------------------------------------ add_library( migemo SHARED migemo.def "${CMAKE_CURRENT_BINARY_DIR}/migemo.rc" $) target_include_directories( migemo PUBLIC $ $ $) set_target_properties( migemo PROPERTIES OUTPUT_NAME "migemo" VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) #------------------------------------------------------------------------------ add_library(migemo_static STATIC $) target_include_directories( migemo_static PUBLIC ${PROJECT_SOURCE_DIR}/src $ $) #------------------------------------------------------------------------------ install( TARGETS migemo RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT core LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT core ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT core) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/include/migemo.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT core) cmigemo-1.8.0/src/charset.c000066400000000000000000000171301524447636500155460ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // charset.c - // // Written By: MURAOKA Taro #include "common.h" #define BUFLEN_DETECT 4096 #include #include #include "charset.h" int charset_none_int2char(unsigned int in, unsigned char *out) { if (out) *out = (unsigned char)in; return 1; } int charset_cp932_char2int(const unsigned char *in, unsigned int *out) { unsigned char c0 = in[0]; unsigned char c1 = c0 ? in[1] : 0; if (((c0 >= 0x81 && c0 <= 0x9f) || (c0 >= 0xe0 && c0 <= 0xf0)) && (c1 >= 0x40 && c1 <= 0xfc && c1 != 0x7f)) { if (out) *out = (unsigned int)c0 << 8 | (unsigned int)c1; return 2; } if (out) *out = c0; return 1; } int charset_cp932_int2char(unsigned int in, unsigned char *out) { if (in >= 0x100) { if (out) { out[0] = (unsigned char)((in >> 8) & 0xFF); out[1] = (unsigned char)(in & 0xFF); } return 2; } if (out) out[0] = (unsigned char)(in & 0xFF); return 1; } #define IS_EUC_RANGE(c) (0xa1 <= (c) && (c) <= 0xfe) int charset_eucjp_char2int(const unsigned char *in, unsigned int *out) { unsigned char c0 = in[0]; unsigned char c1 = c0 ? in[1] : 0; if ((c0 == 0x8e && c1 >= 0xa0 && c1 <= 0xdf) || (IS_EUC_RANGE(c0) && IS_EUC_RANGE(c1))) { if (out) *out = (unsigned int)c0 << 8 | (unsigned int)c1; return 2; } if (out) *out = c0; return 1; } int charset_eucjp_int2char(unsigned int in, unsigned char *out) { // Same as CP932, but separated to support JISX0213 in the future if (in >= 0x100) { if (out) { out[0] = (unsigned char)((in >> 8) & 0xFF); out[1] = (unsigned char)(in & 0xFF); } return 2; } if (out) out[0] = (unsigned char)(in & 0xFF); return 1; } // Use LUT to determine number of continuation bytes in UTF-8. // clang-format off const unsigned char CHARSET_UTF8_LUT[128] = { // 0x80 - 0xBF: invalid sequence (continuation byte without leader) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xC0 - 0xC1: invalid (overlong encoding) 0, 0, // 0xC2 - 0xDF (110xxxxx): 2 bytes character 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xE0 - 0xEF (1110xxxx): 3 bytes character 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xF0 - 0xF7 (11110xxx): 4 bytes character 4, 4, 4, 4, 4, // 0xF5 - 0xF7: invalid (exceeding Unicode max value of U+10FFFF) 0, 0, 0, // 0xF8 - 0xFF (11111xxx or greater): invalid values. 0, 0, 0, 0, 0, 0, 0, 0, }; // clang-format on int charset_utf8_char2int(const unsigned char *in, unsigned int *out) { return charset_utf8_char2int_inner(in, out); } int charset_utf8_int2char(unsigned int in, unsigned char *out) { if (in < 0x80) { if (out) out[0] = (unsigned char)(in & 0xFF); return 1; } if (in < 0x800) { if (out) { out[0] = 0xc0 + (in >> 6); out[1] = 0x80 + ((in >> 0) & 0x3f); } return 2; } if (in < 0x10000) { if (out) { out[0] = 0xe0 + (in >> 12); out[1] = 0x80 + ((in >> 6) & 0x3f); out[2] = 0x80 + ((in >> 0) & 0x3f); } return 3; } if (in < 0x200000) { if (out) { out[0] = 0xf0 + (in >> 18); out[1] = 0x80 + ((in >> 12) & 0x3f); out[2] = 0x80 + ((in >> 6) & 0x3f); out[3] = 0x80 + ((in >> 0) & 0x3f); } return 4; } // RFC 3629 specifies that a single UTF-8 character consists of up to 4 // bytes, so we adhere to that. return 0; } static int charset_detect_buf(const unsigned char *buf, int len) { int sjis = 0, smode = 0; int euc = 0, emode = 0, eflag = 0; int utf8 = 0, umode = 0, ufailed = 0; int i; for (i = 0; i < len; ++i) { unsigned char c = buf[i]; // Check if it is SJIS if (smode) { if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)) ++sjis; smode = 0; } else if ((0x81 <= c && c <= 0x9f) || (0xe0 <= c && c <= 0xf0)) smode = 1; // Check if it is EUC eflag = 0xa1 <= c && c <= 0xfe; if (emode) { if (eflag) ++euc; emode = 0; } else if (eflag) emode = 1; // Check if it is UTF8 if (!ufailed) { if (umode < 1) { if ((c & 0x80) != 0) { if ((c & 0xe0) == 0xc0) umode = 1; else if ((c & 0xf0) == 0xe0) umode = 2; else if ((c & 0xf8) == 0xf0) umode = 3; else if ((c & 0xfc) == 0xf8) umode = 4; else if ((c & 0xfe) == 0xfc) umode = 5; else { ufailed = 1; --utf8; } } } else { if ((c & 0xc0) == 0x80) { ++utf8; --umode; } else { --utf8; umode = 0; ufailed = 1; } } if (utf8 < 0) utf8 = 0; } } // Finally, return the encoding with the highest score if (euc > sjis && euc > utf8) return CHARSET_EUCJP; else if (!ufailed && utf8 > euc && utf8 > sjis) return CHARSET_UTF8; else if (sjis > euc && sjis > utf8) return CHARSET_CP932; else return CHARSET_NONE; } // character returns a character set encoder/decoder. Even for invalid // character sets, it returns a primitive encoder and decoder that function on // a single-byte basis. void charset_getproc(int charset, CHARSET_PROC_CHAR2INT *char2int, CHARSET_PROC_INT2CHAR *int2char) { CHARSET_PROC_CHAR2INT c2i = NULL; CHARSET_PROC_INT2CHAR i2c = NULL; switch (charset) { case CHARSET_CP932: c2i = charset_cp932_char2int; i2c = charset_cp932_int2char; break; case CHARSET_EUCJP: c2i = charset_eucjp_char2int; i2c = charset_eucjp_int2char; break; case CHARSET_UTF8: c2i = charset_utf8_char2int; i2c = charset_utf8_int2char; break; default: c2i = charset_none_char2int; i2c = charset_none_int2char; break; } if (char2int) *char2int = c2i; if (int2char) *int2char = i2c; } int charset_detect_file(const char *path) { int charset = CHARSET_NONE; FILE *fp; if ((fp = fopen(path, "rt")) != NULL) { unsigned char buf[BUFLEN_DETECT]; size_t len = fread(buf, sizeof(buf[0]), sizeof(buf), fp); fclose(fp); if (len > 0 && len <= INT_MAX) charset = charset_detect_buf(buf, (int)len); } return charset; } cmigemo-1.8.0/src/charset.h000066400000000000000000000047661524447636500155660ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // charset.h - // // Written By: MURAOKA Taro #pragma once enum { CHARSET_NONE = 0, CHARSET_CP932 = 1, CHARSET_EUCJP = 2, CHARSET_UTF8 = 3, }; // The maximum number of bytes into which a single code point can be expanded. #define CHARSET_MAX_BYTES 6 typedef int (*charset_proc_char2int)(const unsigned char *, unsigned int *); typedef int (*charset_proc_int2char)(unsigned int, unsigned char *); #define CHARSET_PROC_CHAR2INT charset_proc_char2int #define CHARSET_PROC_INT2CHAR charset_proc_int2char extern const unsigned char CHARSET_UTF8_LUT[128]; #ifdef __cplusplus extern "C" { #endif int charset_none_int2char(unsigned int in, unsigned char *out); int charset_cp932_char2int(const unsigned char *in, unsigned int *out); int charset_cp932_int2char(unsigned int in, unsigned char *out); int charset_eucjp_char2int(const unsigned char *in, unsigned int *out); int charset_eucjp_int2char(unsigned int in, unsigned char *out); int charset_utf8_char2int(const unsigned char *in, unsigned int *out); int charset_utf8_int2char(unsigned int in, unsigned char *out); int charset_detect_file(const char *path); void charset_getproc(int charset, CHARSET_PROC_CHAR2INT *char2int, CHARSET_PROC_INT2CHAR *int2char); #ifdef __cplusplus } #endif static inline int charset_none_char2int(const unsigned char *in, unsigned int *out) { if (out) *out = *in; return 1; } static inline int charset_utf8_char2int_inner(const unsigned char *in, unsigned int *out) { if (!(in[0] & 0x80)) return charset_none_char2int(in, out); int len = CHARSET_UTF8_LUT[in[0] - 128]; if (!len) // Output an invalid byte as-is. return charset_none_char2int(in, out); unsigned int code = in[0] & (0xff >> len); for (int i = 1; i < len; ++i) { // check invalid byte. if ((in[i] & 0xc0) != 0x80) // Output an invalid byte as-is. return charset_none_char2int(in, out); code <<= 6; code += in[i] & 0x3f; } if (out) *out = code; return len; } static inline unsigned int charset_decode(CHARSET_PROC_CHAR2INT proc, const unsigned char **pptr) { unsigned int code = 0; *pptr += proc ? proc(*pptr, &code) : charset_utf8_char2int_inner(*pptr, &code); return code; } static inline CHARSET_PROC_CHAR2INT charset_regulate_char2int(CHARSET_PROC_CHAR2INT proc) { return proc && proc != charset_utf8_char2int ? proc : NULL; } cmigemo-1.8.0/src/common.h000066400000000000000000000006011524447636500154050ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // common.h - To inject shared code into all .c files, such as for debugging // purposes. #pragma once // Example for heap debugging on Windows. You can enable it by changing the '0' // below to '1'. #if 0 # if defined(_WIN32) && defined(_DEBUG) # define _CRTDBG_MAP_ALLOC # include # include # endif #endif cmigemo-1.8.0/src/filename.c000066400000000000000000000035551524447636500157030ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // filename.c - Operate filename. // // Written by: Muraoka Taro #include "common.h" #include #include static size_t my_strlen(const char *s) { size_t len = strlen(s); return len <= INT_MAX ? len : INT_MAX; } // Cut out directroy string from filepath. // // Copies the part of `path` preceding the final `\` or `/` into `dir`. `cap` // is the size of the buffer allocated for `dir`, including the terminating // null character. If the size is insufficient, no copy is performed. The // return value is the size required for the copy, including the null // character. // // Returns an empty string for the root path. size_t filename_directory(char *dir, size_t cap, const char *path) { const char *p = path + my_strlen(path); for (; p > path; p--) if (*p == '\\' || *p == '/') break; // Returns an empty string if the path is from the root or does not contain // a directory separator. if (p == path) { if (cap > 0 && dir) dir[0] = '\0'; return 1; } // Returns the string up to, but not including, the last directory // separator. size_t len = p - path; if (cap >= len + 1 && dir) { memcpy(dir, path, len); dir[len] = '\0'; } return len + 1; } size_t filename_join(char *out, size_t cap, const char *dir, const char *file) { size_t len_d = my_strlen(dir); // Strip trailing directory separators. while (len_d > 0 && (dir[len_d - 1] == '/' || dir[len_d - 1] == '\\')) len_d--; size_t len_f = my_strlen(file); size_t total = len_d + 1 + len_f + 1; if (cap >= total && out) { memcpy(out, dir, len_d); out[len_d] = '/'; memcpy(out + len_d + 1, file, len_f); out[len_d + 1 + len_f] = '\0'; } return total; } cmigemo-1.8.0/src/filename.h000066400000000000000000000005541524447636500157040ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // filename.h - Operate filename. // // Written by: Muraoka Taro #pragma once #ifdef __cplusplus extern "C" { #endif size_t filename_directory(char *dir, size_t cap, const char *path); size_t filename_join(char *out, size_t cap, const char *dir, const char *file); #ifdef __cplusplus } #endif cmigemo-1.8.0/src/index.md000066400000000000000000000064251524447636500154070ustar00rootroot00000000000000--- type: Directory Index title: "src Index" description: "C sources and headers for the migemo shared library core (dictionary tree, static tree, romaji, regexp, charset), with CMake build rules and Windows build support files." tags: [index] --- # Overview This directory holds the C implementation of the `migemo` shared library: the migemo tree (dictionary storage/query), the static (serializable) tree, romaji conversion, regular expression generation, character set/encoding handling, and supporting utilities (string buffer, word list, filename helpers), plus the CMake build script and Windows module-definition/resource files. # Directory Contents | File / Path | Type | Description | | :--- | :--- | :--- | | [migemo.c](./migemo.c) | Source | Core implementation of the public migemo API (open/close/query and dictionary loading). | | [migemo_struct.h](./migemo_struct.h) | Header | Defines the internal `struct migemo` aggregating the mtree, romaji tables, and rxgen state. | | [mtree.c](./mtree.c) | Source | Migemo tree (mtree) operations for loading the dictionary and querying words. | | [mtree.h](./mtree.h) | Header | Public declarations of the migemo tree (mtree) operations. | | [stree.c](./stree.c) | Source | Static (flat, serializable) version of the mtree with load/save and query support. | | [stree.h](./stree.h) | Header | Public declarations of the static mtree (stree) serialization and query API. | | [romaji.c](./romaji.c) | Source | Romaji conversion support for input handling. | | [romaji.h](./romaji.h) | Header | Public declarations of the romaji conversion module. | | [rxgen.c](./rxgen.c) | Source | Regular expression generator producing patterns for matching input against the dictionary. | | [rxgen.h](./rxgen.h) | Header | Public declarations of the regular expression generator. | | [charset.c](./charset.c) | Source | Character set and multi-byte encoding conversion helpers (CP932, EUC-JP, UTF-8). | | [charset.h](./charset.h) | Header | Public declarations of the character set conversion module. | | [strbuf.c](./strbuf.c) | Source | Dynamic string buffer implementation used throughout the library. | | [strbuf.h](./strbuf.h) | Header | Public declarations of the string buffer module. | | [trie.c](./trie.c) | Source | Trie statistics printing used for diagnosing the dictionary tree structure. | | [trie.h](./trie.h) | Header | Public declarations of the trie statistics helpers. | | [wordlist.c](./wordlist.c) | Source | Word list handling for dictionary expansion. | | [wordlist.h](./wordlist.h) | Header | Public declarations of the word list module. | | [filename.c](./filename.c) | Source | Filename manipulation helpers for locating dictionaries. | | [filename.h](./filename.h) | Header | Public declarations of the filename helper module. | | [common.h](./common.h) | Header | Shared code (e.g., debugging facilities) injected into all .c files. | | [migemo.def](./migemo.def) | Build Support | MSVC module definition file controlling exported library symbols. | | [migemo.rc.in](./migemo.rc.in) | Build Support | CMake template generating the Windows resource file for the library. | | [CMakeLists.txt](./CMakeLists.txt) | Build | CMake rules building the migemo library, generating the public header, and configuring Windows resources. | # References - [Parent Directory](../index.md) cmigemo-1.8.0/src/migemo.c000066400000000000000000000426441524447636500154020ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // migemo.c - // // Written By: MURAOKA Taro #include "common.h" #include #include #include #include #include #include #include "charset.h" #include "filename.h" #include "migemo.h" #include "migemo_struct.h" #include "mtree.h" #include "romaji.h" #include "rxgen.h" #include "strbuf.h" #include "wordlist.h" #define DICT_ROMA2HIRA "roma2hira.dat" #define DICT_HIRA2KATA "hira2kata.dat" #define DICT_HAN2ZEN "han2zen.dat" #define DICT_ZEN2HAN "zen2han.dat" #ifndef _MAX_PATH # define _MAX_PATH 1024 // Placeholder value #endif static int my_strlen(const char *s) { size_t len; len = strlen(s); return len <= INT_MAX ? (int)len : INT_MAX; } static mtree * load_mtree_dictionary(migemo *mo, const char *dict_file) { if (mo->charset == CHARSET_NONE) mo->charset = charset_detect_file(dict_file); CHARSET_PROC_CHAR2INT char2int = NULL; CHARSET_PROC_INT2CHAR int2char = NULL; charset_getproc(mo->charset, &char2int, &int2char); migemo_setproc_char2int(mo, (MIGEMO_PROC_CHAR2INT)char2int); migemo_setproc_int2char(mo, (MIGEMO_PROC_INT2CHAR)int2char); FILE *fp = fopen(dict_file, "rt"); if (!fp) return NULL; mtree *mt = mtree_load(mo->mtree, fp, char2int); fclose(fp); return mt; } /// Add a dictionary or data file to the Migemo object. /// /// Supported dictionary types (`dict_id`): /// // clang-format off /// - `MIGEMO_DICTID_MIGEMO`: Main dictionary file (`migemo-dict`). /// - `MIGEMO_DICTID_ROMA2HIRA`: Romaji to Hiragana conversion table (`roma2hira.dat`). /// - `MIGEMO_DICTID_HIRA2KATA`: Hiragana to Katakana conversion table (`hira2kata.dat`). /// - `MIGEMO_DICTID_HAN2ZEN`: Half-width to Full-width conversion table (`han2zen.dat`). /// - `MIGEMO_DICTID_ZEN2HAN`: Full-width to Half-width conversion table (`zen2han.dat`). // clang-format on /// /// @param mo Migemo object. /// @param dict_id Identifier specifying the type of dictionary/data. /// @param dict_file Path to the dictionary or data file to load. /// @return dict_id on success, 0 on failure. int MIGEMO_CALLTYPE migemo_load(migemo *mo, int dict_id, const char *dict_file) { if (!mo && dict_file) return 0; // Load migemo dictionary if (dict_id == MIGEMO_DICTID_MIGEMO) { if (!mo->mtree) return 0; // ERROR: switched to sdict and released. mtree *mt = load_mtree_dictionary(mo, dict_file); if (!mt) return 0; mo->mtree = mt; mo->enable = 1; return dict_id; // Loaded successfully } // Load static dictionary (sdict) if (dict_id == MIGEMO_DICTID_MIGEMO_SDICT) { stree *st = stree_load(dict_file); if (!st) return 0; mo->stree = st; mo->enable = 1; // Setup charset. mo->charset = st->head.charset; CHARSET_PROC_CHAR2INT char2int = NULL; CHARSET_PROC_INT2CHAR int2char = NULL; charset_getproc(mo->charset, &char2int, &int2char); migemo_setproc_char2int(mo, (MIGEMO_PROC_CHAR2INT)char2int); migemo_setproc_int2char(mo, (MIGEMO_PROC_INT2CHAR)int2char); return dict_id; } romaji *dict; switch (dict_id) { case MIGEMO_DICTID_ROMA2HIRA: // Load romaji dictionary dict = mo->roma2hira; break; case MIGEMO_DICTID_HIRA2KATA: // Load katakana dictionary dict = mo->hira2kata; break; case MIGEMO_DICTID_HAN2ZEN: // Load half-width to full-width dictionary dict = mo->han2zen; break; case MIGEMO_DICTID_ZEN2HAN: // Load half-width to full-width dictionary dict = mo->zen2han; break; default: return 0; } return romaji_load(dict, dict_file, mo->char2int) == 0 ? dict_id : 0; } static migemo * migemo_open2(const char *dict, int dict_id) { migemo *mo = (migemo *)calloc(1, sizeof(migemo)); if (!mo) return NULL; // Construct the Migemo object and its members mo->enable = 0; mo->mtree = mtree_open(); mo->charset = CHARSET_NONE; mo->rx = rxgen_open(); mo->roma2hira = romaji_open(); mo->hira2kata = romaji_open(); mo->han2zen = romaji_open(); mo->zen2han = romaji_open(); mo->char2int = NULL; if (!mo->mtree || !mo->rx || !mo->roma2hira || !mo->hira2kata || !mo->han2zen || !mo->zen2han) { migemo_close(mo); return NULL; } // If a default migemo dictionary is specified, also look for romaji and // katakana dictionaries if (dict) { char dir[_MAX_PATH]; char roma_dict[_MAX_PATH]; char kata_dict[_MAX_PATH]; char h2z_dict[_MAX_PATH]; char z2h_dict[_MAX_PATH]; filename_directory(dir, _MAX_PATH, dict); const char *tmp = strlen(dir) ? dir : "."; filename_join(roma_dict, _MAX_PATH, tmp, DICT_ROMA2HIRA); filename_join(kata_dict, _MAX_PATH, tmp, DICT_HIRA2KATA); filename_join(h2z_dict, _MAX_PATH, tmp, DICT_HAN2ZEN); filename_join(z2h_dict, _MAX_PATH, tmp, DICT_ZEN2HAN); if (migemo_load(mo, dict_id, dict) != 0) { romaji_load(mo->roma2hira, roma_dict, mo->char2int); romaji_load(mo->hira2kata, kata_dict, mo->char2int); romaji_load(mo->han2zen, h2z_dict, mo->char2int); romaji_load(mo->zen2han, z2h_dict, mo->char2int); } } return mo; } migemo *MIGEMO_CALLTYPE migemo_open(const char *dict) { return migemo_open2(dict, MIGEMO_DICTID_MIGEMO); } void MIGEMO_CALLTYPE migemo_close(migemo *mo) { if (mo) { if (mo->zen2han) romaji_close(mo->zen2han); if (mo->han2zen) romaji_close(mo->han2zen); if (mo->hira2kata) romaji_close(mo->hira2kata); if (mo->roma2hira) romaji_close(mo->roma2hira); if (mo->rx) rxgen_close(mo->rx); stree_destroy(mo->stree); if (mo->mtree) mtree_close(mo->mtree); free(mo); } } static int migemo_add_word(migemo *mo, const unsigned char *word) { return rxgen_add(mo->rx, word); } static inline void migemo_add_wordlist(migemo *mo, wordlist *list) { for (; list; list = wordlist_next(list)) migemo_add_word(mo, wordlist_word(list)); } static void migemo_add_mnode_siblings(migemo *mo, mnode *node) { migemo_add_wordlist(mo, node->list); if (node->child) migemo_add_mnode_siblings(mo, node->child); if (node->low) migemo_add_mnode_siblings(mo, node->low); if (node->high) migemo_add_mnode_siblings(mo, node->high); } static void migemo_add_mtree_matches(migemo *mo, unsigned char *query) { mnode *node = mtree_query(mo->mtree, query); if (node) { migemo_add_wordlist(mo, node->list); if (node->child) migemo_add_mnode_siblings(mo, node->child); } } static void migemo_add_stree_words(migemo *mo, snode *node) { if (node->word_idx == STREE_INVALID_WORD_IDX) return; const unsigned char *p = mo->stree->word_buf + node->word_idx; while (*p) { migemo_add_word(mo, p); p += strlen(p) + 1; } } static void migemo_add_stree_children(migemo *mo, uint32_t start, uint32_t end) { for (uint32_t i = start; i < end; i++) { snode *node = mo->stree->nodes + i; migemo_add_stree_words(mo, node); uint32_t child_start = node->start; uint32_t child_end = node->end; if (child_start < child_end) migemo_add_stree_children(mo, child_start, child_end); } } static void migemo_add_stree_matches(migemo *mo, unsigned char *query) { snode *node = stree_query(mo->stree, query); if (!node) return; migemo_add_stree_words(mo, node); // Add words from children and decendant. uint32_t start = node->start; uint32_t end = node->end; if (start < end) migemo_add_stree_children(mo, start, end); } static void migemo_add_matches(migemo *mo, unsigned char *query) { if (mo->stree) migemo_add_stree_matches(mo, query); else migemo_add_mtree_matches(mo, query); } /// Convert input from Romaji to Kana and add it to the search keys. static void migemo_add_roma_variants(migemo *mo, unsigned char *query) { wordlist *hira_list = romaji_convert_all(mo->roma2hira, query); for (wordlist *hira_item = hira_list; hira_item; hira_item = wordlist_next(hira_item)) { unsigned char *hira = wordlist_word(hira_item); migemo_add_word(mo, hira); migemo_add_matches(mo, hira); wordlist *kata_list = romaji_convert_all(mo->hira2kata, hira); for (wordlist *kata_item = kata_list; kata_item; kata_item = wordlist_next(kata_item)) { unsigned char *kata = wordlist_word(kata_item); migemo_add_word(mo, kata); migemo_add_matches(mo, kata); wordlist *han_list = romaji_convert_all(mo->zen2han, kata); for (wordlist *han_item = han_list; han_item; han_item = wordlist_next(han_item)) { unsigned char *han = wordlist_word(han_item); migemo_add_word(mo, han); } wordlist_destroy(han_list); } wordlist_destroy(kata_list); } wordlist_destroy(hira_list); } /// Split the query into phrases. /// /// Phrases are typically separated by uppercase letters. A phrase starting /// with multiple uppercase letters is separated by non-uppercase characters. static wordlist * migemo_segment_query(migemo *mo, const unsigned char *query) { wordlist *queries = NULL, **pnext = &queries; const unsigned char *r = query; for (bool loop = true; loop;) { const unsigned char *start = r; // Determine how to identify query boundaries. bool upper_mode = false; int first = charset_decode(mo->char2int, &r); if (first < 0x80 && isupper(first)) { // Look ahead to the second character. const unsigned char *r2 = r; int second = charset_decode(mo->char2int, &r2); upper_mode = second < 0x80 && isupper(second); } // Locate the boundary where the case switches. In "upper mode," the // first lowercase letter marks the boundary; in "lower mode," the // first uppercase letter marks the boundary. const unsigned char *prev = NULL; while (1) { prev = r; int code = charset_decode(mo->char2int, &r); if (code == 0) { loop = false; break; } if (code < 0x80 && (isupper(code) != 0) != upper_mode) break; } // Register a phrase if (prev) { *pnext = wordlist_new(start, prev - start); pnext = &(*pnext)->next; r = prev; } } return queries; } // Convert a single word using migemo. Does not perform argument checking. static void migemo_process_word(migemo *mo, unsigned char *query) { int len = my_strlen(query); unsigned char *lower = malloc(len + 1); if (!lower) return; // Error: memory allocation // Naturally, add the query itself to the candidates migemo_add_word(mo, query); // Convert the query string to lowercase. const unsigned char *r = query; unsigned char *w = lower; while (1) { const unsigned char *prev = r; int code = charset_decode(mo->char2int, &r); ptrdiff_t step = r - prev; if (step == 1 && code < 0x80 && isupper(code)) *w = (unsigned char)tolower(code); else memcpy(w, prev, step); if (code == 0) break; w += step; } // Dictionary search using a lowercase query. migemo_add_matches(mo, lower); // Convert query to full-width and add to candidates wordlist *zen_list = romaji_convert_all(mo->han2zen, query); for (wordlist *zen = zen_list; zen; zen = wordlist_next(zen)) migemo_add_word(mo, wordlist_word(zen)); wordlist_destroy(zen_list); // Convert query to half-width and add to candidates wordlist *han_list = romaji_convert_all(mo->zen2han, query); for (wordlist *han = han_list; han; han = wordlist_next(han)) migemo_add_word(mo, wordlist_word(han)); wordlist_destroy(han_list); // Add Hiragana, Katakana, and dictionary lookups using them migemo_add_roma_variants(mo, lower); free(lower); } unsigned char *MIGEMO_CALLTYPE migemo_query(migemo *mo, const unsigned char *query) { if (!mo || !mo->rx || !query) return NULL; wordlist *queries = migemo_segment_query(mo, query); if (queries == NULL) { // Error: no queries return NULL; } strbuf *patbuf = strbuf_open(); if (patbuf == NULL) { // Error: insufficient memory for output wordlist_destroy(queries); return NULL; } rxgen_reset(mo->rx); for (wordlist *wl = queries; wl; wl = wordlist_next(wl)) { migemo_process_word(mo, wordlist_word(wl)); unsigned char *subpat = rxgen_generate(mo->rx); rxgen_reset(mo->rx); strbuf_append_str(patbuf, subpat); rxgen_release(mo->rx, subpat); } unsigned char *pattern = strbuf_get(patbuf); // Explicitly set to NULL to decouple it from `strbuf` management. patbuf->buf = NULL; strbuf_close(patbuf); wordlist_destroy(queries); return pattern; } void MIGEMO_CALLTYPE migemo_release(migemo *mo, unsigned char *used_pattern) { free(used_pattern); } /// Set regular expression metacharacters (operators) for the Migemo object. /// /// Supported metacharacter identifiers (`index`): /// // clang-format off /// - `MIGEMO_OPINDEX_OR`: OR operator (default: "|"). /// - `MIGEMO_OPINDEX_NEST_IN`: Group opening bracket (default: "("). /// - `MIGEMO_OPINDEX_NEST_OUT`: Group closing bracket (default: ")"). /// - `MIGEMO_OPINDEX_SELECT_IN`: Character class opening bracket (default: "["). /// - `MIGEMO_OPINDEX_SELECT_OUT`: Character class closing bracket (default: "]"). /// - `MIGEMO_OPINDEX_NEWLINE`: Pattern inserted between characters for matching across lines (default: ""). // clang-format on /// /// @param mo Migemo object. /// @param index Metacharacter identifier (`MIGEMO_OPINDEX_*`). /// @param op Metacharacter string to set. /// @return 1 on success, 0 on failure. int MIGEMO_CALLTYPE migemo_set_operator(migemo *mo, int index, const unsigned char *op) { if (!mo) return 0; return rxgen_set_operator(mo->rx, index, op) == 0 ? 1 : 0; } /// Retrieve the metacharacter (operator) string for the specified index. /// /// For details about supported `index` values, see migemo_set_operator(). /// /// @param mo Migemo object. /// @param index Metacharacter identifier (`MIGEMO_OPINDEX_*`). /// @return Pointer to the metacharacter string on success, or NULL if `mo` /// is NULL or `index` is invalid. const unsigned char *MIGEMO_CALLTYPE migemo_get_operator(migemo *mo, int index) { if (!mo) return NULL; return rxgen_get_operator(mo->rx, index); } /// Set custom characters to escape in generated regular expressions. /// /// @param mo Migemo object. /// @param chars String of characters to escape (ASCII 32-126). If NULL, default /// set ("\\.*+^$/") is used. If "", no characters are escaped. void MIGEMO_CALLTYPE migemo_set_escape_chars(migemo *mo, const unsigned char *chars) { if (!mo) return; rxgen_set_escape_chars(mo->rx, chars); } /// Set a custom character conversion procedure (char -> int) for the Migemo /// object. /// /// @param mo Migemo object. /// @param proc Character conversion procedure. void MIGEMO_CALLTYPE migemo_setproc_char2int(migemo *mo, MIGEMO_PROC_CHAR2INT proc) { if (!mo) return; mo->char2int = charset_regulate_char2int(proc); rxgen_setproc_char2int(mo->rx, (CHARSET_PROC_CHAR2INT)proc); } /// Set a custom character conversion procedure (int -> char) for the Migemo /// object. /// /// @param mo Migemo object. /// @param proc Character conversion procedure. void MIGEMO_CALLTYPE migemo_setproc_int2char(migemo *mo, MIGEMO_PROC_INT2CHAR proc) { if (!mo) return; rxgen_setproc_int2char(mo->rx, (CHARSET_PROC_INT2CHAR)proc); } /// Check whether the main dictionary is loaded and ready for queries. /// /// @param mo Migemo object. /// @return Non-zero if enabled, 0 otherwise. int MIGEMO_CALLTYPE migemo_is_enable(migemo *mo) { if (!mo) return 0; return mo->enable; } /// Retrieve the version string of the C/Migemo library. /// /// @return Static version string (e.g., "1.6.1"). const char *MIGEMO_CALLTYPE migemo_version(void) { return MIGEMO_VERSION MIGEMO_VERSION_PRERELEASE; } int MIGEMO_CALLTYPE migemo_switch_sdict(migemo *mo, int flags) { if (!mo->mtree) return 0; if (mo->stree) stree_destroy(mo->stree); mo->stree = stree_from_mtree(mo->mtree); if (!mo->stree) return 0; if (flags & MIGEMO_SDICT_RELEASE_MDICT) { mtree_close(mo->mtree); mo->mtree = NULL; } return 1; } int MIGEMO_CALLTYPE migemo_save_sdict(migemo *mo, const char *dict_file) { if (!mo->stree) return 0; return stree_save(mo->stree, dict_file) == 0 ? 1 : 0; } migemo *MIGEMO_CALLTYPE migemo_open_sdict(const char *dict_file) { return migemo_open2(dict_file, MIGEMO_DICTID_MIGEMO_SDICT); } cmigemo-1.8.0/src/migemo.def000066400000000000000000000006041524447636500157040ustar00rootroot00000000000000; Written By: Muraoka Taro ;LIBRARY MIGEMO ;DESCRIPTION "Migemo DLL" EXPORTS migemo_open migemo_close migemo_query migemo_release migemo_switch_sdict migemo_save_sdict migemo_open_sdict migemo_set_operator migemo_get_operator migemo_set_escape_chars migemo_setproc_char2int migemo_setproc_int2char migemo_load migemo_is_enable migemo_version cmigemo-1.8.0/src/migemo.rc.in000066400000000000000000000022661524447636500161650ustar00rootroot00000000000000#include LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL VS_VERSION_INFO VERSIONINFO FILEVERSION @PROJECT_VERSION_MAJOR@,@PROJECT_VERSION_MINOR@,@PROJECT_VERSION_PATCH@,0 PRODUCTVERSION @PROJECT_VERSION_MAJOR@,@PROJECT_VERSION_MINOR@,@PROJECT_VERSION_PATCH@,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x40004L FILETYPE 0x2L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" // US English, Unicode BEGIN VALUE "Comments", "C/Migemo library for Japanese incremental search\0" VALUE "CompanyName", "KaoriYa\0" VALUE "FileDescription", "C/Migemo DLL\0" VALUE "FileVersion", "@PROJECT_VERSION@\0" VALUE "InternalName", "CMigemo\0" VALUE "LegalCopyright", "Copyright (C) MURAOKA Taro (KoRoN)/KaoriYa\0" VALUE "LegalTrademarks", "C/Migemo\0" VALUE "OriginalFilename", "migemo.dll\0" VALUE "ProductName", "C/Migemo\0" VALUE "ProductVersion", "@PROJECT_VERSION@\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x0409, 1200 // US English, Unicode END END cmigemo-1.8.0/src/migemo_struct.h000066400000000000000000000006451524447636500170060ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // migemo_struct.h - #pragma once #include "charset.h" #include "mtree.h" #include "romaji.h" #include "rxgen.h" #include "stree.h" // Migemo object struct migemo { int enable; mtree *mtree; stree *stree; int charset; romaji *roma2hira; romaji *hira2kata; romaji *han2zen; romaji *zen2han; rxgen *rx; CHARSET_PROC_CHAR2INT char2int; }; cmigemo-1.8.0/src/mtree.c000066400000000000000000000240051524447636500152300ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // mtree.c - Migemo tree (mtree) operations // // Written By: MURAOKA Taro #include "common.h" #include #include #include #include #include "mtree.h" #include "strbuf.h" #include "trie.h" #define MNODE_BUFSIZE 16384 static void mnode_debug_stat_stub( mnode *node, trie_stat *stat, int sib_depth, int total_cmp) { if (!node) return; stat->total_nodes++; stat->total_sibling_depth += sib_depth; if (sib_depth > stat->max_sibling_depth) stat->max_sibling_depth = sib_depth; if (node->low) stat->low_count++; if (node->high) stat->high_count++; if (node->child) stat->child_count++; if (node->list) { stat->wordtail_count++; stat->total_node_cmp_count += total_cmp; if (total_cmp > stat->max_node_cmp_count) stat->max_node_cmp_count = total_cmp; } // recursive calls for low, high, and child nodes. if (node->low) mnode_debug_stat_stub(node->low, stat, sib_depth + 1, total_cmp + 1); if (node->high) mnode_debug_stat_stub(node->high, stat, sib_depth + 1, total_cmp + 1); if (node->child) mnode_debug_stat_stub(node->child, stat, 0, total_cmp + 1); } static void mnode_debug_stat(mnode *root, trie_stat *stat) { if (!stat) return; memset(stat, 0, sizeof(*stat)); if (!root) return; mnode_debug_stat_stub(root, stat, 0, 1); } void mtree_print_stat(mtree *mt, const char *label) { if (!mt || !mt->rootnode) { printf("== INVALID mnode ===\n"); return; } trie_stat stat; mnode_debug_stat(mt->rootnode, &stat); trie_stat_print(&stat, label); } static mnode * mnode_arena_alloc(mnode_arena *arena, unsigned int code) { if (!arena->curr || arena->curr->used >= MNODE_BLOCK_SIZE) { mnode_block *block = (mnode_block *)calloc(1, sizeof(mnode_block)); if (!block) return NULL; if (!arena->head) arena->head = block; else arena->curr->next = block; arena->curr = block; } mnode *p = &arena->curr->nodes[arena->curr->used++]; p->code = code; return p; } static void mnode_arena_free(mnode_arena *arena) { for (mnode_block *b = arena->head; b;) { mnode_block *next = b->next; for (size_t i = 0; i < b->used; i++) if (b->nodes[i].list) wordlist_destroy(b->nodes[i].list); free(b); b = next; } arena->head = NULL; arena->curr = NULL; } void mtree_close(mtree *mt) { if (mt) { mnode_arena_free(&mt->arena); free(mt); } } static inline mnode * mtree_ensure_node(mtree *mt, const unsigned char *key) { if (!key) return NULL; unsigned int code = charset_decode(mt->char2int, &key); if (code == 0) return NULL; mnode **res = NULL; mnode **ppnext = &mt->rootnode; while (1) { res = ppnext; if (!*res) { *res = mnode_arena_alloc(&mt->arena, code); if (!(*res)) return NULL; } else { unsigned int pivot = (*res)->code; if (code < pivot) { ppnext = &(*res)->low; continue; } else if (code > pivot) { ppnext = &(*res)->high; continue; } } ppnext = &(*res)->child; (*res)->weight++; code = charset_decode(mt->char2int, &key); if (code == 0) break; } return *res; } size_t mnode_count_siblings(mnode *node) { if (!node) return 0; return mnode_count_siblings(node->low) + 1 + mnode_count_siblings(node->high); } mnode ** mnode_collect_siblings(mnode *node, mnode **buf) { if (!node) return buf; buf = mnode_collect_siblings(node->low, buf); *buf++ = node; return mnode_collect_siblings(node->high, buf); } static mnode * mnode_balanced_tree(mnode **nodes, size_t start, size_t end) { if (start >= end) return NULL; int left = (int)start - 1, right = (int)end; unsigned int lsum = 0, rsum = 0; while (left < right) if (lsum < rsum || (lsum == rsum && (left - start + 1) <= (end - 1 - right))) lsum += nodes[++left]->weight; else rsum += nodes[--right]->weight; size_t mid = left; mnode *root = nodes[mid]; root->low = mnode_balanced_tree(nodes, start, mid); root->high = mnode_balanced_tree(nodes, mid + 1, end); return root; } static mnode * mnode_balance(mnode *root) { if (!root) return NULL; size_t count = mnode_count_siblings(root); mnode **nodes = calloc(count, sizeof(mnode *)); mnode_collect_siblings(root, nodes); root = mnode_balanced_tree(nodes, 0, count); for (size_t i = 0; i < count; i++) nodes[i]->child = mnode_balance(nodes[i]->child); free(nodes); return root; } static inline int mtree_scan_to_next_break( unsigned char **start, unsigned char **end, unsigned char **in) { for (unsigned char *p = *in; *p; p++) { if (*p < 0x80 && isspace(*p)) continue; *start = p; for (; *p; p++) { if (*p == '\t') { *p = '\0'; *end = p; *in = p + 1; return 0; } } *end = p; *in = p; return 2; // EOL } return 1; // SKIP: empty line. } typedef struct { FILE *fp; size_t avail; size_t head; int err; bool eof; bool read_request; unsigned char buf[MNODE_BUFSIZE]; } mtree_file; static inline unsigned char * mtree_readline(mtree_file *mf, size_t *line_len) { while (1) { if (mf->read_request) { size_t len = fread(mf->buf + mf->avail, 1, sizeof(mf->buf) - mf->avail - 1, mf->fp); mf->err = ferror(mf->fp); mf->eof = feof(mf->fp); if (len == 0 || mf->err != 0) return NULL; mf->head = 0; mf->avail += len; mf->read_request = false; } unsigned char *start = mf->buf + mf->head; unsigned char *tail = memchr(start, '\n', mf->avail - mf->head); if (tail) { size_t len = tail - start + 1; mf->head += len; *line_len = len; return start; } if (mf->eof) { // Reached EOF. size_t len = mf->avail - mf->head; mf->head = mf->avail; *line_len = len; mf->buf[mf->avail] = '\0'; return len != 0 ? start : NULL; } // Shift remaining data to the front to read more. size_t len = mf->avail - mf->head; memmove(mf->buf, mf->buf + mf->head, len); mf->avail = len; mf->head = 0; mf->read_request = true; } return NULL; } // Batch add data from a file to existing nodes. mtree * mtree_load(mtree *mt, FILE *fp, CHARSET_PROC_CHAR2INT char2int) { mt->char2int = charset_regulate_char2int(char2int); mtree_file mf = {.fp = fp, .read_request = true}; while (1) { // Read a line from the file. size_t len = 0; unsigned char *p = mtree_readline(&mf, &len); if (!p) { if (mf.eof) break; // ERROR: File read error. return NULL; } if (len > 0 && p[len - 1] != '\n' && !mf.eof) { // ERROR: Line is too long. return NULL; } // Trim last LF ('\n'). if (len > 0 && p[len - 1] == '\n') p[len - 1] = '\0'; // Skip the comment line if (*p == ';') continue; unsigned char *key = NULL, *kend = NULL; switch (mtree_scan_to_next_break(&key, &kend, &p)) { case 0: // found a key, forward to the values. break; case 1: // skip empty line, forward to the next line. continue; case 2: // error return NULL; } wordlist *values = NULL, **tail = &values; while (1) { unsigned char *value = NULL, *vend = NULL; int ret = mtree_scan_to_next_break(&value, &vend, &p); if (value) { *tail = wordlist_new(value, vend - value); tail = &(*tail)->next; } // Cases where the loop is exited // ret == 1: couldn't found any values. // ret == 2: EOL, found values. if (ret != 0) break; } if (!values) continue; // Register a key with values. mnode *node = mtree_ensure_node(mt, key); if (!node) { wordlist_destroy(values); return NULL; } *tail = node->list; node->list = values; } mt->rootnode = mnode_balance(mt->rootnode); return mt; } mtree * mtree_open(void) { mtree *mt = (mtree *)calloc(1, sizeof(*mt)); // Set the default to UTF-8. mt->char2int = NULL; return mt; } mnode * mtree_query(mtree *mt, const unsigned char *query) { if (!mt || !mt->rootnode || !query) return NULL; unsigned int code = charset_decode(mt->char2int, &query); if (code == 0) return NULL; mnode *node = mt->rootnode; while (node) { // Search from siblings while (node != NULL && code != node->code) node = code < node->code ? node->low : node->high; if (!node) break; // Not found the rune. // Proceed to the child node code = charset_decode(mt->char2int, &query); if (code == 0) break; // Found the node. node = node->child; } return node; } mnode * mtree_rootnode(mtree *mt) { return mt->rootnode; } cmigemo-1.8.0/src/mtree.h000066400000000000000000000026521524447636500152410ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // mtree.h - Migemo tree (mtree) operations // // Written By: MURAOKA Taro // Need to include #pragma once #include #include "charset.h" #include "wordlist.h" #define MNODE_BLOCK_BYTES (64 * 1024) #define MNODE_BLOCK_HEADER_SIZE (sizeof(void *) + sizeof(size_t)) #define MNODE_BLOCK_SIZE \ ((MNODE_BLOCK_BYTES - MNODE_BLOCK_HEADER_SIZE) / sizeof(mnode)) typedef struct mnode mnode; struct mnode { mnode *low, *high; mnode *child; unsigned int code; unsigned int weight; wordlist *list; }; typedef struct mnode_block mnode_block; struct mnode_block { mnode_block *next; size_t used; mnode nodes[MNODE_BLOCK_SIZE]; }; typedef struct mnode_arena { mnode_block *head; mnode_block *curr; } mnode_arena; typedef struct mtree { mnode *rootnode; mnode_arena arena; CHARSET_PROC_CHAR2INT char2int; } mtree; #ifdef __cplusplus extern "C" { #endif // Life cycle management mtree *mtree_open(void); void mtree_close(mtree *mt); // Load dictionary & query mtree *mtree_load(mtree *mt, FILE *fp, CHARSET_PROC_CHAR2INT char2int); mnode *mtree_query(mtree *mt, const unsigned char *query); // Other operations mnode *mtree_rootnode(mtree *mt); // Debug & maintenance void mtree_print_stat(mtree *mt, const char *title); #ifdef __cplusplus } #endif cmigemo-1.8.0/src/romaji.c000066400000000000000000000403771524447636500154070ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // romaji.c - Romaji conversion // // Written By: MURAOKA Taro #include "common.h" #include #include #include #include #include "romaji.h" #include "strbuf.h" #include "trie.h" #if defined(_MSC_VER) # define STRDUP _strdup #else # define STRDUP strdup #endif #define ROMAJI_READ_BUFSIZE 1024 #define ROMAJI_PUSHBACK_BUFSIZE 256 #define ROMAJI_BLOCK_BYTES (16 * 1024) #define ROMAJI_BLOCK_HEADER_SIZE (sizeof(void *) + sizeof(size_t)) #define ROMAJI_BLOCK_SIZE \ ((ROMAJI_BLOCK_BYTES - ROMAJI_BLOCK_HEADER_SIZE) / sizeof(romanode)) typedef struct romanode romanode; struct romanode { romanode *low, *high; romanode *child; unsigned int code; unsigned char *value; unsigned char *remain; }; typedef struct romanode_block romanode_block; struct romanode_block { romanode_block *next; size_t used; romanode nodes[ROMAJI_BLOCK_SIZE]; }; typedef struct romanode_arena romanode_arena; struct romanode_arena { romanode_block *head; romanode_block *curr; }; struct romaji { romanode *rootnode; romanode_arena arena; CHARSET_PROC_CHAR2INT char2int; }; static romanode * romanode_arena_alloc(romanode_arena *arena, unsigned int code) { if (!arena->curr || arena->curr->used >= ROMAJI_BLOCK_SIZE) { romanode_block *block = (romanode_block *)calloc(1, sizeof(romanode_block)); if (!block) return NULL; if (!arena->head) arena->head = block; else arena->curr->next = block; arena->curr = block; } romanode *p = &arena->curr->nodes[arena->curr->used++]; p->code = code; return p; } static void romanode_arena_free(romanode_arena *arena) { for (romanode_block *p = arena->head; p;) { romanode_block *next = p->next; for (int i = 0; i < p->used; i++) { free(p->nodes[i].value); free(p->nodes[i].remain); } free(p); p = next; } arena->head = NULL; arena->curr = NULL; } static romanode * romanode_dig(romanode_arena *arena, romanode **pp, unsigned int code) { romanode *p = *pp; if (p == NULL) { *pp = romanode_arena_alloc(arena, code); return *pp; } while (1) { if (code == p->code) return p; if (code < p->code) { if (p->low == NULL) { p->low = romanode_arena_alloc(arena, code); return p->low; } p = p->low; } else { if (p->high == NULL) { p->high = romanode_arena_alloc(arena, code); return p->high; } p = p->high; } } } size_t romanode_count_siblings(romanode *node) { if (!node) return 0; return romanode_count_siblings(node->low) + 1 + romanode_count_siblings(node->high); } romanode ** romanode_collect_siblings(romanode *node, romanode **buf) { if (!node) return buf; buf = romanode_collect_siblings(node->low, buf); *buf++ = node; return romanode_collect_siblings(node->high, buf); } static romanode * romanode_balanced_tree(romanode **nodes, size_t start, size_t end) { if (start >= end) return NULL; size_t mid = (start + end) / 2; romanode *root = nodes[mid]; root->low = romanode_balanced_tree(nodes, start, mid); root->high = romanode_balanced_tree(nodes, mid + 1, end); return root; } static romanode * romanode_balance(romanode *root) { if (!root) return NULL; size_t count = romanode_count_siblings(root); romanode **nodes = calloc(count, sizeof(romanode *)); romanode_collect_siblings(root, nodes); root = romanode_balanced_tree(nodes, 0, count); for (size_t i = 0; i < count; i++) nodes[i]->child = romanode_balance(nodes[i]->child); free(nodes); return root; } romaji * romaji_open() { romaji *rj = (romaji *)calloc(1, sizeof(romaji)); if (!rj) return NULL; rj->char2int = NULL; return rj; } void romaji_close(romaji *rj) { if (rj) { romanode_arena_free(&rj->arena); free(rj); } } static int romaji_add_entry(romaji *rj, const unsigned char *key, const unsigned char *value, const unsigned char *remain) { romanode **ppnode = &rj->rootnode; romanode *pnode = NULL; const unsigned char *p = key; while (1) { unsigned int code = charset_decode(rj->char2int, &p); if (code == 0) { if (!pnode) return 2; // Empty key. // Discard longer keys. if (*ppnode) *ppnode = NULL; // Duplicate value, and remain. unsigned char *dup_value = STRDUP(value); if (!dup_value) return 3; // Allocation for value failed. unsigned char *dup_remain = NULL; if (remain) { dup_remain = STRDUP(remain); if (!dup_remain) return 4; // Allocation for remain failed. } // Replace existing value, and remain. free(pnode->value); free(pnode->remain); pnode->value = dup_value; pnode->remain = dup_remain; break; } pnode = romanode_dig(&rj->arena, ppnode, code); if (!pnode) return 5; // Allocation error. // Move the focus deeper by traversing child nodes ppnode = &pnode->child; // Do not add the key if a shorter key is found. if (pnode && pnode->value) return 1; } return 0; } static void romanode_stat_stub( romanode *node, trie_stat *stat, int sib_depth, int total_cmp) { if (!node) return; stat->total_nodes++; stat->total_sibling_depth += sib_depth; if (sib_depth > stat->max_sibling_depth) stat->max_sibling_depth = sib_depth; if (node->low) stat->low_count++; if (node->high) stat->high_count++; if (node->child) stat->child_count++; if (node->value) { stat->wordtail_count++; stat->total_node_cmp_count += total_cmp; if (total_cmp > stat->max_node_cmp_count) stat->max_node_cmp_count = total_cmp; } // recursive calls for low, high, and child nodes. if (node->low) romanode_stat_stub(node->low, stat, sib_depth + 1, total_cmp + 1); if (node->high) romanode_stat_stub(node->high, stat, sib_depth + 1, total_cmp + 1); if (node->child) romanode_stat_stub(node->child, stat, 0, total_cmp + 1); } static void romanode_stat(romaji *rj, trie_stat *stat) { if (!stat || !rj || !rj->rootnode) return; memset(stat, 0, sizeof(*stat)); romanode_stat_stub(rj->rootnode, stat, 0, 1); } void romanode_print_stat(romaji *rj, const char *title) { if (!rj || !rj->rootnode) { printf("== INVALID romanode ===\n"); return; } trie_stat stat; romanode_stat(rj, &stat); trie_stat_print(&stat, title); } typedef enum { MODE_KEY_WAITING = 0, MODE_KEY_READING = 1, MODE_VALUE_WAITING = 2, MODE_VALUE_READING = 3, MODE_REMAIN_WAITING = 4, MODE_REMAIN_READING = 5, MODE_LINE_SKIP = 6, } load_mode; static int romaji_isspace_u(unsigned int code) { return code < 0x80 && isspace((int)code); } static int romaji_load_stub(romaji *rj, FILE *fp) { unsigned char buf[ROMAJI_READ_BUFSIZE]; while (1) { // Read a line from the file. if (!fgets(buf, sizeof(buf), fp)) { if (feof(fp)) break; // File read error. return 1; } size_t len = strlen(buf); if (len > 0 && buf[len - 1] != '\n' && !feof(fp)) { // The line is too long. return 2; } // Parse the line. load_mode mode = MODE_KEY_WAITING; unsigned char *end = buf + len; unsigned char *next; unsigned char *key = NULL, *key_end = NULL; unsigned char *value = NULL, *value_end = NULL; unsigned char *remain = NULL, *remain_end = NULL; for (unsigned char *p = buf; p < end; p = next) { next = p; unsigned int code = charset_decode(rj->char2int, (const unsigned char **)&next); // End of the line. if (code == '\n' || code == 0) { // Skip an empty line. if (!key) break; // Syntax error: value missing. if (!value) return 3; if (!value_end) // Case of: Key + Value + EOL value_end = p; else if (remain && !remain_end) // Case of: Key + Value + Remain remain_end = p; // Add a valid node to the dictionary. *key_end = '\0'; *value_end = '\0'; if (remain_end) *remain_end = '\0'; int err = romaji_add_entry(rj, key, value, remain); if (err > 1) return err * 10 + 4; break; } switch (mode) { case MODE_KEY_WAITING: if (code == '#') { // If the line starts with `##`, the key is treated as // starting with `#`; if it starts with only `#`, it is // treated as a comment line. unsigned char *next2 = next; unsigned int code2 = charset_decode( rj->char2int, (const unsigned char **)&next2); if (code2 != '#') { next = end; continue; } code = code2; p = next; next = next2; } if (!romaji_isspace_u(code)) { key = p; mode = MODE_KEY_READING; } break; case MODE_KEY_READING: if (romaji_isspace_u(code)) { key_end = p; mode = MODE_VALUE_WAITING; } break; case MODE_VALUE_WAITING: if (!romaji_isspace_u(code)) { value = p; mode = MODE_VALUE_READING; } break; case MODE_VALUE_READING: if (romaji_isspace_u(code)) { value_end = p; mode = MODE_REMAIN_WAITING; } break; case MODE_REMAIN_WAITING: if (!romaji_isspace_u(code)) { remain = p; mode = MODE_REMAIN_READING; } break; case MODE_REMAIN_READING: if (romaji_isspace_u(code)) { remain_end = p; mode = MODE_LINE_SKIP; } break; case MODE_LINE_SKIP: default: break; } } } return 0; } /// Load the Romaji dictionary. /// @param rj Romaji object /// @param filename Dictionary filename /// @return 0 on success, non-zero on failure. int romaji_load(romaji *rj, const unsigned char *filename, CHARSET_PROC_CHAR2INT char2int) { if (!rj || !filename) return -1; rj->char2int = charset_regulate_char2int(char2int); FILE *fp = fopen(filename, "rt"); if (!fp) return -1; int result = romaji_load_stub(rj, fp); fclose(fp); rj->rootnode = romanode_balance(rj->rootnode); return result; } static romanode * romaji_find_siblings(romaji *rj, romanode *node, unsigned int code) { if (node && node->child) node = node->child; if (!node) node = rj->rootnode; while (node) { if (node->code == code) return node; else if (code < node->code) node = node->low; else node = node->high; } return NULL; } static inline size_t romaji_decode_len(CHARSET_PROC_CHAR2INT proc, const unsigned char *s) { const unsigned char *p = s; charset_decode(proc, &p); return p - s; } static wordlist * romaji_add_pending_node( wordlist *head, wordlist *tail, romanode *node, strbuf *prefix) { if (!node) return tail; tail = romaji_add_pending_node(head, tail, node->low, prefix); if (node->value) { size_t len = strbuf_len(prefix); strbuf_append_str(prefix, node->value); if (!wordlist_contains(head, strbuf_get(prefix))) { wordlist *item = wordlist_new(strbuf_get(prefix), strbuf_len(prefix)); tail->next = item; tail = item; } strbuf_truncate(prefix, len); } tail = romaji_add_pending_node(head, tail, node->child, prefix); tail = romaji_add_pending_node(head, tail, node->high, prefix); return tail; } wordlist * romaji_convert_all(romaji *rj, const unsigned char *src) { if (!rj->rootnode) return NULL; wordlist *list = NULL; unsigned char *srcbuf = NULL; strbuf *dstbuf = NULL; strbuf *pending = NULL; size_t srclen = strlen(src); srcbuf = calloc(1, ROMAJI_PUSHBACK_BUFSIZE + srclen + 1); if (!srcbuf) goto END; unsigned char *curr = srcbuf + ROMAJI_PUSHBACK_BUFSIZE; memcpy(curr, src, srclen + 1); dstbuf = strbuf_open(); if (!dstbuf) goto END; pending = strbuf_open(); if (!pending) goto END; romanode *node = NULL; while (1) { const unsigned char *prev = curr; unsigned int code = charset_decode(rj->char2int, (const unsigned char **)&curr); if (code == 0) break; node = romaji_find_siblings(rj, node, code); if (!node) { strbuf_append_mem(pending, prev, curr - prev); // Consume a code from the pending, add it to dstbuf. unsigned char *p = strbuf_get(pending); size_t len = romaji_decode_len(rj->char2int, p); strbuf_append_mem(dstbuf, p, len); // Push the pending remainder to the front of srcbuf. size_t rem_len = strbuf_len(pending) - len; if (curr < srcbuf + rem_len) // Check if srcbuf has underflowed. goto END; curr -= rem_len; memcpy(curr, p + len, rem_len); strbuf_reset(pending); // Start the next search from the root. node = NULL; continue; } if (node->value) { strbuf_append_str(dstbuf, node->value); // Push node->remain to front of curr. if (node->remain) { size_t len = strlen(node->remain); // Check for source buffer underflow. if (curr < srcbuf + len) goto END; curr -= len; memcpy(curr, node->remain, len); } strbuf_reset(pending); // Start the next search from the root. node = NULL; continue; } strbuf_append_mem(pending, prev, curr - prev); } if (strbuf_len(pending) == 0) list = wordlist_new(strbuf_get(dstbuf), strbuf_len(dstbuf)); else { // Output all entries under the pending node. wordlist pendings = {0}; if (node) romaji_add_pending_node(&pendings, &pendings, node->child, dstbuf); list = pendings.next; } END: free(srcbuf); strbuf_close(dstbuf); strbuf_close(pending); return list; } cmigemo-1.8.0/src/romaji.h000066400000000000000000000011751524447636500154050ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // romaji.h - Romaji conversion // // Written By: MURAOKA Taro #pragma once #include "charset.h" #include "wordlist.h" typedef struct romaji romaji; #ifdef __cplusplus extern "C" { #endif // Life cycle management romaji *romaji_open(); void romaji_close(romaji *rj); // Load and convert int romaji_load(romaji *rj, const unsigned char *filename, CHARSET_PROC_CHAR2INT char2int); wordlist *romaji_convert_all(romaji *rj, const unsigned char *src); // Debug & maintenance void romanode_print_stat(romaji *rj, const char *title); #ifdef __cplusplus } #endif cmigemo-1.8.0/src/rxgen.c000066400000000000000000000333661524447636500152510ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // rxgen.c - regular expression generator // // Written By: MURAOKA Taro #include "common.h" #include #include #include #include #include #include "rxgen.h" #include "strbuf.h" #include "trie.h" #if defined(_MSC_VER) # define STRDUP _strdup #else # define STRDUP strdup #endif #define RXGEN_OP_MAXLEN 8 #define RXGEN_OP_OR "|" #define RXGEN_OP_NEST_IN "(" #define RXGEN_OP_NEST_OUT ")" #define RXGEN_OP_SELECT_IN "[" #define RXGEN_OP_SELECT_OUT "]" #define RXGEN_OP_NEWLINE "" #define RXGEN_DEBUG_STAT 0 #define RNODE_BLOCK_BYTES (64 * 1024) #define RNODE_BLOCK_HEADER_SIZE (sizeof(void *) + sizeof(size_t)) #define RNODE_BLOCK_SIZE \ ((RNODE_BLOCK_BYTES - RNODE_BLOCK_HEADER_SIZE) / sizeof(rnode)) typedef struct rnode rnode; struct rnode { rnode *low, *high; rnode *child; uint8_t height; unsigned int code; bool wordtail; }; typedef struct rnode_block rnode_block; struct rnode_block { rnode_block *next; size_t used; rnode nodes[RNODE_BLOCK_SIZE]; }; typedef struct rnode_arena { rnode_block *head; rnode_block *curr; } rnode_arena; struct rxgen { rnode *root; rnode_arena arena; CHARSET_PROC_CHAR2INT char2int; CHARSET_PROC_INT2CHAR int2char; uint32_t escapes_bitmap[3]; // 3 = (126 - 32 + 1 + 31) / 32 unsigned char op_or[RXGEN_OP_MAXLEN]; unsigned char op_nest_in[RXGEN_OP_MAXLEN]; unsigned char op_nest_out[RXGEN_OP_MAXLEN]; unsigned char op_select_in[RXGEN_OP_MAXLEN]; unsigned char op_select_out[RXGEN_OP_MAXLEN]; unsigned char op_newline[RXGEN_OP_MAXLEN]; }; // rnode interfaces static rnode * rnode_arena_alloc(rnode_arena *arena, unsigned code) { if (!arena->curr || arena->curr->used >= RNODE_BLOCK_SIZE) { rnode_block *block = (rnode_block *)calloc(1, sizeof(rnode_block)); if (!block) return NULL; if (!arena->head) arena->head = block; else arena->curr->next = block; arena->curr = block; } rnode *p = &arena->curr->nodes[arena->curr->used++]; p->height = 1; p->code = code; return p; } static void rnode_arena_free(rnode_arena *arena) { if (arena == NULL) return; for (rnode_block *p = arena->head; p;) { rnode_block *tmp = p; p = p->next; free(tmp); } arena->head = NULL; arena->curr = NULL; } // rxgen interfaces void rxgen_setproc_char2int(rxgen *rx, CHARSET_PROC_CHAR2INT proc) { if (!rx) return; rx->char2int = charset_regulate_char2int(proc); } void rxgen_setproc_int2char(rxgen *rx, CHARSET_PROC_INT2CHAR proc) { if (rx) rx->int2char = proc ? proc : charset_none_int2char; } void rxgen_set_escape_chars(rxgen *rx, const unsigned char *chars) { if (!rx) return; memset(rx->escapes_bitmap, 0, sizeof(rx->escapes_bitmap)); if (chars == NULL) chars = (const unsigned char *)"\\.*+^$/"; for (const unsigned char *p = chars; *p; ++p) { unsigned char c = *p; if (c >= 32 && c <= 126) { unsigned int idx = c - 32; rx->escapes_bitmap[idx / 32] |= (1U << (idx % 32)); } } } rxgen * rxgen_open() { rxgen *rx = (rxgen *)calloc(1, sizeof(rxgen)); if (rx) { rxgen_setproc_char2int(rx, NULL); rxgen_setproc_int2char(rx, NULL); rxgen_set_escape_chars(rx, NULL); strcpy(rx->op_or, RXGEN_OP_OR); strcpy(rx->op_nest_in, RXGEN_OP_NEST_IN); strcpy(rx->op_nest_out, RXGEN_OP_NEST_OUT); strcpy(rx->op_select_in, RXGEN_OP_SELECT_IN); strcpy(rx->op_select_out, RXGEN_OP_SELECT_OUT); strcpy(rx->op_newline, RXGEN_OP_NEWLINE); } return rx; } void rxgen_close(rxgen *rx) { if (rx) { rnode_arena_free(&rx->arena); free(rx); } } static inline uint8_t rnode_height(rnode *node) { return node ? node->height : 0; } static inline void rnode_update_height(rnode *p) { uint8_t l = rnode_height(p->low); uint8_t h = rnode_height(p->high); p->height = 1 + (l > h ? l : h); } static inline rnode * rnode_rotate_left(rnode *node) { rnode *r = node->high; node->high = r->low; r->low = node; rnode_update_height(node); rnode_update_height(r); return r; } static inline rnode * rnode_rotate_right(rnode *node) { rnode *l = node->low; node->low = l->high; l->high = node; rnode_update_height(node); rnode_update_height(l); return l; } static inline rnode * rnode_balance(rnode_arena *arena, rnode *node) { if (!node) return NULL; uint8_t l = rnode_height(node->low); uint8_t r = rnode_height(node->high); if (r > l + 1) { if (rnode_height(node->high->high) < rnode_height(node->high->low)) node->high = rnode_rotate_right(node->high); return rnode_rotate_left(node); } else if (l > r + 1) { if (rnode_height(node->low->low) < rnode_height(node->low->high)) node->low = rnode_rotate_left(node->low); return rnode_rotate_right(node); } rnode_update_height(node); return node; } static inline rnode * rnode_dig2balance(rnode_arena *arena, rnode **pp, unsigned int code) { rnode **path[32]; int path_top = 0; while (*pp) { path[path_top++] = pp; unsigned int pivot = (*pp)->code; pp = (code > pivot) ? &(*pp)->high : &(*pp)->low; } *pp = rnode_arena_alloc(arena, code); rnode *ret = *pp; while (path_top > 0) { rnode **p = path[--path_top]; *p = rnode_balance(arena, *p); } return ret; } static inline rnode * rnode_dig2(rnode_arena *arena, rnode **pp, unsigned int code, bool balance) { rnode **root = pp; while (*pp) { unsigned int pivot = (*pp)->code; if (code > pivot) pp = &(*pp)->high; else if (code < pivot) pp = &(*pp)->low; else return *pp; } if (!balance) { *pp = rnode_arena_alloc(arena, code); return *pp; } return rnode_dig2balance(arena, root, code); } int rxgen_add(rxgen *rx, const unsigned char *word) { if (!word) return 0; rnode **ppnode = &rx->root; rnode *pnode = NULL; bool balance = true; while (1) { unsigned int code = charset_decode(rx->char2int, &word); // Terminate if the input pattern is exhausted if (code == 0) break; pnode = rnode_dig2(&rx->arena, ppnode, code, balance); if (!pnode) return 0; // allocation error. if (pnode->wordtail) // If a shorter word is already registered than the one being // registered, discard the remaining characters. E.g.: // 赤 + 赤ちゃん -> 赤 // 国際 + 国際便 -> 国際 return 2; // not registered a word, but found short one. // Move the focus deeper by traversing child nodes ppnode = &pnode->child; balance = false; } if (pnode) pnode->wordtail = true; if (*ppnode) // If a longer word is already registered than the one being // registered, discard the longer one. E.g.: // 赤ちゃん + 赤 -> 赤 // 国際便 + 国際 -> 国際 *ppnode = NULL; return 1; // registered a word, some nodes. } static void rxgen_rnode_count(rnode *node, int *childrenCount, int *brotherCount) { if (node->child) (*childrenCount)++; if (node->low) { (*brotherCount)++; rxgen_rnode_count(node->low, childrenCount, brotherCount); } if (node->high) { (*brotherCount)++; rxgen_rnode_count(node->high, childrenCount, brotherCount); } } static inline void rxgen_append_ch(rxgen *rx, strbuf *buf, unsigned int code) { unsigned char bytes[CHARSET_MAX_BYTES]; int len = rx->int2char(code, bytes); strbuf_append_mem(buf, bytes, len); } static inline bool rxgen_is_escape(rxgen *rx, unsigned int code) { if (code < 32 || code > 126) return false; unsigned int idx = code - 32; return rx->escapes_bitmap[idx / 32] & (1U << (idx % 32)); } static void rxgen_write_node_code(rxgen *rx, strbuf *buf, rnode *node) { unsigned int code = node->code; if (rxgen_is_escape(rx, code)) rxgen_append_ch(rx, buf, '\\'); rxgen_append_ch(rx, buf, code); } static void rxgen_write_node_no_children(rxgen *rx, strbuf *buf, rnode *node) { if (node->low) rxgen_write_node_no_children(rx, buf, node->low); if (node->child == NULL) rxgen_write_node_code(rx, buf, node); if (node->high) rxgen_write_node_no_children(rx, buf, node->high); } static void rxgen_generate_stub(rxgen *rx, strbuf *buf, rnode *node); static void rxgen_write_node_has_children(rxgen *rx, strbuf *buf, rnode *node, bool *needOr) { if (node->low) rxgen_write_node_has_children(rx, buf, node->low, needOr); if (node->child != NULL) { // Output OR if necessary if (*needOr) strbuf_append_str(buf, rx->op_or); rxgen_write_node_code(rx, buf, node); // Insert a pattern that skips whitespace/newline if (rx->op_newline[0]) strbuf_append_str(buf, rx->op_newline); rxgen_generate_stub(rx, buf, node->child); *needOr = true; } if (node->high) rxgen_write_node_has_children(rx, buf, node->high, needOr); } static void rxgen_generate_stub(rxgen *rx, strbuf *buf, rnode *node) { // Check characteristics of the current level (number of siblings, number of // children) int childrenCount = 0; int brotherCount = 1; rxgen_rnode_count(node, &childrenCount, &brotherCount); int noChildrenCount = brotherCount - childrenCount; #if 0 // For debug printf("node=%p code=%04X\n noChildrenCount=%d childrenCount=%d brotherCount=%d\n", node, node->code, noChildrenCount, childrenCount, brotherCount); #endif bool needGroup = brotherCount > 1 && childrenCount > 0; bool needClass = noChildrenCount > 1; // Group using () if necessary if (needGroup) strbuf_append_str(buf, rx->op_nest_in); // Group nodes without children first with [] if (noChildrenCount > 0) { if (needClass) { strbuf_append_str(buf, rx->op_select_in); rxgen_write_node_no_children(rx, buf, node); strbuf_append_str(buf, rx->op_select_out); } else rxgen_write_node_no_children(rx, buf, node); } // Output nodes with children if (childrenCount > 0) { bool needOr = noChildrenCount > 0; rxgen_write_node_has_children(rx, buf, node, &needOr); } // Group using () if necessary if (needGroup) strbuf_append_str(buf, rx->op_nest_out); } #if RXGEN_DEBUG_STAT static void rnode_debug_stat_stub( rnode *node, trie_stat *stat, int sib_depth, int total_cmp) { if (!node) return; stat->total_nodes++; stat->total_sibling_depth += sib_depth; if (sib_depth > stat->max_sibling_depth) stat->max_sibling_depth = sib_depth; stat->total_node_cmp_count += total_cmp; if (total_cmp > stat->max_node_cmp_count) stat->max_node_cmp_count = total_cmp; if (node->low) stat->low_count++; if (node->high) stat->high_count++; if (node->child) stat->child_count++; if (node->wordtail) stat->wordtail_count++; if (node->low) rnode_debug_stat_stub(node->low, stat, sib_depth + 1, total_cmp + 1); if (node->high) rnode_debug_stat_stub(node->high, stat, sib_depth + 1, total_cmp + 1); if (node->child) rnode_debug_stat_stub(node->child, stat, 0, total_cmp + 1); } static void rnode_debug_stat(rnode *root) { trie_stat stat; memset(&stat, 0, sizeof(stat)); if (!root) return; rnode_debug_stat_stub(root, &stat, 0, 1); trie_stat_print(&stat, "rnode statistics"); } #endif unsigned char * rxgen_generate(rxgen *rx) { unsigned char *answer = NULL; strbuf *buf; if (rx && (buf = strbuf_open())) { if (rx->root) { #if RXGEN_DEBUG_STAT rnode_debug_stat(rx->root); #endif rxgen_generate_stub(rx, buf, rx->root); } answer = STRDUP(strbuf_get(buf)); strbuf_close(buf); } return answer; } void rxgen_release(rxgen *rx, unsigned char *s) { free(s); } // Reset all patterns added via rxgen_add() void rxgen_reset(rxgen *rx) { if (rx) { rnode_arena_free(&rx->arena); rx->root = NULL; } } static unsigned char * rxgen_get_operator_stub(rxgen *rx, int index) { switch (index) { case RXGEN_OPINDEX_OR: return rx->op_or; case RXGEN_OPINDEX_NEST_IN: return rx->op_nest_in; case RXGEN_OPINDEX_NEST_OUT: return rx->op_nest_out; case RXGEN_OPINDEX_SELECT_IN: return rx->op_select_in; case RXGEN_OPINDEX_SELECT_OUT: return rx->op_select_out; case RXGEN_OPINDEX_NEWLINE: return rx->op_newline; default: return NULL; } } const unsigned char * rxgen_get_operator(rxgen *rx, int index) { return (const unsigned char *)(rx ? rxgen_get_operator_stub(rx, index) : NULL); } int rxgen_set_operator(rxgen *rx, int index, const unsigned char *op) { unsigned char *dest; if (!rx) return 1; // Invalid rx if (strlen(op) >= RXGEN_OP_MAXLEN) return 2; // Too long operator if (!(dest = rxgen_get_operator_stub(rx, index))) return 3; // No such an operator strcpy(dest, op); return 0; } cmigemo-1.8.0/src/rxgen.h000066400000000000000000000021711524447636500152440ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // rxgen.h - regular expression generator // // Written By: MURAOKA Taro #pragma once #include "charset.h" typedef struct rxgen rxgen; // for rxgen_set_operator #define RXGEN_OPINDEX_OR 0 #define RXGEN_OPINDEX_NEST_IN 1 #define RXGEN_OPINDEX_NEST_OUT 2 #define RXGEN_OPINDEX_SELECT_IN 3 #define RXGEN_OPINDEX_SELECT_OUT 4 #define RXGEN_OPINDEX_NEWLINE 5 #ifdef __cplusplus extern "C" { #endif // Life cycle management rxgen *rxgen_open(); void rxgen_close(rxgen *rx); // Regexp pattern generation int rxgen_add(rxgen *rx, const unsigned char *word); unsigned char *rxgen_generate(rxgen *rx); void rxgen_release(rxgen *rx, unsigned char *s); void rxgen_reset(rxgen *rx); // Configuration void rxgen_setproc_char2int(rxgen *rx, CHARSET_PROC_CHAR2INT proc); void rxgen_setproc_int2char(rxgen *rx, CHARSET_PROC_INT2CHAR proc); void rxgen_set_escape_chars(rxgen *rx, const unsigned char *chars); int rxgen_set_operator(rxgen *rx, int index, const unsigned char *op); const unsigned char *rxgen_get_operator(rxgen *rx, int index); #ifdef __cplusplus } #endif cmigemo-1.8.0/src/strbuf.c000066400000000000000000000046301524447636500154230ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // strbuf.h - // // Written By: MURAOKA Taro #include "common.h" #include #include #include #include #include "strbuf.h" #define STRBUF_DEFAULT_SIZE 64 #define STRBUF_MAX_SIZE (8 * 1024 * 1024) strbuf * strbuf_open() { strbuf *sb = (strbuf *)malloc(sizeof(strbuf)); if (!sb) return NULL; sb->cap = STRBUF_DEFAULT_SIZE; sb->buf = (unsigned char *)malloc(sb->cap); if (!sb->buf) { free(sb); return NULL; } sb->len = 0; sb->buf[0] = '\0'; return sb; } void strbuf_close(strbuf *sb) { if (sb) { free(sb->buf); free(sb); } } // strbuf_extend(strbuf * sb, int req_len); // Expand the buffer. Returns 0 on error. // The caller decides whether to expand for performance. size_t strbuf_extend(strbuf *sb, size_t req_len) { if (req_len > STRBUF_MAX_SIZE) return 0; size_t newlen = sb->cap * 2; while (req_len > newlen) newlen *= 2; unsigned char *newbuf; if (!(newbuf = (unsigned char *)realloc(sb->buf, newlen))) return 0; sb->cap = newlen; sb->buf = newbuf; return req_len; } size_t strbuf_append_ch(strbuf *sb, unsigned char ch) { if (!strbuf_extend(sb, sb->len + 2)) return 0; return strbuf_add(sb, ch); } size_t strbuf_append(strbuf *sb, strbuf *q) { return strbuf_append_mem(sb, q->buf, q->len); } size_t strbuf_append_str(strbuf *sb, const unsigned char *s) { size_t len = 0; if (s != NULL) { size_t l = strlen(s); len = l < INT_MAX ? l : INT_MAX; } if (len > 0) { size_t newlen = (size_t)sb->len + len + 1; if (newlen > sb->cap && !strbuf_extend(sb, newlen)) return 0; memcpy(&sb->buf[sb->len], s, len + 1); sb->len += len; } return sb->len; } size_t strbuf_append_mem(strbuf *sb, const unsigned char *p, size_t len) { if (p != NULL && len > 0) { size_t newlen = sb->len + len + 1; if (newlen > sb->cap && !strbuf_extend(sb, newlen)) return 0; memcpy(&sb->buf[sb->len], p, len); sb->len += len; sb->buf[sb->len] = '\0'; } return sb->len; } size_t strbuf_truncate(strbuf *sb, size_t len) { if (len >= sb->len) return sb->len; sb->buf[len] = '\0'; sb->len = len; return len; } cmigemo-1.8.0/src/strbuf.h000066400000000000000000000024261524447636500154310ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // strbuf.h - // // Written By: MURAOKA Taro #pragma once typedef struct strbuf strbuf; struct strbuf { size_t cap; // amount of memory allocated to buf size_t len; // length of the string actually stored in buf unsigned char *buf; }; #ifdef __cplusplus extern "C" { #endif // Life cycle managements strbuf *strbuf_open(); void strbuf_close(strbuf *sb); size_t strbuf_extend(strbuf *sb, size_t req_len); // Append functions size_t strbuf_append(strbuf *sb, strbuf *q); size_t strbuf_append_ch(strbuf *sb, unsigned char ch); size_t strbuf_append_str(strbuf *sb, const unsigned char *s); size_t strbuf_append_mem(strbuf *sb, const unsigned char *p, size_t len); // Others size_t strbuf_truncate(strbuf *sb, size_t len); #ifdef __cplusplus } #endif static inline size_t strbuf_len(strbuf *sb) { return sb->len; } static inline unsigned char * strbuf_get(strbuf *sb) { return sb->buf; } static inline void strbuf_reset(strbuf *sb) { sb->len = 0; sb->buf[0] = '\0'; } static inline size_t strbuf_add(strbuf *sb, unsigned char ch) { if (sb->len + 2 <= sb->cap) { sb->buf[sb->len++] = ch; sb->buf[sb->len] = 0; return sb->len; } return strbuf_append_ch(sb, ch); } cmigemo-1.8.0/src/stree.c000066400000000000000000000161041524447636500152370ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // stree.c - Static version of mtree #include "common.h" #include #include #include "mtree.h" #include "stree.h" ////////////////////////////////////////////////////////////////////////////// static stree * stree_alloc(stree_header *head) { if (head->node_count == 0) return NULL; stree *st = calloc(1, sizeof(stree)); if (!st) goto FAIL; st->head = *head; st->nodes = calloc(head->node_count, sizeof(snode)); st->word_buf = calloc(head->word_buf_size, sizeof(uint8_t)); if (!st->nodes || !st->word_buf) goto FAIL; return st; FAIL: stree_destroy(st); return NULL; } void stree_destroy(stree *st) { if (!st) return; free(st->nodes); free(st->word_buf); free(st); } static void stree_count_mnode(stree_header *head, mnode *node) { head->node_count++; if (node->low) stree_count_mnode(head, node->low); if (node->list) { for (wordlist *list = node->list; list; list = wordlist_next(list)) head->word_buf_size += (uint32_t)strlen(wordlist_word(list)) + 1; head->word_buf_size++; // for terminal '\0' } if (node->child) stree_count_mnode(head, node->child); if (node->high) stree_count_mnode(head, node->high); } typedef struct stree_converter { stree *st; uint32_t node_next; uint32_t word_buf_next; } stree_converter; static uint32_t stree_count_mnode_siblings(mnode *node) { if (!node) return 0; return 1 + stree_count_mnode_siblings(node->low) + stree_count_mnode_siblings(node->high); } static uint32_t stree_fill_mnode_siblings( stree_converter *cnv, mnode *node, uint32_t curr); static void stree_fill_mnode(stree_converter *cnv, mnode *node, uint32_t curr) { if (!node) return; uint32_t countSiblings = stree_count_mnode_siblings(node->child); uint32_t start = cnv->node_next; uint32_t end = start + countSiblings; snode dst = { .code = node->code, .start = start, .end = end, .word_idx = STREE_INVALID_WORD_IDX, }; cnv->node_next = end; if (node->list) { dst.word_idx = cnv->word_buf_next; for (wordlist *list = node->list; list; list = wordlist_next(list)) { unsigned char *word = wordlist_word(list); size_t len = strlen(word); memcpy(cnv->st->word_buf + cnv->word_buf_next, word, len); cnv->word_buf_next += (uint32_t)len; cnv->st->word_buf[cnv->word_buf_next++] = '\0'; } cnv->st->word_buf[cnv->word_buf_next++] = '\0'; } cnv->st->nodes[curr] = dst; if (!node->child) return; stree_fill_mnode_siblings(cnv, node->child, start); } static uint32_t stree_fill_mnode_siblings(stree_converter *cnv, mnode *node, uint32_t curr) { if (node->low) curr = stree_fill_mnode_siblings(cnv, node->low, curr); stree_fill_mnode(cnv, node, curr); curr++; if (node->high) curr = stree_fill_mnode_siblings(cnv, node->high, curr); return curr; } static uint8_t stree_char2int_to_charset(CHARSET_PROC_CHAR2INT char2int) { if (char2int == charset_cp932_char2int) return CHARSET_CP932; else if (char2int == charset_eucjp_char2int) return CHARSET_EUCJP; else if (char2int == charset_utf8_char2int || char2int == NULL) // With the introduction of default values for optimization purposes, // NULL has also come to signify UTF-8. return CHARSET_UTF8; else return CHARSET_NONE; } stree * stree_from_mtree(mtree *mt) { stree_header head = {.node_count = 1}; memcpy(&head.id, STREE_HEAD_ID_V1, sizeof(head.id)); mnode *mtroot = mtree_rootnode(mt); if (mtroot) stree_count_mnode(&head, mtroot); stree *st = stree_alloc(&head); if (!st) return NULL; st->char2int = charset_regulate_char2int(mt->char2int); st->head.charset = stree_char2int_to_charset(mt->char2int); stree_converter cnv = { .st = st, .node_next = 1, }; mnode root = { .child = mtroot, }; stree_fill_mnode(&cnv, &root, 0); return st; } ////////////////////////////////////////////////////////////////////////////// stree * stree_load(const char *filename) { stree *retval = NULL, *st = NULL; FILE *fp = fopen(filename, "rb"); if (!fp) goto END; // Load the header stree_header head = {0}; if (fread(&head, sizeof(head), 1, fp) < 1) goto END; if (memcmp(head.id, STREE_HEAD_ID_V1, 4) != 0) goto END; // Allocate buffers st = stree_alloc(&head); if (!st) goto END; // Load buffers if (fread(st->nodes, sizeof(snode), head.node_count, fp) != head.node_count) goto END; if (fread(st->word_buf, sizeof(uint8_t), head.word_buf_size, fp) != head.word_buf_size) goto END; // Setup charset. CHARSET_PROC_CHAR2INT char2int = NULL; charset_getproc(head.charset, &char2int, NULL); st->char2int = charset_regulate_char2int(char2int); retval = st; st = NULL; END: if (st) stree_destroy(st); if (fp) fclose(fp); return retval; } int stree_save(stree *st, const char *filename) { int retval = 1; FILE *fp = fopen(filename, "wb"); if (!fp) goto END; stree_header head = st->head; memcpy(&head.id, STREE_HEAD_ID_V1, 4); if (fwrite(&head, sizeof(stree_header), 1, fp) != 1) goto END; if (fwrite(st->nodes, sizeof(snode), head.node_count, fp) != head.node_count) goto END; if (fwrite(st->word_buf, sizeof(uint8_t), head.word_buf_size, fp) != head.word_buf_size) goto END; retval = 0; END: if (fp) { fclose(fp); if (retval != 0) remove(filename); } return retval; } static uint32_t stree_find_siblings(stree *st, uint32_t start, uint32_t end, unsigned int code) { if (start < end && (code < st->nodes[start].code || code > st->nodes[end - 1].code)) return STREE_INVALID_NODE_ID; while (start < end) { uint32_t mid = (start + end) / 2; uint32_t pivot = st->nodes[mid].code; if (code < pivot) end = mid; else if (code > pivot) start = mid + 1; else return mid; } return STREE_INVALID_NODE_ID; } snode * stree_query(stree *st, const unsigned char *query) { if (!st || !query) return NULL; unsigned int code = charset_decode(st->char2int, &query); if (code == 0) return NULL; uint32_t curr = 0; while (1) { snode node = st->nodes[curr]; // Search from siblings curr = stree_find_siblings(st, node.start, node.end, code); if (curr == STREE_INVALID_NODE_ID) return NULL; // Not found the code (rune). // Proceed to the child node code = charset_decode(st->char2int, &query); if (code == 0) break; // Found the node. } return &st->nodes[curr]; } cmigemo-1.8.0/src/stree.h000066400000000000000000000020071524447636500152410ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // stree.h - Static version of mtree #pragma once #include #include "charset.h" #include "mtree.h" #define STREE_HEAD_ID_V1 "MGS1" #define STREE_INVALID_NODE_ID 0xffffffff #define STREE_INVALID_WORD_IDX 0xffffffff typedef struct stree stree; typedef struct snode { uint32_t code; uint32_t start; uint32_t end; uint32_t word_idx; } snode; typedef struct stree_header { uint8_t id[4]; uint32_t node_count; uint32_t word_buf_size; uint8_t charset; } stree_header; typedef struct stree { stree_header head; snode *nodes; uint8_t *word_buf; CHARSET_PROC_CHAR2INT char2int; } stree; #ifdef __cplusplus extern "C" { #endif // Life cycle management void stree_destroy(stree *st); stree *stree_from_mtree(mtree *mt); // Serialization stree *stree_load(const char *filename); int stree_save(stree *st, const char *filename); // Query snode *stree_query(stree *st, const unsigned char *query); #ifdef __cplusplus } #endif cmigemo-1.8.0/src/trie.c000066400000000000000000000031721524447636500150610ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // trie.c - #include #include "common.h" #include "trie.h" void trie_stat_print(const trie_stat *stat, const char *title) { printf("=== %s\n", title ? title : ""); printf("Total Nodes : %zu\n", stat->total_nodes); printf("Wordtail Nodes : %zu\n", stat->wordtail_count); printf("Pointer Counts : low=%zu, high=%zu, child=%zu\n", stat->low_count, stat->high_count, stat->child_count); printf("Low/High Balance Ratio: %.2f%% / %.2f%%\n", stat->low_count + stat->high_count > 0 ? (double)stat->low_count / (stat->low_count + stat->high_count) * 100.0 : 0.0, stat->low_count + stat->high_count > 0 ? (double)stat->high_count / (stat->low_count + stat->high_count) * 100.0 : 0.0); printf("Sibling Depth : max=%d, avg=%.2f\n", stat->max_sibling_depth, stat->total_nodes > 0 ? (double)stat->total_sibling_depth / stat->total_nodes : 0.0); printf("Node Compare Count : max=%d, avg=%.2f\n", stat->max_node_cmp_count, stat->total_nodes > 0 ? (double)stat->total_node_cmp_count / stat->total_nodes : 0.0); printf("Word Compare Count : max=%d, avg=%.2f\n", stat->max_node_cmp_count, stat->wordtail_count > 0 ? (double)stat->total_node_cmp_count / stat->wordtail_count : 0.0); printf("===\n"); } cmigemo-1.8.0/src/trie.h000066400000000000000000000006231524447636500150640ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // trie.h - #pragma once typedef struct { size_t total_nodes; size_t low_count; size_t high_count; size_t child_count; size_t wordtail_count; int max_sibling_depth; size_t total_sibling_depth; int max_node_cmp_count; size_t total_node_cmp_count; } trie_stat; void trie_stat_print(const trie_stat *stat, const char *title); cmigemo-1.8.0/src/wordlist.c000066400000000000000000000015201524447636500157600ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // wordlist.h - // // Written By: MURAOKA Taro #include "common.h" #include #include #include #include "wordlist.h" wordlist * wordlist_new(const unsigned char *p, size_t len) { if (!p) return NULL; wordlist *wl = (wordlist *)malloc(sizeof(wordlist) + len + 1); if (!wl) return NULL; wl->next = NULL; if (len > 0) memcpy(wl->ptr, p, len); wl->ptr[len] = '\0'; return wl; } void wordlist_destroy(wordlist *wl) { while (wl) { wordlist *next = wl->next; free(wl); wl = next; } } bool wordlist_contains(wordlist *wl, const unsigned char *str) { for (; wl; wl = wl->next) if (!strcmp(wl->ptr, str)) return true; return false; } cmigemo-1.8.0/src/wordlist.h000066400000000000000000000012751524447636500157740ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // wordlist.h - // // Written By: MURAOKA Taro #pragma once #include #include typedef struct wordlist wordlist; struct wordlist { wordlist *next; unsigned char ptr[]; }; #ifdef __cplusplus extern "C" { #endif // Life cycle management wordlist *wordlist_new(const unsigned char *ptr, size_t len); void wordlist_destroy(wordlist *wl); // Others bool wordlist_contains(wordlist *wl, const unsigned char *str); #ifdef __cplusplus } #endif static inline wordlist * wordlist_next(wordlist *wl) { return wl->next; } static inline unsigned char * wordlist_word(wordlist *wl) { return wl->ptr; } cmigemo-1.8.0/test/000077500000000000000000000000001524447636500141375ustar00rootroot00000000000000cmigemo-1.8.0/test/CMakeLists.txt000066400000000000000000000020071524447636500166760ustar00rootroot00000000000000set(ALL_TEST_TARGETS "") function(add_migemo_test name src) set(target "${name}_test") add_executable(${target} ${src}) target_link_libraries(${target} PRIVATE migemo_static) target_include_directories(${target} PRIVATE ${PROJECT_SOURCE_DIR}/src) if(ARGN) target_compile_definitions(${target} PRIVATE ${ARGN}) endif() add_test(NAME "test_${name}" COMMAND ${target}) set(ALL_TEST_TARGETS ${ALL_TEST_TARGETS} ${target} PARENT_SCOPE) endfunction() #------------------------------------------------------------------------------ add_migemo_test( migemo migemo.c TEST_DICTDIR_MIGEMO="${CMAKE_CURRENT_SOURCE_DIR}/_testdata" TEST_DICTDIR_ROMA2HIRA="${PROJECT_SOURCE_DIR}/dict") add_migemo_test(romaji romaji.c TEST_DICTDIR_ROMA2HIRA="${PROJECT_SOURCE_DIR}/dict") add_migemo_test(rxgen rxgen.c) #------------------------------------------------------------------------------ add_custom_target( check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure DEPENDS ${ALL_TEST_TARGETS}) cmigemo-1.8.0/test/_testdata/000077500000000000000000000000001524447636500161075ustar00rootroot00000000000000cmigemo-1.8.0/test/_testdata/migemo-dict000066400000000000000000000000641524447636500202300ustar00rootroot00000000000000あか 赤 紅 朱 あけ 明 あき 秋 あく 悪 cmigemo-1.8.0/test/index.md000066400000000000000000000024361524447636500155750ustar00rootroot00000000000000--- type: Directory Index title: "Test Index" description: "Holds the C test programs and fixture dictionary for cmigemo's CTest suite" tags: [index] --- # Overview Contains the executable C tests for the migemo library (migemo queries, romaji conversion, and rxgen regexp generation) plus their shared test configuration and fixture dictionary, registered with CMake via `add_migemo_test`. # Directory Contents | File / Path | Type | Description | | :--- | :--- | :--- | | [CMakeLists.txt](./CMakeLists.txt) | File | Defines the CTest test targets and the `check` convenience target for all test executables. | | [migemo.c](./migemo.c) | File | Test program that asserts migemo_query results against expected conversions using the fixture dictionary. | | [romaji.c](./romaji.c) | File | Test program that verifies romaji-to-hiragana conversion output against expected wordlists. | | [rxgen.c](./rxgen.c) | File | Test program that checks regexp generation, including escape-character handling, in rxgen. | | [test_common.h](./test_common.h) | Header | Provides default test-directory macros such as the romaji dictionary directory path. | | [_testdata/](./_testdata) | Directory | Contains the `migemo-dict` fixture dictionary consumed by the migemo test. | # References - [Parent Directory](../index.md) cmigemo-1.8.0/test/migemo.c000066400000000000000000000040051524447636500155570ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: #include #include #include "migemo.h" #include "test_common.h" #ifndef TEST_DICTDIR_MIGEMO # define TEST_DICTDIR_MIGEMO "test1" #endif static int assert_query(migemo *p, const char *q, const char *ex) { char *r; r = migemo_query(p, q); if (strcmp(r, ex) != 0) { printf("Failed: query \"%s\" generate \"%s\" (expected \"%s\")\n", q, r, ex); migemo_release(p, r); return 1; } migemo_release(p, r); return 0; } static int test_all(migemo *p) { if (assert_query(p, "ak", "([悪明朱秋紅赤]|ak|あ[かきくけこっ])") != 0) return 1; if (assert_query(p, "n", "[nなにぬねのん]") != 0) return 1; // FIXME: add tests return 0; } int main(int argc, char **argv) { int r; migemo *p; const char *ver = migemo_version(); if (ver == NULL || strcmp(ver, MIGEMO_VERSION MIGEMO_VERSION_PRERELEASE) != 0) { printf("Failed: migemo_version() returned \"%s\" (expected \"%s\")\n", ver ? ver : "(null)", MIGEMO_VERSION MIGEMO_VERSION_PRERELEASE); return 1; } p = migemo_open(TEST_DICTDIR_MIGEMO "/migemo-dict"); if (p == NULL) { printf("Failed: can't create migemo object and get its pointer\n"); return 1; } r = migemo_load(p, MIGEMO_DICTID_ROMA2HIRA, TEST_DICTDIR_ROMA2HIRA "/roma2hira.dat"); if (r != MIGEMO_DICTID_ROMA2HIRA) { printf("Failed: can't load \"%s\" (dict_id: %d)\n", TEST_DICTDIR_ROMA2HIRA "/roma2hira.dat", MIGEMO_DICTID_ROMA2HIRA); return r; } if (test_all(p)) { printf("Failed: mtree\n"); return 1; } if (migemo_switch_sdict(p, MIGEMO_SDICT_RELEASE_MDICT) == 0) { printf("Failed: migemo_switch_sdict\n"); return 1; } if (test_all(p)) { printf("Failed: sdict\n"); return 1; } migemo_close(p); return 0; } cmigemo-1.8.0/test/romaji.c000066400000000000000000000121171524447636500155660ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: #include #include #include #include "romaji.h" #include "wordlist.h" #include "test_common.h" static uint32_t count_list(wordlist *list) { uint32_t count = 0; for (; list; list = list->next) count++; return count; } static int check_all(romaji *rj, const unsigned char *src, const unsigned char **want) { int result = 1; wordlist *list = romaji_convert_all(rj, src); uint32_t got_count = count_list(list); uint32_t want_count = 0; for (const unsigned char **p = want; *p; p++) want_count++; if (got_count != want_count) { printf("count mismatch: want=%d got=%d src=%s\n", want_count, got_count, src); goto END; } if (got_count == 0) { result = 0; goto END; } wordlist *wl = list; for (uint32_t i = 0; i < got_count; i++) { if (strcmp(want[i], wl->ptr)) { printf("#%d mismatch: want=%s got=%s src=%s\n", i, want[i], wl->ptr, src); goto END; } wl = wl->next; } result = 0; END: if (list && result != 0) { printf("got list for src=%s\n", src); int i = 0; for (wordlist *curr = list; curr; curr = curr->next) printf(" #%d %s\n", i++, curr->ptr); } if (list) wordlist_destroy(list); return result; } static int check_one(romaji *rj, const unsigned char *src, const unsigned char *want) { return check_all(rj, src, (const unsigned char *[]){want, NULL}); } static int test_roma2hira(void) { romaji *rj = romaji_open(); int has_error = 1; if (!rj) { printf("Failed: romaji_open() returned NULL\n"); goto END; } int r; r = romaji_load(rj, TEST_DICTDIR_ROMA2HIRA "/roma2hira.dat", NULL); if (r != 0) { printf("Failed: romaji_load() returned non zero: %d", r); goto END; } r = check_all(rj, "a", (const unsigned char *[]){"あ", NULL}); if (r != 0) goto END; r = check_all(rj, "aki", (const unsigned char *[]){"あき", NULL}); if (r != 0) goto END; r = check_all(rj, "k", (const unsigned char *[]){"か", "け", "き", "っ", "こ", "く", "くぁ", "きゃ", "きぇ", "きぃ", "きょ", "きゅ", NULL}); if (r != 0) goto END; r = check_all(rj, "nya", (const unsigned char *[]){"にゃ", NULL}); if (r != 0) goto END; r = check_all(rj, "ny", (const unsigned char *[]){ "にゃ", "にぇ", "にぃ", "にょ", "にゅ", NULL}); if (r != 0) goto END; r = check_all(rj, "n", (const unsigned char *[]){"ん", "な", "ね", "に", "の", "ぬ", "にゃ", "にぇ", "にぃ", "にょ", "にゅ", NULL}); if (r != 0) goto END; r = check_all(rj, "", (const unsigned char *[]){"", NULL}); if (r != 0) goto END; r = check_one(rj, "nn", "ん"); if (r != 0) goto END; r = check_one(rj, "n'", "ん"); if (r != 0) goto END; r = check_one(rj, "ltu", "っ"); if (r != 0) goto END; r = check_all(rj, "nk", (const unsigned char *[]){"んか", "んけ", "んき", "んっ", "んこ", "んく", "んくぁ", "んきゃ", "んきぇ", "んきぃ", "んきょ", "んきゅ", NULL}); if (r != 0) goto END; r = check_one(rj, "nba", "んば"); if (r != 0) goto END; r = check_one(rj, "bba", "っば"); if (r != 0) goto END; r = check_one(rj, "ai", "あい"); if (r != 0) goto END; r = check_one(rj, "kate", "かて"); if (r != 0) goto END; has_error = 0; // Passed all cases. END: if (rj) romaji_close(rj); return has_error; } static int test_hira2kana(void) { romaji *rj = romaji_open(); int has_error = 1; if (!rj) { printf("Failed: romaji_open() returned NULL\n"); goto END; } int r; r = romaji_load(rj, TEST_DICTDIR_ROMA2HIRA "/hira2kata.dat", NULL); if (r != 0) { printf("Failed: romaji_load() returned non zero: %d", r); goto END; } r = check_one(rj, "あ", "ア"); if (r != 0) goto END; r = check_one(rj, "にゃ", "ニャ"); if (r != 0) goto END; r = check_one(rj, "きゃんでぃ", "キャンディ"); if (r != 0) goto END; r = check_one(rj, "っ", "ッ"); if (r != 0) goto END; r = check_one(rj, "しゃ", "シャ"); if (r != 0) goto END; r = check_one(rj, "きゃ", "キャ"); if (r != 0) goto END; r = check_one(rj, "きゃんでいー", "キャンデイー"); if (r != 0) goto END; has_error = 0; // Passed all cases. END: if (rj) romaji_close(rj); return has_error; } int main(int argc, char **argv) { int r; if ((r = test_roma2hira()) != 0) return r; if ((r = test_hira2kana()) != 0) return r; return 0; } cmigemo-1.8.0/test/rxgen.c000066400000000000000000000060311524447636500154260ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: #include #include #include "migemo.h" #include "rxgen.h" int main(int argc, char **argv) { rxgen *rx = rxgen_open(); if (!rx) { printf("Failed: rxgen_open() returned NULL\n"); return 1; } // Test rxgen_set_escape_chars with NULL (default set: \.*+^$/) rxgen_set_escape_chars(rx, NULL); rxgen_add(rx, (const unsigned char *)"a+b.c*d^e$f/g\\h?i"); unsigned char *pat = rxgen_generate(rx); if (!pat) { printf("Failed: rxgen_generate() returned NULL\n"); rxgen_close(rx); return 1; } const char *expected_default = "a\\+b\\.c\\*d\\^e\\$f\\/g\\\\h?i"; if (strcmp((const char *)pat, expected_default) != 0) { printf("Failed default rxgen escape: got \"%s\", expected \"%s\"\n", pat, expected_default); rxgen_release(rx, pat); rxgen_close(rx); return 1; } rxgen_release(rx, pat); // Test rxgen_set_escape_chars with custom string including out-of-range // chars rxgen_reset(rx); // Escape '?' and '+' (plus ASCII out-of-range chars 0x01, 0xFF) rxgen_set_escape_chars(rx, (const unsigned char *)"\x01?+\xFF"); rxgen_add(rx, (const unsigned char *)"a+b.c?d"); pat = rxgen_generate(rx); const char *expected_custom = "a\\+b.c\\?d"; if (strcmp((const char *)pat, expected_custom) != 0) { printf("Failed custom rxgen escape: got \"%s\", expected \"%s\"\n", pat, expected_custom); rxgen_release(rx, pat); rxgen_close(rx); return 1; } rxgen_release(rx, pat); // Test rxgen_set_escape_chars with empty string "" (no escaping) rxgen_reset(rx); rxgen_set_escape_chars(rx, (const unsigned char *)""); rxgen_add(rx, (const unsigned char *)"a+b.c\\d"); pat = rxgen_generate(rx); const char *expected_empty = "a+b.c\\d"; if (strcmp((const char *)pat, expected_empty) != 0) { printf("Failed empty rxgen escape: got \"%s\", expected \"%s\"\n", pat, expected_empty); rxgen_release(rx, pat); rxgen_close(rx); return 1; } rxgen_release(rx, pat); rxgen_close(rx); // Test migemo_set_escape_chars API migemo *mo = migemo_open(NULL); if (!mo) { printf("Failed: migemo_open(NULL) returned NULL\n"); return 1; } migemo_set_escape_chars(mo, (const unsigned char *)"+?"); unsigned char *qres = migemo_query(mo, (const unsigned char *)"a+b?c.d"); if (!qres) { printf("Failed: migemo_query returned NULL\n"); migemo_close(mo); return 1; } const char *expected_migemo = "a\\+b\\?c.d"; if (strcmp((const char *)qres, expected_migemo) != 0) { printf("Failed migemo custom escape query: got \"%s\", expected " "\"%s\"\n", qres, expected_migemo); migemo_release(mo, qres); migemo_close(mo); return 1; } migemo_release(mo, qres); migemo_close(mo); return 0; } cmigemo-1.8.0/test/test_common.h000066400000000000000000000002031524447636500166320ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: #pragma once #ifndef TEST_DICTDIR_ROMA2HIRA # define TEST_DICTDIR_ROMA2HIRA "../dict" #endif cmigemo-1.8.0/tools/000077500000000000000000000000001524447636500143205ustar00rootroot00000000000000cmigemo-1.8.0/tools/CMakeLists.txt000066400000000000000000000017541524447636500170670ustar00rootroot00000000000000if(WIN32) set(CMIGEMO_DEFAULT_DICTDIR "${CMAKE_INSTALL_FULL_DATADIR}/cmigemo/cp932") set(DEFAULT_DICTDIR "${PROJECT_BINARY_DIR}/dict/cp932") else() set(CMIGEMO_DEFAULT_DICTDIR "${CMAKE_INSTALL_FULL_DATADIR}/cmigemo/utf-8") set(DEFAULT_DICTDIR "${PROJECT_BINARY_DIR}/dict/utf-8") endif() #------------------------------------------------------------------------------ add_executable(cmigemo cmigemo.c) target_link_libraries(cmigemo PRIVATE migemo) target_compile_definitions( cmigemo PRIVATE CMIGEMO_DICTDIR="${CMIGEMO_DEFAULT_DICTDIR}") install( TARGETS cmigemo RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT core LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT core ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT core) #------------------------------------------------------------------------------ add_executable(romaji romaji.c) target_compile_definitions(romaji PUBLIC DICTDIR="${DEFAULT_DICTDIR}") target_link_libraries(romaji PRIVATE migemo_static) cmigemo-1.8.0/tools/cmigemo.c000066400000000000000000000230411524447636500161040ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // main.c - Migemo library test driver // // Written By: MURAOKA Taro #include #include #include #include #include #include "migemo.h" #define MIGEMO_ABOUT "cmigemo - C/Migemo Library " MIGEMO_VERSION " Driver" #define MIGEMO_SUBDICT_MAX 8 #ifndef S_ISREG # define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) #endif static int is_exist_regular(const char *file) { struct stat st; return stat(file, &st) == 0 && S_ISREG(st.st_mode); } // main int query_loop(migemo *mo, int quiet) { unsigned char buf[256]; while (!feof(stdin)) { if (!quiet) printf("QUERY: "); // Changed from gets() to fgets() if (!fgets(buf, sizeof(buf), stdin)) { if (!quiet) printf("\n"); break; } // Replace LF with '\0'. If no LF is present, set the end of the buffer // to '\0' to ensure the string is null-terminated. int i = 0; while (i < sizeof(buf) - 1 && buf[i] != '\n' && buf[i] != '\0') i++; buf[i] = '\0'; unsigned char *ans = migemo_query(mo, buf); if (ans) printf(quiet ? "%s\n" : "PATTERN: %s\n", ans); fflush(stdout); migemo_release(mo, ans); } return 0; } static void help(const char *prgname, int exitcode) { printf("\ %s \n\ \n\ USAGE: %s [OPTIONS]\n\ \n\ OPTIONS:\n\ -d --dict Use a file for dictionary.\n\ -s --subdict Sub dictionary files. (MAX %d times)\n\ -u --userdict Alias for -s/--subdict\n\ --convert Convert the dictionary to static (sdict)\n\ and keep using it.\n\ --save Save converted static dictionary (sdict)\n\ (imply --convert)\n\ --sdict Load as static dictionary (sdict)\n\ (conflict with -d/s/u, and --convert/save)\n\ -q --quiet Show no message except results.\n\ -v --vim Use vim style regexp.\n\ -e --emacs Use emacs style regexp.\n\ -n --nonewline Don't use newline match.\n\ -w --word Expand a and soon exit.\n\ -h --help Show this message.\n\ ", MIGEMO_ABOUT, prgname, MIGEMO_SUBDICT_MAX); exit(exitcode); } static void unknown_option(const char *prgname, char *arg) { fprintf(stderr, "ERROR: unknown option: %s\n", arg); help(prgname, 1); } static void missing_argument(const char *prgname, char *arg) { fprintf(stderr, "ERROR: missing argument: %s\n", arg); help(prgname, 1); } static void assure_file(const char *file) { if (is_exist_regular(file)) return; fprintf(stderr, "ERROR: can't find file: %s\n", file); exit(1); } static migemo * open_first_migemo(const char **found, const char **dicts) { for (; dicts != NULL && *dicts != NULL; dicts++) { if (is_exist_regular(*dicts) == 0) continue; migemo *mo = migemo_open(*dicts); if (mo == NULL) continue; *found = *dicts; return mo; } return NULL; } static const char *default_dicts[] = { #if _WIN32 "./dict/cp932/" MIGEMO_DICT_FILENAME, "../dict/cp932/" MIGEMO_DICT_FILENAME, "./build/dict/cp932/" MIGEMO_DICT_FILENAME, #else "./dict/utf-8/" MIGEMO_DICT_FILENAME, "../dict/utf-8/" MIGEMO_DICT_FILENAME, "./build/dict/utf-8/" MIGEMO_DICT_FILENAME, #endif "./dict/" MIGEMO_DICT_FILENAME, "../dict/" MIGEMO_DICT_FILENAME, "./build/dict/" MIGEMO_DICT_FILENAME, #ifdef CMIGEMO_DICTDIR CMIGEMO_DICTDIR "/" MIGEMO_DICT_FILENAME, #endif NULL, }; int main(int argc, char **argv) { const char *prgname = argv[0]; int mode_vim = 0; int mode_emacs = 0; int mode_nonewline = 0; int mode_quiet = 0; char *dict = NULL; char *subdict[MIGEMO_SUBDICT_MAX] = {0}; int subdict_count = 0; int convert = 0; char *save_sdict = NULL; char *sdict = NULL; migemo *mo; char *word = NULL; while (*++argv) { if (0) ; else if (!strcmp("--vim", *argv) || !strcmp("-v", *argv)) mode_vim = 1; else if (!strcmp("--emacs", *argv) || !strcmp("-e", *argv)) mode_emacs = 1; else if (!strcmp("--nonewline", *argv) || !strcmp("-n", *argv)) mode_nonewline = 1; else if (!strcmp("--dict", *argv) || !strcmp("-d", *argv)) { if (!argv[1]) missing_argument(prgname, *argv); dict = *++argv; } else if (!strcmp("--subdict", *argv) || !strcmp("-s", *argv) || !strcmp("--userdict", *argv) || !strcmp("-u", *argv)) { if (!argv[1]) missing_argument(prgname, *argv); if (subdict_count >= MIGEMO_SUBDICT_MAX) { fprintf(stderr, "ERROR: too many --subdict/userdict\n"); help(prgname, 1); } subdict[subdict_count++] = *++argv; } else if (!strcmp("--convert", *argv)) convert = 1; else if (!strcmp("--save", *argv)) { if (!argv[1]) missing_argument(prgname, *argv); convert = 1; save_sdict = *++argv; } else if (!strcmp("--sdict", *argv)) { if (!argv[1]) missing_argument(prgname, *argv); sdict = *++argv; } else if ((!strcmp("--word", *argv) || !strcmp("-w", *argv))) { if (!argv[1]) missing_argument(prgname, *argv); word = *++argv; } else if (!strcmp("--quiet", *argv) || !strcmp("-q", *argv)) mode_quiet = 1; else if (!strcmp("--help", *argv) || !strcmp("-h", *argv)) help(prgname, 0); else if (**argv == '-') unknown_option(prgname, *argv); } // Check dependencies between options. if (sdict) { if (dict || subdict_count > 0 || convert || save_sdict) { fprintf(stderr, "ERROR: --sdict conflicts with -d/s/u and " "--convert/save\n"); help(prgname, 1); } } // Load the main migemo dictionary if (sdict) { assure_file(sdict); mo = migemo_open_sdict(sdict); if (!word && !mode_quiet) printf("migemo_open_sdict(\"%s\")=%p\n", sdict, mo); if (!mo) { fprintf(stderr, "ERROR: failed to load static dictionary: %s\n", sdict); return 1; } } else if (dict) { assure_file(dict); mo = migemo_open(dict); if (!word && !mode_quiet) printf("migemo_open(\"%s\")=%p\n", dict, mo); if (!mo) { fprintf(stderr, "ERROR: failed to load dictionary: %s\n", dict); return 1; } } else { const char *found = NULL; mo = open_first_migemo(&found, default_dicts); if (!word && !mode_quiet) printf("migemo_open(\"%s\")=%p\n", found ? found : "(N/A)", mo); if (!mo) { fprintf(stderr, "ERROR: failed to load default dictionaries\n"); return 1; } } // Load sub-dictionaries if (subdict_count > 0) { for (int i = 0; i < subdict_count; ++i) { if (subdict[i] == NULL || subdict[i][0] == '\0') continue; assure_file(subdict[i]); int result = migemo_load(mo, MIGEMO_DICTID_MIGEMO, subdict[i]); if (!word && !mode_quiet) printf("migemo_load(%p, %d, \"%s\")=%d\n", mo, MIGEMO_DICTID_MIGEMO, subdict[i], result); } } // Convert to static dictionary if (convert) { if (migemo_switch_sdict(mo, MIGEMO_SDICT_RELEASE_MDICT) == 0) { fprintf(stderr, "ERROR: failed to convert the dictionary to sdict\n"); return 1; } if (!word && !mode_quiet) printf("converted to sdict\n"); if (save_sdict) { if (migemo_save_sdict(mo, save_sdict) == 0) { fprintf(stderr, "ERROR: failed to save sdict\n"); return 1; } if (!word && !mode_quiet) printf("sdict saved to: %s\n", save_sdict); } } // Configure operators for each editor. if (mode_vim) { migemo_set_operator(mo, MIGEMO_OPINDEX_OR, "\\|"); migemo_set_operator(mo, MIGEMO_OPINDEX_NEST_IN, "\\%("); migemo_set_operator(mo, MIGEMO_OPINDEX_NEST_OUT, "\\)"); if (!mode_nonewline) migemo_set_operator(mo, MIGEMO_OPINDEX_NEWLINE, "\\_s*"); } else if (mode_emacs) { migemo_set_operator(mo, MIGEMO_OPINDEX_OR, "\\|"); migemo_set_operator(mo, MIGEMO_OPINDEX_NEST_IN, "\\("); migemo_set_operator(mo, MIGEMO_OPINDEX_NEST_OUT, "\\)"); if (!mode_nonewline) migemo_set_operator(mo, MIGEMO_OPINDEX_NEWLINE, "\\s-*"); } if (word) { unsigned char *ans; ans = migemo_query(mo, word); if (ans) printf(mode_vim ? "%s" : "%s\n", ans); migemo_release(mo, ans); } else { if (!mode_quiet) printf("clock()=%f\n", (float)clock() / CLOCKS_PER_SEC); query_loop(mo, mode_quiet); } migemo_close(mo); return 0; } cmigemo-1.8.0/tools/index.md000066400000000000000000000016341524447636500157550ustar00rootroot00000000000000--- type: Directory Index title: "tools Index" description: "Contains the source programs for the cmigemo and romaji command-line tools and their CMake build rules." tags: [index] --- # Overview Holds the sources for the command-line tools built by the project (`cmigemo`, `romaji`) along with the CMake rules that define, link, and install them. # Directory Contents | File / Path | Type | Description | | :--- | :--- | :--- | | [CMakeLists.txt](./CMakeLists.txt) | Build Script | Defines and installs the `cmigemo` and `romaji` executables with their dictionary-directory compile definitions. | | [cmigemo.c](./cmigemo.c) | Source Code | Command-line driver that loads a migemo dictionary, accepts query options, and prints regexp expansion results. | | [romaji.c](./romaji.c) | Source Code | Interactive romaji-to-hiragana/katakana/hankaku/zenkaku conversion console. | # References - [Parent Directory](../index.md) cmigemo-1.8.0/tools/romaji.c000066400000000000000000000100401524447636500157400ustar00rootroot00000000000000// vim:set ts=8 sts=4 sw=4 tw=0 et: // // romaji_main.c - Romaji convert console. // // Author: MURAOKA Taro #include #include #include #include "charset.h" #include "romaji.h" #define ABOUT "romaji - Romaji converter" #ifndef DICTDIR # define DICTDIR "../../dict" #endif #ifndef DICT_ROMA2HIRA # define DICT_ROMA2HIRA (DICTDIR "/roma2hira.dat") #endif #ifndef DICT_HIRA2KATA # define DICT_HIRA2KATA (DICTDIR "/hira2kata.dat") #endif #ifndef DICT_HAN2ZEN # define DICT_HAN2ZEN (DICTDIR "/han2zen.dat") #endif #ifndef DICT_ZEN2HAN # define DICT_ZEN2HAN (DICTDIR "/zen2han.dat") #endif void query_one(romaji *rj, romaji *hira2kata, romaji *han2zen, romaji *zen2han, char *buf) { wordlist *hira = romaji_convert_all(rj, buf); for (wordlist *p = hira; p; p = wordlist_next(p)) { printf(" hira=%s\n", wordlist_word(p)); wordlist *kata = romaji_convert_all(hira2kata, wordlist_word(p)); for (wordlist *q = kata; q; q = wordlist_next(q)) { printf(" kata=%s\n", wordlist_word(q)); wordlist *han = romaji_convert_all(zen2han, wordlist_word(q)); for (wordlist *r = han; r; r = wordlist_next(r)) printf(" han=%s\n", wordlist_word(r)); wordlist_destroy(han); } wordlist_destroy(kata); } wordlist_destroy(hira); wordlist *zen = romaji_convert_all(han2zen, buf); for (wordlist *p = zen; p; p = wordlist_next(p)) printf(" zen=%s\n", wordlist_word(p)); wordlist_destroy(zen); } void query_loop(romaji *rj, romaji *hira2kata, romaji *han2zen, romaji *zen2han) { unsigned char buf[256]; while (!feof(stdin)) { printf("QUERY: "); if (!fgets(buf, sizeof(buf), stdin)) { printf("\n"); break; } // Replace LF with '\0'. If no LF is present, set the end of the buffer // to '\0' to ensure the string is null-terminated. int i = 0; while (i < sizeof(buf) - 1 && buf[i] != '\n' && buf[i] != '\0') i++; buf[i] = '\0'; query_one(rj, hira2kata, han2zen, zen2han, buf); } } static void help(char *prgname) { printf("\ %s \n\ \n\ USAGE: %s [OPTIONS]\n\ \n\ OPTIONS:\n\ -w --word Expand a and soon exit.\n\ -h --help Show this message.\n\ ", ABOUT, prgname); exit(0); } int main(int argc, char **argv) { char *word = NULL; char *prgname = argv[0]; romaji *rj = romaji_open(); romaji *hira2kata = romaji_open(); romaji *han2zen = romaji_open(); romaji *zen2han = romaji_open(); if (!rj || !hira2kata || !han2zen || !zen2han) { printf("failed to allocate memory for romaji\n"); return 1; } while (*++argv) { if (0) ; else if (argv[1] && (!strcmp("--word", *argv) || !strcmp("-w", *argv))) word = *++argv; else if (!strcmp("--help", *argv) || !strcmp("-h", *argv)) help(prgname); } CHARSET_PROC_CHAR2INT char2int = charset_utf8_char2int; // Detect charset if (strstr(DICT_ROMA2HIRA, "cp932")) char2int = charset_cp932_char2int; // Load romaji dictionaries. int retval = 0; retval = romaji_load(rj, DICT_ROMA2HIRA, char2int); printf("romaji_load(%s)=%d\n", DICT_ROMA2HIRA, retval); retval = romaji_load(hira2kata, DICT_HIRA2KATA, char2int); printf("romaji_load(%s)=%d\n", DICT_HIRA2KATA, retval); retval = romaji_load(han2zen, DICT_HAN2ZEN, char2int); printf("romaji_load(%s)=%d\n", DICT_HAN2ZEN, retval); retval = romaji_load(zen2han, DICT_ZEN2HAN, char2int); printf("romaji_load(%s)=%d\n", DICT_ZEN2HAN, retval); if (word) query_one(rj, hira2kata, han2zen, zen2han, word); else query_loop(rj, hira2kata, han2zen, zen2han); if (zen2han) romaji_close(zen2han); if (han2zen) romaji_close(han2zen); if (hira2kata) romaji_close(hira2kata); if (rj) romaji_close(rj); return 0; } cmigemo-1.8.0/wasm/000077500000000000000000000000001524447636500141275ustar00rootroot00000000000000cmigemo-1.8.0/wasm/.gitignore000066400000000000000000000000461524447636500161170ustar00rootroot00000000000000migemo_wasm.js migemo_wasm.wasm dict/ cmigemo-1.8.0/wasm/CMakeLists.txt000066400000000000000000000025541524447636500166750ustar00rootroot00000000000000get_target_property(MIGEMO_SOURCES migemo_objects SOURCES) get_target_property(MIGEMO_DIR migemo_objects SOURCE_DIR) list(TRANSFORM MIGEMO_SOURCES PREPEND "${MIGEMO_DIR}/" REGEX "^[^/]") #------------------------------------------------------------------------------ add_executable(migemo_wasm ${MIGEMO_SOURCES}) target_include_directories( migemo_wasm PRIVATE ${CMAKE_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/src/include) set_target_properties( migemo_wasm PROPERTIES OUTPUT_NAME "migemo_wasm" SUFFIX ".js") target_link_options( migemo_wasm PRIVATE "--js-library" "${CMAKE_CURRENT_SOURCE_DIR}/library.js" "-sEXPORTED_FUNCTIONS=['_migemo_open','_migemo_close','_migemo_query','_migemo_release','_migemo_load','_migemo_is_enable','_migemo_set_escape_chars','_migemo_version','_malloc','_free']" "-sEXPORTED_RUNTIME_METHODS=['FS','ccall','cwrap','UTF8ToString','allocate','ALLOC_NORMAL']" "-sMODULARIZE=1" "-sEXPORT_NAME='createMigemoModule'" "-sEXPORT_ES6=1" "-sENVIRONMENT=web,node" "-sALLOW_MEMORY_GROWTH=1") add_custom_command( TARGET migemo_wasm POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $/migemo_wasm.js ${CMAKE_CURRENT_SOURCE_DIR}/migemo_wasm.js COMMAND ${CMAKE_COMMAND} -E copy $/migemo_wasm.wasm ${CMAKE_CURRENT_SOURCE_DIR}/migemo_wasm.wasm) cmigemo-1.8.0/wasm/demo.html000066400000000000000000000036551524447636500157520ustar00rootroot00000000000000

C/Migemo WASM

Notice: Load this page via an HTTP server (e.g., npx serve ., or python -m http.server). Fetching dictionary files directly via file:// protocol will fail due to browser security restrictions.
  1. Open developer's console (Ctrl + Shift + j)
  2. Run migemo.version(), then you'll get version of C/Migemo
  3. Run migemo.query('akas'), then you'll get a RegExp object:
    /([暴灯証證]|akas|あか[さしすせそっ]|アカ[サシスセソッ]|垢擦り|明[石科]|絳し|赤([司坂崎潮白碕線芝錆]|っ恥|信号|新聞|水晶|瀬川)|akas|アカ[ッサシスセソ])/
  4. Run migemo.query('asak'), then you'll get a RegExp object:
    /(asak|あさ[かきくけこっ子]|アサ[カキクケコッ]|亜抄子|安(積|佐北)|明後日|朝([倉加子川影明霞風]|っ(腹|ぱら)|香宮)|浅[倉口子川草香]|麻[倉子木]|asak|アサ[ッカキクケコ])/
cmigemo-1.8.0/wasm/index.js000066400000000000000000000174561524447636500156110ustar00rootroot00000000000000let moduleInstance = null; let migemoInstance = 0; /** * Gets the Emscripten module factory function dynamically. * @returns {Promise} */ async function getModuleFactory() { if (typeof globalThis !== 'undefined' && typeof globalThis.createMigemoModule === 'function') { return globalThis.createMigemoModule; } try { const mod = await import('./migemo_wasm.js'); return mod.default || mod.createMigemoModule || mod; } catch (e) { try { const mod = await import('../build-wasm/bin/migemo_wasm.js'); return mod.default || mod.createMigemoModule || mod; } catch (e2) { try { const mod = await import('../build/bin/migemo_wasm.js'); return mod.default || mod.createMigemoModule || mod; } catch (e3) { throw new Error("Unable to locate createMigemoModule factory function. Ensure migemo_wasm.js is built."); } } } } /** * Normalizes user options into a standard object structure. * @param {Object|string|Uint8Array|ArrayBuffer} options * @returns {Object} */ function normalizeOptions(options) { if (typeof options === 'string') { return { dictPath: options }; } if (options instanceof Uint8Array || options instanceof ArrayBuffer) { return { dictData: options }; } if (typeof options === 'object' && options !== null) { return { ...options }; } return {}; } /** * Ensures directory structure exists in Emscripten Virtual File System. * @param {Object} FS * @param {string} filePath */ function ensureDirectory(FS, filePath) { const parts = filePath.split('/').filter(Boolean); let currentPath = ''; for (let i = 0; i < parts.length - 1; i++) { currentPath += '/' + parts[i]; try { FS.mkdir(currentPath); } catch (e) { // Ignore EEXIST } } } /** * Initializes C/Migemo WebAssembly module and loads dictionary. * @param {Object|string|Uint8Array|ArrayBuffer} options * @returns {Promise} Returns the C pointer singleton for the Migemo instance. */ export async function init(options = {}) { const opts = normalizeOptions(options); // Close previous C instance if active to prevent memory leaks if (migemoInstance) { close(); } // Load Emscripten module if not yet loaded if (!moduleInstance) { let factory = opts.createMigemoModule; if (!factory) { factory = await getModuleFactory(); } const defaultModuleOpts = { locateFile: (path, scriptDirectory) => { if (scriptDirectory) return scriptDirectory + path; return path; } }; moduleInstance = await factory({ ...defaultModuleOpts, ...opts.moduleOpts }); } const FS = moduleInstance.FS; let dictPath = opts.dictPath || null; // Handle options.dictData if (opts.dictData) { const data = opts.dictData instanceof Uint8Array ? opts.dictData : new Uint8Array(opts.dictData); dictPath = opts.dictPath || '/migemo-dict'; ensureDirectory(FS, dictPath); try { FS.unlink(dictPath); } catch (e) { // Ignore ENOENT } if (typeof FS.createDataFile === 'function') { const lastSlash = dictPath.lastIndexOf('/'); const parentDir = lastSlash > 0 ? dictPath.substring(0, lastSlash) : '/'; const fileName = lastSlash >= 0 ? dictPath.substring(lastSlash + 1) : dictPath; try { FS.createDataFile(parentDir, fileName, data, true, true, true); } catch (e) { // Fallback to FS.writeFile FS.writeFile(dictPath, data); } } else { FS.writeFile(dictPath, data); } } // Handle options.subdicts if (opts.subdicts && typeof opts.subdicts === 'object') { const baseDir = dictPath ? (dictPath.substring(0, dictPath.lastIndexOf('/')) || '/') : '/'; const standardNames = { roma2hira: 'roma2hira.dat', hira2kata: 'hira2kata.dat', han2zen: 'han2zen.dat', zen2han: 'zen2han.dat' }; for (const [key, val] of Object.entries(opts.subdicts)) { if (val instanceof Uint8Array || val instanceof ArrayBuffer) { const fileName = standardNames[key] || (key.endsWith('.dat') ? key : `${key}.dat`); const subPath = baseDir === '/' ? `/${fileName}` : `${baseDir}/${fileName}`; const subData = val instanceof Uint8Array ? val : new Uint8Array(val); ensureDirectory(FS, subPath); try { FS.unlink(subPath); } catch (e) {} FS.writeFile(subPath, subData); } } } const migemoOpen = moduleInstance.cwrap('migemo_open', 'number', ['string']); migemoInstance = migemoOpen(dictPath); if (!migemoInstance) { throw new Error(`Failed to initialize Migemo with dictPath: ${dictPath}`); } const migemoSetEscapeChars = moduleInstance.cwrap('migemo_set_escape_chars', 'number', ['number', 'string']); const jsEscapeChars = '\\.*+?^${}()|[]/'; migemoSetEscapeChars(migemoInstance, jsEscapeChars); return migemoInstance; } /** * Converts input query string into a JavaScript RegExp object. * @param {string} pattern * @returns {RegExp} */ export function query(pattern) { if (!migemoInstance || !moduleInstance) { throw new Error("Migemo is not initialized. Call init() first."); } const migemoQuery = moduleInstance.cwrap('migemo_query', 'number', ['number', 'string']); const migemoRelease = moduleInstance.cwrap('migemo_release', 'void', ['number', 'number']); const resPtr = migemoQuery(migemoInstance, pattern); if (!resPtr) { return new RegExp(pattern); } const resStr = moduleInstance.UTF8ToString(resPtr); migemoRelease(migemoInstance, resPtr); return new RegExp(resStr); } /** * Closes and frees the active Migemo instance pointer. */ export function close() { if (migemoInstance && moduleInstance) { const migemoClose = moduleInstance.cwrap('migemo_close', 'void', ['number']); migemoClose(migemoInstance); migemoInstance = 0; } } /** * Checks whether dictionary is loaded and enabled. * @returns {boolean} */ export function isEnable() { if (!migemoInstance || !moduleInstance) return false; const migemoIsEnable = moduleInstance.cwrap('migemo_is_enable', 'number', ['number']); return Boolean(migemoIsEnable(migemoInstance)); } /** * Loads an additional dictionary file into the active instance. * @param {number} dictId * @param {string} dictPath * @returns {number} */ export function load(dictId, dictPath) { if (!migemoInstance || !moduleInstance) { throw new Error("Migemo is not initialized. Call init() first."); } const migemoLoad = moduleInstance.cwrap('migemo_load', 'number', ['number', 'number', 'string']); return migemoLoad(migemoInstance, dictId, dictPath); } /** * Sets custom characters to escape in generated regular expressions. * @param {string|null} chars String of characters to escape, or null to restore default. * @returns {number} 0 on success, non-zero on error. */ export function setEscapeChars(chars) { if (!migemoInstance || !moduleInstance) { throw new Error("Migemo is not initialized. Call init() first."); } const migemoSetEscapeChars = moduleInstance.cwrap('migemo_set_escape_chars', 'number', ['number', 'string']); return migemoSetEscapeChars(migemoInstance, chars); } /** * Returns the version string of the C/Migemo library. * @returns {string} Version string (e.g., "1.6.1") */ export function version() { if (!moduleInstance) { throw new Error("Migemo is not initialized. Call init() first."); } const migemoVersion = moduleInstance.cwrap('migemo_version', 'string', []); return migemoVersion(); } /** * Returns the underlying Emscripten module instance. * @returns {Object|null} */ export function getModule() { return moduleInstance; } /** * Returns the active C Migemo pointer singleton. * @returns {number} */ export function getInstance() { return migemoInstance; } export default { init, query, close, isEnable, load, setEscapeChars, version, getModule, getInstance }; cmigemo-1.8.0/wasm/index.md000066400000000000000000000036461524447636500155710ustar00rootroot00000000000000--- type: Directory Index title: "wasm Index" description: "WebAssembly build of C/Migemo with its JavaScript API wrapper, demo page, dictionaries, and test files." tags: [index] --- # Overview This directory contains the Emscripten/WebAssembly port of C/Migemo: a CMake build definition, the compiled `.js`/`.wasm` artifacts, a high-level JavaScript API, a browser demo page, the dictionary files, and a small test harness. # Directory Contents | File / Path | Type | Description | | :--- | :--- | :--- | | [CMakeLists.txt](./CMakeLists.txt) | CMake | Builds the `migemo_wasm` Emscripten executable that exports the migemo API functions and copies the generated `.js`/`.wasm` artifacts back into this directory. | | [demo.html](./demo.html) | HTML | Demo page that loads the WASM module from local dictionary files over HTTP and shows interactive browser-console usage examples. | | [dict/](./dict/) | Directory | Holds the main dictionaries (`migemo-dict`, `migemo-dict-zh`) and the `roma2hira.dat`, `hira2kata.dat`, `han2zen.dat`, `zen2han.dat` sub-dictionaries fetched by the demo. | | [index.js](./index.js) | JavaScript | High-level API that loads the Emscripten module, writes dictionary data into the virtual filesystem, and exposes `init`, `query`, `close`, `version`, and related functions. | | [library.js](./library.js) | JavaScript | Emscripten `--js-library` file that adds `$ALLOC_NORMAL` and `$allocate` helpers for copying memory into the WASM heap. | | [migemo_wasm.js](./migemo_wasm.js) | Build Artifact | Emscripten-generated JS loader that exposes the `createMigemoModule` factory for the compiled module. | | [migemo_wasm.wasm](./migemo_wasm.wasm) | Build Artifact | Compiled WebAssembly binary of the C/Migemo library consumed by `migemo_wasm.js`. | | [test/](./test/) | Directory | Contains `index.html` and `test.js`, a lightweight browser-based test harness for the WASM module. | # References - [Parent Directory](../index.md) cmigemo-1.8.0/wasm/library.js000066400000000000000000000004711524447636500161330ustar00rootroot00000000000000addToLibrary({ $ALLOC_NORMAL: 0, $allocate: function(slab, allocator) { var ptr = _malloc(slab.length); if (typeof HEAPU8 !== 'undefined') { HEAPU8.set(slab, ptr); } else if (typeof Module !== 'undefined' && Module.HEAPU8) { Module.HEAPU8.set(slab, ptr); } return ptr; } }); cmigemo-1.8.0/wasm/test/000077500000000000000000000000001524447636500151065ustar00rootroot00000000000000cmigemo-1.8.0/wasm/test/index.html000066400000000000000000000102661524447636500171100ustar00rootroot00000000000000 C/Migemo WebAssembly Demo & Verification

C/Migemo WebAssembly Demo

1. Initialization

Status: Not Initialized

2. Incremental Search Query

Generated RegExp:

N/A

Test Matches:

-
cmigemo-1.8.0/wasm/test/test.js000066400000000000000000000117211524447636500164250ustar00rootroot00000000000000import fs from 'node:fs'; import path from 'node:path'; import assert from 'node:assert/strict'; import { fileURLToPath } from 'node:url'; import { init, query, close, isEnable, load, version, getModule, getInstance } from '../index.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const rootDir = path.resolve(__dirname, '../../'); async function runTests() { console.log('--- Starting WASM Migemo Tests ---'); // Load sample dictionary files const dictDataPath = path.join(rootDir, 'test/_testdata/migemo-dict'); const roma2hiraPath = path.join(rootDir, 'dict/roma2hira.dat'); const hira2kataPath = path.join(rootDir, 'dict/hira2kata.dat'); const han2zenPath = path.join(rootDir, 'dict/han2zen.dat'); const zen2hanPath = path.join(rootDir, 'dict/zen2han.dat'); const dictBuffer = fs.readFileSync(dictDataPath); const roma2hiraBuf = fs.readFileSync(roma2hiraPath); const hira2kataBuf = fs.readFileSync(hira2kataPath); const han2zenBuf = fs.readFileSync(han2zenPath); const zen2hanBuf = fs.readFileSync(zen2hanPath); // Test 1: Initialize with dictData Buffer and subdicts Buffers console.log('Test 1: Initialize with dictData Buffer & subdicts'); const instance1 = await init({ dictData: dictBuffer, dictPath: '/test-dict/migemo-dict', subdicts: { roma2hira: roma2hiraBuf, hira2kata: hira2kataBuf, han2zen: han2zenBuf, zen2han: zen2hanBuf } }); assert.ok(instance1 > 0, 'Instance pointer should be a positive number'); assert.strictEqual(getInstance(), instance1, 'getInstance() should match active handle'); assert.strictEqual(isEnable(), true, 'isEnable() should be true'); // Test 2: Query API returning RegExp console.log('Test 2: Query API returning RegExp'); const rx1 = query('ak'); assert.ok(rx1 instanceof RegExp, 'query() must return a native RegExp instance'); console.log('Query "ak" -> RegExp:', rx1.toString()); // Verify regex behavior on Japanese and Romaji strings assert.ok(rx1.test('赤'), 'RegExp should match "赤"'); assert.ok(rx1.test('ak'), 'RegExp should match "ak"'); const rx2 = query('n'); assert.ok(rx2 instanceof RegExp, 'query("n") must return a native RegExp instance'); console.log('Query "n" -> RegExp:', rx2.toString()); assert.ok(rx2.test('なにぬねの'), 'RegExp should match "なにぬねの"'); // Test 3: Check exported runtime methods on module console.log('Test 3: Verify Exported Runtime Utilities and C APIs'); const mod = getModule(); assert.ok(mod, 'Module instance should be defined'); assert.ok(typeof mod.FS === 'object', 'FS should be exported on module'); assert.ok(typeof mod.ccall === 'function', 'ccall should be exported on module'); assert.ok(typeof mod.cwrap === 'function', 'cwrap should be exported on module'); assert.ok(typeof mod.UTF8ToString === 'function', 'UTF8ToString should be exported on module'); assert.ok(typeof mod.allocate === 'function', 'allocate should be exported on module'); assert.ok(mod.ALLOC_NORMAL !== undefined, 'ALLOC_NORMAL should be exported on module'); assert.ok(typeof mod._migemo_open === 'function', '_migemo_open C API should be exported'); assert.ok(typeof mod._migemo_close === 'function', '_migemo_close C API should be exported'); assert.ok(typeof mod._migemo_query === 'function', '_migemo_query C API should be exported'); assert.ok(typeof mod._migemo_release === 'function', '_migemo_release C API should be exported'); assert.ok(typeof mod._migemo_load === 'function', '_migemo_load C API should be exported'); assert.ok(typeof mod._migemo_version === 'function', '_migemo_version C API should be exported'); const ver = version(); assert.ok(typeof ver === 'string' && ver.length > 0, 'version() should return a non-empty string'); console.log('Version:', ver); // Test 4: Re-initialization (Singleton Lifecycle & dictPath input) console.log('Test 4: Re-initialization & Virtual FS Path'); // Write files to virtual FS directly const virtualPath = '/virtual/opfs/migemo-dict'; mod.FS.mkdirTree('/virtual/opfs'); mod.FS.writeFile(virtualPath, dictBuffer); mod.FS.writeFile('/virtual/opfs/roma2hira.dat', roma2hiraBuf); const instance2 = await init({ dictPath: virtualPath }); assert.ok(instance2 > 0, 'New instance pointer should be valid'); assert.strictEqual(getInstance(), instance2, 'getInstance() should equal instance2'); const rx3 = query('ak'); assert.ok(rx3.test('明'), 'Query using re-initialized dictPath should match "明"'); // Test 5: Close API console.log('Test 5: Close API'); close(); assert.strictEqual(getInstance(), 0, 'getInstance() should be 0 after close()'); assert.strictEqual(isEnable(), false, 'isEnable() should be false after close()'); assert.throws(() => query('ak'), /Migemo is not initialized/, 'query() should throw if not initialized'); console.log('All WASM Migemo tests passed successfully!'); } runTests().catch(err => { console.error('Test failed:', err); process.exit(1); });