You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
HermitCrab: the order of segments inside a bracketed class in a rendered shape depends on load order #573
When a shape node matches more than one segment, the display string lists the matching segments in the order they were added to the CharacterDefinitionTable, not in a fixed order. The same grammar can therefore render as |b[ae]t or |b[ea]t, depending on how it was loaded. The parses and the morphemes are the same either way.
How it happens:
ToRegexString (HermitCrabExtensions.cs) gets the bracket contents from CharacterDefinitionTable.GetMatchingStrReps, which goes through the table's HashSet<CharacterDefinition>.
CharacterDefinition does not override Equals or GetHashCode. A HashSet that never had an item removed enumerates in the order items were added, but .NET does not document or guarantee that order.
The XML loader adds segments in grammar.xml order. FieldWorks' HCLoader.LoadCharacterDefinitionTable adds them by iterating IPhPhonemeSet.PhonemesOC, a collection with no defined order.
Seen in the conformance fixture edge-cases/loader-pattern-shapes (#480). Run from grammar.xml it renders bat and bet as |b[ae]t. Run from a FLEx project generated from that grammar and loaded through FieldWorks HCLoader (Machine 3.9.6), it renders |b[ea]t.
Won't fix. The members of a bracketed class are a set, and their order has no meaning. Sorting them would change what Try A Word shows in FLEx for no change in behaviour. Tools that compare these strings (the conformance suite, PanGloss, the FieldWorks contract check) should compare the contents of each [...] as a set. This issue records the analysis for anyone who sees the order differ between two loads of the same grammar.
Activity
johnml1135 commentedon Oct 27, 2026
Closing as won't fix; see the last paragraph of the description.
Compare bracketed shape classes as sets in the conformance runner
Compare bracketed shape classes as sets in the conformance gates