private static bool TryParseSecondaryAddress(ref ParserState state, out SecondaryAddressSyntaxNode result) { result = default; var snapshot = state; state.ConsumeWhiteSpace(); foreach (var(expanded, abbreviated, requiresRange) in PostalDesignators.SecondaryAddressUnitDesignators) { if (!requiresRange && state.TryConsume(t => t.Matches(expanded) || t.Matches(abbreviated))) { result = new SecondaryAddressSyntaxNode(abbreviated, state.TakeBuffer()); return(true); } } if (!TryParseStreetSuffix(ref state, out _) && TryParseRange(ref state, out var rangeUnitIdentifier)) { state.ConsumeWhiteSpace(); string designator = null; if (state.TryConsume(t => t.IsOctothorpe)) { designator = "#"; state.ConsumeWhiteSpace(); } if (state.TryConsume(t => t.IsCommaOrPeriod)) { state.ConsumeWhiteSpace(); } foreach (var(expanded, abbreviated, _) in PostalDesignators.SecondaryAddressUnitDesignators) { if (state.TryConsume(t => t.Matches(expanded) || t.Matches(abbreviated))) { designator = abbreviated; break; } } if (designator != null) { result = new SecondaryAddressSyntaxNode(designator, state.TakeBuffer(), rangeUnitIdentifier); return(true); } } state = snapshot; return(false); }
public static bool TryParseSecondaryAddress(string input, out SecondaryAddressSyntaxNode result) { var tokens = Tokenizer.Tokenize(input).Reverse().ToImmutableArray(); var state = new ParserState(tokens); var success = TryParseSecondaryAddress(ref state, out var syntax) && state.Current.IsNone; result = success ? syntax : null; return(success); }