コード例 #1
0
ファイル: Parser.cs プロジェクト: tuespetre/USPSAddressParser
        public static bool TryParseStreetAddress(string input, out StreetAddressSyntaxNode result)
        {
            var tokens = Tokenizer.Tokenize(input).Reverse().ToImmutableArray();

            var state = new ParserState(tokens);

            var success = TryParseStreetAddress(ref state, out var syntax) && state.Current.IsNone;

            result = success ? syntax : null;

            return(success);
        }
コード例 #2
0
ファイル: Parser.cs プロジェクト: tuespetre/USPSAddressParser
        private static bool TryParseStreetAddress(ref ParserState state, out StreetAddressSyntaxNode result)
        {
            result = default;

            var snapshot = state;

            TryParseSecondaryAddress(ref state, out var secondaryAddress);

            if (!TryParseSecondaryAddress(ref state, out _))
            {
                var gotPostDirectional = TryParseDirectional(ref state, out var postDirectional);

                var gotSuffix = TryParseStreetSuffix(ref state, out var suffix);

                var primaryNameTokens = state.Tokens.Skip(state.Index).ToImmutableArray();

                state = new ParserState(state.Tokens, state.Tokens.Length);

                if (TryParseFromEnd <RangeSyntaxNode>(ref primaryNameTokens, out var addressNumber, TryParseRange) &&
                    addressNumber.Components.Any(c => c.IsNumeric))
                {
                    var gotPreDirectional = TryParseFromEnd <DirectionalSyntaxNode>(ref primaryNameTokens, out var preDirectional, TryParseDirectional);

                    primaryNameTokens = primaryNameTokens.Reverse().ToImmutableArray();

                    if (primaryNameTokens.All(t => t.IsWhiteSpace))
                    {
                        if (gotSuffix && !gotPreDirectional)
                        {
                            primaryNameTokens = suffix.Tokens.ToImmutableArray();
                            suffix            = null;
                        }
                        else if (gotPostDirectional)
                        {
                            primaryNameTokens = postDirectional.Tokens.ToImmutableArray();
                            postDirectional   = null;
                        }
                        else if (gotPreDirectional)
                        {
                            primaryNameTokens = preDirectional.Tokens.ToImmutableArray();
                            preDirectional    = null;
                        }
                    }

                    if (primaryNameTokens.Length >= 3)
                    {
                        var token0 = primaryNameTokens[0];
                        var token2 = primaryNameTokens[2];

                        if (token0.Matches("CO") || token0.Matches("CTY") || token0.Matches("COUNTY"))
                        {
                            if (token2.Matches("RD") || token2.Matches("ROAD"))
                            {
                                primaryNameTokens
                                    = primaryNameTokens
                                      .SetItem(0, token0.WithValue("COUNTY"))
                                      .SetItem(2, token0.WithValue("ROAD"));
                            }
                        }
                    }

                    if (!primaryNameTokens.IsEmpty)
                    {
                        result = new StreetAddressSyntaxNode(
                            addressNumber,
                            preDirectional,
                            primaryNameTokens,
                            suffix,
                            postDirectional,
                            secondaryAddress);

                        return(true);
                    }
                }
            }

            state = snapshot;

            return(false);
        }