- Notifications
You must be signed in to change notification settings - Fork3
A Simple PHP Roman Numerals Library
License
wandersonwhcr/romans
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
A Simple PHP Roman Numerals Library
This library includes a simple couple of filters to convert astring
withRoman number to anint
that represents the input as decimal and decimalint
to astring
with Roman number as result.
useRomans\Filter\RomanToInt;$filter =newRomanToInt();$result =$filter->filter('MCMXCIX');// 1999
useRomans\Filter\IntToRoman;$filter =newIntToRoman();$result =$filter->filter(1999);// MCMXCIX
This package usesComposer as defaultrepository. You can install it adding the name of package inrequire
sectionofcomposer.json
, pointing to the last stable version.
{"require": {"wandersonwhcr/romans":"^1.0" }}
Also, Romans uses Semantic Versioning. The following package versions supportthese PHP releases:
- Romans
1.0.*
: PHP^7.0
(Augustus) - Romans
1.1.*
: PHP^7.0
(Tiberius) - Romans
1.2.*
: PHP>=7.4
(Caligula) - Romans
1.3.*
: PHP>=7.4
(Claudius) - Romans
1.4.*
: PHP>=7.4
(Nero) - Romans
1.5.*
: PHP>=8.0
(Galba)
This library can be used as dependency for projects, making integrations withlibraries or frameworks easier. If you want to add more items in this list,please, open an issue or create a pull request, adding your projectalphabetically.
- Illuminate Romans: Laravel Illuminate Romans Integration
- Kirby Romans: Kirby CMS Integration
- Laminas Romans: Laminas Project Romans Integration
- Plates Romans Extension: Plates Extension
- Twig Roman Numerals Extension: Twig Extension (Symfony, WordPress + Timber)
Zend Romans: Zend Framework Romans IntegrationDEPRECATED
TheRomans
package uses a Lexer-Parser approach and a Deterministic FiniteAutomaton (DFA) to convert Roman number toint
, using a Grammar Token library.
useRomans\Grammar\Grammar;useRomans\Lexer\Lexer;useRomans\Parser\Parser;$grammar =newGrammar();$lexer =newLexer($grammar);$parser =newParser($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
The filterRomanToInt
uses Lexer to tokenize the input and Parser to build theint
number. When errors are found, the Lexer or Parser throw Exceptions tonotify the problem with a specific code.
useRomans\Filter\RomanToInt;useRomans\Lexer\ExceptionasLexerException;useRomans\Parser\ExceptionasParserException;$filter =newRomanToInt();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)}
You can use this structure to validate Roman numbers, adding atry..catchblock to check if$input
is valid. Also, you can validate if anint
can befiltered to Roman using anIntToRoman
filter.
useRomans\Filter\IntToRoman;useRomans\Filter\ExceptionasFilterException;$filter =newIntToRoman();try {$filter->filter($input);}catch (FilterException$e) {// Invalid Integer (< 0) (FilterException::INVALID_INTEGER)}
The zero value is represented asstring
"N"
, the initial ofnulla ornihil, the Latin word for "nothing" (see references).
useRomans\Filter\RomanToInt;useRomans\Filter\IntToRoman;$filter =newRomanToInt();$result =$filter->filter('N');// 0 (Zero)$filter =newIntToRoman();$result =$filter->filter(0);// N
This package usesPSR-6 Caching Interfaceto improve execution, mainly over loops (likewhile
orforeach
) using cachelibraries. Any PSR-6 implementation can be used and we suggestSymfony Cache package.
useRomans\Filter\IntToRoman;useRomans\Filter\RomanToInt;useSymfony\Component\Cache\Adapter\ArrayAdapter;$cache =newArrayAdapter();$filter =newRomanToInt();$filter->setCache($cache);$result =$filter->filter('MCMXCIX');// 1999$result =$filter->filter('MCMXCIX');// 1999 (from cache)$filter =newIntToRoman();$filter->setCache($cache);$result =$filter->filter(1999);// MCMXCIX$result =$filter->filter(1999);// MCMXCIX (from cache)
You can use Docker Compose to build an image and run a container to develop andtest this package.
docker-compose builddocker-compose run --rm romans composer installdocker-compose run --rm romans composertest
This section describes techniques used by this package to convert Roman numbersintoint
and vice-versa.
A Lexer-Parser approach was chosen because the validating and reading of Romannumbers are more simplified: the Lexer is responsible for reading and transformthe input into tokens, validating content at char level; and the Parser isresponsible for transform tokens into numbers, validating content at positionlevel and converting toint
through a DFA.
Wikipedia says that "lexical analysis is the process of converting a sequence ofcharacters into a sequence of tokens", that "is a structure representing alexeme that explicity indicates its categorization for the purpose of parsing".Even, Wikipedia says that "parsing or syntax analysis is the process ofanalysing symbols conforming to the rules of a formal grammar".
This structure makes easier the development of a structure responsible to readan inputstring
, converting it to another structure according to specificcharset and its position inside input.
A DFA was developed to check if astring
with Roman number is valid. Thistechnique was choiced because other implementations simply convert the inputwithout checking rules, like four chars sequentially.
The current automaton definition is declared below.
M = (Q, Σ, δ, q0, F)Q = { a, b, c, d, e, f, g, y, z }Σ = { I, V, X, L, C, D, M, N }q0 = gF = { z }z -> εy -> $za -> y | Iy | IIy | IIIyb -> a | IVy | Va | IXyc -> b | Xb | XXb | XXXbd -> c | XLb | Lc | XCbe -> d | Cd | CCd | CCCdf -> e | CDd | De | CMdg -> f | Ny | Mg
- Rapid Tables:How to Convert Roman Numerals to Numbers
- Wikipedia:Zero in Roman Numerals
- Wikipedia:Lexical Analysis
- Wikipedia:Parsing
- Wikipedia:Deterministic Finite Automaton
This package is opensource and available under MIT license described inLICENSE.
About
A Simple PHP Roman Numerals Library