Une bibliothèque simple de chiffres romains PHP
Cette bibliothèque comprend quelques filtres simples pour convertir une string
avec un nombre romain en un int
qui représente l'entrée sous forme décimale et int
décimal en une string
avec un nombre romain comme résultat.
use Romans Filter RomanToInt ;
$ filter = new RomanToInt ();
$ result = $ filter -> filter ( ' MCMXCIX ' ); // 1999
use Romans Filter IntToRoman ;
$ filter = new IntToRoman ();
$ result = $ filter -> filter ( 1999 ); // MCMXCIX
Ce package utilise Composer comme référentiel par défaut. Vous pouvez l'installer en ajoutant le nom du package dans la section require
de composer.json
, pointant vers la dernière version stable.
{
"require" : {
"wandersonwhcr/romans" : " ^1.0 "
}
}
De plus, Romans utilise le versioning sémantique. Les versions de package suivantes prennent en charge ces versions PHP :
1.0.*
: PHP ^7.0
(Auguste)1.1.*
: PHP ^7.0
(Tibère)1.2.*
: PHP >=7.4
(Caligula)1.3.*
: PHP >=7.4
(Claudius)1.4.*
: PHP >=7.4
(Néron)1.5.*
: PHP >=8.0
(Galba) Cette bibliothèque peut être utilisée comme dépendance pour des projets, facilitant ainsi les intégrations avec des bibliothèques ou des frameworks. Si vous souhaitez ajouter d'autres éléments à cette liste, veuillez ouvrir un ticket ou créer une pull request, en ajoutant votre projet par ordre alphabétique.
Le package Romans
utilise une approche Lexer-Parser et un automate fini déterministe (DFA) pour convertir le nombre romain en int
, à l'aide d'une bibliothèque de jetons de grammaire.
use Romans Grammar Grammar ;
use Romans Lexer Lexer ;
use Romans Parser Parser ;
$ grammar = new Grammar ();
$ lexer = new Lexer ( $ grammar );
$ parser = new Parser ( $ grammar );
$ tokens = $ lexer -> tokenize ( ' MCMXCIX ' );
/*
$tokens = [
0 => 'M' // Grammar::T_M
1 => 'C', // Grammar::T_C
2 => 'M', // Grammar::T_M
3 => 'X', // Grammar::T_X
4 => 'C', // Grammar::T_C
5 => 'I', // Grammar::T_I
6 => 'X', // Grammar::T_X
];
*/
$ result = $ parser -> parse ( $ tokens ); // 1999
Le filtre RomanToInt
utilise Lexer pour tokeniser l'entrée et Parser pour construire le numéro int
. Lorsque des erreurs sont détectées, le Lexer ou l'analyseur lève des exceptions pour signaler le problème avec un code spécifique.
use Romans Filter RomanToInt ;
use Romans Lexer Exception as LexerException ;
use Romans Parser Exception as ParserException ;
$ filter = new RomanToInt ();
try {
$ filter -> filter ( $ input );
} catch ( LexerException $ e ) {
// Unknown Token (LexerException::UNKNOWN_TOKEN)
} catch ( ParserException $ e ) {
// Invalid Token Type (Not String) (ParserException::INVALID_TOKEN_TYPE)
// Unknown Token (ParserException::UNKNOWN_TOKEN)
// Invalid Roman (ParserException::INVALID_ROMAN)
}
Vous pouvez utiliser cette structure pour valider les nombres romains, en ajoutant un bloc try..catch pour vérifier si $input
est valide. En outre, vous pouvez valider si un int
peut être filtré en Roman à l'aide d'un filtre IntToRoman
.
use Romans Filter IntToRoman ;
use Romans Filter Exception as FilterException ;
$ filter = new IntToRoman ();
try {
$ filter -> filter ( $ input );
} catch ( FilterException $ e ) {
// Invalid Integer (< 0) (FilterException::INVALID_INTEGER)
}
La valeur zéro est représentée par string
"N"
, l'initiale de nulla ou nihil , le mot latin pour "rien" (voir références).
use Romans Filter RomanToInt ;
use Romans Filter IntToRoman ;
$ filter = new RomanToInt ();
$ result = $ filter -> filter ( ' N ' ); // 0 (Zero)
$ filter = new IntToRoman ();
$ result = $ filter -> filter ( 0 ); // N
Ce package utilise l'interface de mise en cache PSR-6 pour améliorer l'exécution, principalement sur des boucles (comme while
ou foreach
) à l'aide de bibliothèques de cache. N'importe quelle implémentation PSR-6 peut être utilisée et nous suggérons le package Symfony Cache.
use Romans Filter IntToRoman ;
use Romans Filter RomanToInt ;
use Symfony Component Cache Adapter ArrayAdapter ;
$ cache = new ArrayAdapter ();
$ filter = new RomanToInt ();
$ filter -> setCache ( $ cache );
$ result = $ filter -> filter ( ' MCMXCIX ' ); // 1999
$ result = $ filter -> filter ( ' MCMXCIX ' ); // 1999 (from cache)
$ filter = new IntToRoman ();
$ filter -> setCache ( $ cache );
$ result = $ filter -> filter ( 1999 ); // MCMXCIX
$ result = $ filter -> filter ( 1999 ); // MCMXCIX (from cache)
Vous pouvez utiliser Docker Compose pour créer une image et exécuter un conteneur pour développer et tester ce package.
docker-compose build
docker-compose run --rm romans composer install
docker-compose run --rm romans composer test
Cette section décrit les techniques utilisées par ce package pour convertir les nombres romains en int
et vice-versa.
Une approche Lexer-Parser a été choisie car la validation et la lecture des nombres romains sont plus simplifiées : le Lexer est responsable de la lecture et de la transformation de l'entrée en jetons, validant le contenu au niveau des caractères ; et l'analyseur est chargé de transformer les jetons en nombres, de valider le contenu au niveau de la position et de le convertir en int
via un DFA.
Wikipédia dit que « l'analyse lexicale est le processus de conversion d'une séquence de caractères en une séquence de jetons », c'est-à-dire « une structure représentant un lexème qui indique explicitement sa catégorisation à des fins d'analyse ». Même Wikipédia dit que « l'analyse syntaxique ou syntaxique est le processus d'analyse de symboles conformes aux règles d'une grammaire formelle ».
Cette structure facilite le développement d'une structure chargée de lire une string
d'entrée, en la convertissant en une autre structure en fonction d'un jeu de caractères spécifique et de sa position dans l'entrée.
Un DFA a été développé pour vérifier si une string
avec un numéro romain est valide. Cette technique a été choisie car d'autres implémentations convertissent simplement l'entrée sans vérifier les règles, comme quatre caractères séquentiellement.
La définition actuelle de l'automate est déclarée ci-dessous.
M = (Q, Σ, δ, q0, F)
Q = { a, b, c, d, e, f, g, y, z }
Σ = { I, V, X, L, C, D, M, N }
q0 = g
F = { z }
z -> ε
y -> $z
a -> y | Iy | IIy | IIIy
b -> a | IVy | Va | IXy
c -> b | Xb | XXb | XXXb
d -> c | XLb | Lc | XCb
e -> d | Cd | CCd | CCCd
f -> e | CDd | De | CMd
g -> f | Ny | Mg
Ce package est open source et disponible sous licence MIT décrite dans LICENSE.