Skip to content

Fix hash and equals contract and align the simulator with Java - #44

Merged
marcospassos merged 2 commits into
devfrom
fix/runtime-alignment
Aug 15, 2026
Merged

Fix hash and equals contract and align the simulator with Java#44
marcospassos merged 2 commits into
devfrom
fix/runtime-alignment

Conversation

@marcospassos

@marcospassos marcospassos commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

Fixes correctness issues found by running this runtime and the Java reference over the same grammars and inputs and comparing the output.

Changes

  • Hash and equals now agree for ATN configs, prediction contexts and bit sets. Values that are equal no longer land in different buckets, so sets and maps stop degrading into linear scans.
  • MurmurHash matches Java bit for bit. It uses PHP's native murmur3a when available and falls back to a pure PHP implementation otherwise.
  • ATNState::hashCode() returns the state number, as in Java and C#.
  • The anonymous Equivalence class in ATNConfigSet is now a named class, so the set can be serialized.
  • setTrace(false) clears the tracer, so isTrace() reports the right value. Enabling twice no longer attaches two listeners.
  • The lexer decodes its input once instead of on every read, and the hot loops in both simulators avoid repeated method calls.

These also make the runtime faster, but the gain varies too much per grammar to quote a single figure here.

Verification

  • antlr4 runtime-testsuite: 361 of 362 descriptors pass. The one failure comes from antlr4's PHP.stg, not from this repository.
  • Parse trees, token streams and error output are byte identical to Java across 68 inputs from the grammars-v4 corpus.
  • PHPStan at level max is clean.

Closes #33
Closes #36
Closes #12

Supersedes #28 and #34, which this replaces.

No tests in this PR. They come in a follow up.

@marcospassos marcospassos mentioned this pull request Aug 15, 2026
Values that compare equal now hash equally for ATN configs, prediction
contexts and bit sets, so sets and maps stop degrading into linear scans.
MurmurHash matches Java bit for bit, using PHP's native murmur3a when
available with a pure PHP fallback. ATNState::hashCode() returns the state
number as in Java and C#.

The anonymous Equivalence class in ATNConfigSet is now a named class so the
set can be serialized. setTrace(false) clears the tracer so isTrace() reports
the right value.

The lexer decodes its input once instead of on every read, and the hot loops
in both simulators avoid repeated method calls.
@marcospassos
marcospassos force-pushed the fix/runtime-alignment branch from 19f40b0 to 222f990 Compare August 15, 2026 19:44
@marcospassos
marcospassos force-pushed the fix/runtime-alignment branch from 222f990 to 4db05a9 Compare August 15, 2026 19:46
@marcospassos
marcospassos merged commit 396cbea into dev Aug 15, 2026
4 checks passed
@marcospassos
marcospassos deleted the fix/runtime-alignment branch August 15, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant