ICU Parser is a PHP 8.2+ library that treats ICU MessageFormat strings as code.
Unlike simple wrappers around MessageFormatter, ICU Parser implements a compiler-style pipeline (Lexer β Parser β AST) and provides static analysis for ICU messages.
This architecture allows for advanced tooling:
- Parsing: Parse ICU messages into a structured, typed AST.
- Validation: Detect common syntax and semantic errors.
- Type Inference: Extract parameter types from messages.
- Linting: Validate translation catalogs across multiple locales.
- Analysis: Syntax highlighting, pretty-formatting, and debugging.
Built for validation, analysis, and robust tooling in i18n workflows.
If you are new to ICU Parser, start with the Quick Start Guide. If you want a short overview, see docs/overview.md.
# Install the library
composer require yoeunes/icu-parser
# Optional: improve locale support
composer require symfony/intl
# Try the CLI
bin/icu lint translations/Requirements: PHP 8.2+ and ext-intl (the MessageFormatter class).
- ποΈ Deep Parsing: Parse ICU MessageFormat strings into a structured, typed AST.
- π Type Inference: Extract parameter types and their expected formats from messages.
- β Validation: Detect syntax errors, missing plural categories, and semantic issues.
- π Catalog Analysis: Analyze translation files for consistency and completeness.
- π¨ Syntax Highlighting: Colorize ICU messages for better readability.
- π§ Visitor API: A flexible API for building custom ICU analysis tools.
- π οΈ CLI Tooling: Lint, audit, debug, and highlight messages from the command line.
ICU Parser is a static analysis tool, not a runtime formatter.
- Parse: Converts ICU MessageFormat strings into an AST.
- Validate: Checks for syntax errors and common semantic issues.
- Analyze: Infers types, formats messages, and highlights syntax.
- Lint: Scans translation files for errors and inconsistencies.
- Runtime Formatting: It does not format messages at runtime. Use
MessageFormatterfromext-intlfor that. - Complete ICU Coverage: It supports the most common ICU constructs but does not cover every edge case or locale-specific nuance.
- MessageFormat 2 (MF2): It targets ICU MessageFormat 1.x only.
- Well-tested behavior: Parsing, AST structure, error offsets, and syntax validation for the supported ICU syntax.
- Heuristic: Semantic validation is conservative and may miss edge cases. Treat it as a helpful tool, not a complete validator.
- Context matters: Locale-specific rules (e.g., plural categories) vary. Use
symfony/intlfor better locale support.
IcuParser::parse()converts an ICU string into an AST.- The lexer produces a token stream.
- The parser builds an AST (
MessageNode). - Visitors walk the AST to validate, infer types, highlight, or format.
For the full architecture, see docs/ARCHITECTURE.md.
# Parse and validate a message
bin/icu debug "{count, plural, one {# item} other {# items}}"
# Highlight a message
bin/icu highlight "{name}, you have {count, number} items"
# Lint translation files
bin/icu lint translations/
# Audit translation catalogs
bin/icu audit translations/use IcuParser\IcuParser;
use IcuParser\Validation\SemanticValidator;
use IcuParser\Highlight\HighlightTheme;
use IcuParser\Type\ParameterType;
$parser = new IcuParser();
// Parse a message into AST
$ast = $parser->parse('Hello {name}, you have {count, plural, one {# item} other {# items}}');
// Infer parameter types
$types = $parser->infer('{count, number} {date, date, short}')->all();
// Returns: ['count' => ParameterType::NUMBER, 'date' => ParameterType::DATETIME]
// Validate semantics
$validator = new SemanticValidator();
$result = $validator->validate($ast, 'Hello {name}', 'en');
if (!$result->isValid()) {
foreach ($result->getErrors() as $error) {
echo $error->getMessage() . "\n";
}
}
// Format for readability
$pretty = $parser->format('{gender, select, male {He} other {They}}');
// Output:
// {gender, select,
// male {He}
// other {They}
// }
// Highlight syntax
$highlighted = $parser->highlight('{count, number}', HighlightTheme::ansi());ICU Parser integrates with common PHP tooling:
- Symfony bundle: See docs/overview.md
- PHPStan: PHPStan rule (early/experimental)
- Twig: Twig extractor (used by the audit command; requires Twig)
- GitHub Actions: Use
bin/icu lintin your CI pipeline
Start here:
- Quick Start - Get started in a few minutes
- Overview - Scope and capabilities
- Usage Guide - Detailed API usage
- ICU Support - Supported constructs
Key references:
- Architecture - Internal design
- Formatting - Formatting and highlighting
Contributions are welcome! See CONTRIBUTING.md to get started.
# Set up development environment
composer install
# Run tests
composer phpunit
# Check code style
composer phpcs
# Run static analysis
composer phpstan
# Run full lint (includes all of the above)
composer lintReleased under the MIT License.
If you run into issues or have questions, please open an issue on GitHub: https://github.com/yoeunes/icu-parser/issues.