diff --git a/docs/design-date-parser.md b/docs/design-date-parser.md index 189a977a9..9706dce5b 100644 --- a/docs/design-date-parser.md +++ b/docs/design-date-parser.md @@ -2,12 +2,13 @@ ## Status -Proposed — replaces both `do_convtime()` and `ParseDate()` with a -single Ragel -G2 scanner + recursive descent parser. +Implemented (2026-04-06). Replaced both `do_convtime()` and +`ParseDate()` with a unified Ragel -G2 scanner + recursive descent +parser in `mux/lib/date_scan.rl`. ## Background -`convtime()` currently has two independent code paths: +`convtime()` previously had two independent code paths: 1. **`do_convtime()`** — Hand-written parser for the legacy format `[Ddd] Mmm DD HH:MM:SS[.frac] YYYY`. Works correctly. @@ -246,37 +247,24 @@ Apr 6 26 ambiguous (year 26 vs day 26?) ## File Layout ``` -mux/lib/date_scan.rl Ragel source (scanner) +mux/lib/date_scan.rl Ragel source (scanner + parser in one file) mux/lib/date_scan.cpp Generated (read-only, chmod a-w) -mux/lib/date_parse.cpp Recursive descent parser -mux/lib/timeparser.cpp Deleted -mux/lib/timeutil.cpp do_convtime() removed -mux/include/timeutil.h ParseDate() signature unchanged or - replaced by date_parse() +mux/include/timeutil.h ParseDate() signature unchanged ``` -Alternatively, the parser can live in the same `.rl` file after -the `%%write` block, keeping scanner and parser together. +The old `mux/lib/timeparser.cpp` (1650-line deduction engine) has +been deleted. `do_convtime()` remains in `timeutil.cpp` and is +still called by `CLinearTimeAbsolute::SetString()` as a first-try +fast path in `fun_convtime()`. ## Testing -- `testcases/convtime_fn.mux` — legacy format tests (must still pass) -- `testcases/parsedate_fn.mux` — update with ISO + name-based tests -- All 998+ smoke tests must continue to pass -- The round-trip `convtime(convsecs(N, utc), utc) == N` must hold - for all valid N +- `testcases/convtime_fn.mux` — legacy format (7 SHA1-based tests) +- `testcases/parsedate_fn.mux` — 30 tests: ISO 8601, free-form, + timezones, sub-seconds, boundaries, rejections +- All 998 smoke tests pass -## Migration +## Size -1. Write `date_scan.rl` (scanner) and parser. -2. Wire as the sole implementation of date parsing. -3. Remove `do_convtime()` and old `ParseDate()`. -4. Verify all smoke tests pass. -5. Update `help convtime` examples. - -## Size Estimate - -- Ragel scanner: ~150 lines of `.rl` (names are just alternations) -- Recursive descent parser: ~200 lines of C++ -- Total: ~350 lines replacing ~1850 lines - (`do_convtime` ~130 + `ParseDate` ~1650 + helpers) +- `date_scan.rl`: 1277 lines (scanner + recursive descent parser) +- Replaces `timeparser.cpp`: 1653 lines (multi-pass deduction engine) diff --git a/docs/design-libmux-modules.md b/docs/design-libmux-modules.md index c71734631..1bd08788a 100644 --- a/docs/design-libmux-modules.md +++ b/docs/design-libmux-modules.md @@ -75,7 +75,7 @@ bootstraps new connections. Custom marshaling handles CStubSlaveProxy | Mail & comsys | mail, comsys | ~10,500 | | Objects & predicates | object, player, flags, predicates, player_c | ~9,000 | | Configuration & logging | conf, log | ~4,200 | -| Queue & timing | cque, game, timer, timeutil, timeparser | ~8,000 | +| Queue & timing | cque, game, timer, timeutil, date_scan | ~8,000 | | String & utility | stringutil, mathutil, wild, match, help | ~14,000 | | Module system | modules, libmux, stubslave | ~4,200 | | Unicode tables | utf8tables (generated) | ~11,000 | @@ -176,7 +176,7 @@ its first action, so existing code is unaffected. | Category | Files | |----------|-------| | Crypto/hash | sha1, svdrand, svdhash | -| Time | timeutil, timeabsolute, timedelta, timeparser, timezone | +| Time | timeutil, timeabsolute, timedelta, date_scan, timezone | | UTF-8 | utf8_collate, utf8_grapheme, utf8_normalize, utf8tables | | String | stringutil | | Math | mathutil, strtod | @@ -1265,7 +1265,7 @@ log (17), help (15), wild (8), modules (8), and others. | Category | Files | |---|---| | UTF-8 / Unicode | utf8_collate, utf8_grapheme, utf8_normalize | -| Time utilities | timeabsolute, timedelta, timeparser, timeutil, timezone | +| Time utilities | timeabsolute, timedelta, date_scan, timeutil, timezone | | Crypto / hash | sha1, svdhash, svdrand | | Math | funmath, strtod | | Network helpers | netaddr, telnet, slave | @@ -1304,7 +1304,7 @@ libmux.so requires either (a) creating a lighter header or (b) refactoring | utf8_normalize | above + string_desc | config.h, stringutil.h, externs.h (for string_desc) | | timeutil | UTF8, FIELDEDTIME, mux_isdigit, mux_atol | config.h, timeutil.h, stringutil.h | | timeabsolute, timedelta | above + mux_sprintf, mux_assert | config.h, timeutil.h, stringutil.h | -| timeparser, timezone | FIELDEDTIME, UTF8 | config.h, timeutil.h | +| date_scan, timezone | FIELDEDTIME, UTF8 | config.h, timeutil.h | | strtod | basic types only | config.h | | netaddr, telnet | UTF8, socket types | config.h, system headers | | alarm | std threading | config.h, system headers | diff --git a/mux/game/text/help.txt b/mux/game/text/help.txt index 3691a9b06..cbd95bb4f 100644 --- a/mux/game/text/help.txt +++ b/mux/game/text/help.txt @@ -6854,21 +6854,35 @@ CONVTIME() FUNCTION: convtime(