PreviousUpNext

15.4.866  src/lib/regex/glue/regex-match-result.pkg

## regex-match-result.pkg

# Compiled by:
#     src/lib/std/standard.lib

# Regex_Match_Results  are used to
# represent the results of matching
# regular expressions against strings.



api Regex_Match_Result {
    #
    # A match tree is used to represent
    # the results of a nested grouping
    # of regular expressions.

    Regex_Match_Result(X)
        =
        REGEX_MATCH_RESULT (X, List( Regex_Match_Result(X) ));

    root:  Regex_Match_Result(X) -> X;                                  # Return the root (outermost) match in the tree 

    nth:  ((Regex_Match_Result(X), Int)) -> X;                          # Return the nth match in the tree; matches are labeled in pre-order
                                                                        # starting at 0.        Raises INDEX_OUT_OF_BOUNDS.

    map:  (X -> Y) -> Regex_Match_Result(X) -> Regex_Match_Result(Y);   # Map a function over the tree (in preorder) 

    apply:  (X -> Void) -> Regex_Match_Result(X) -> Void;               # Apply a given function over ever element of the tree (in preorder) 

    find:  (X -> Bool) -> Regex_Match_Result(X) -> Null_Or(X);          # Find the first match that satisfies the predicate (or NULL) 

    match_count:  Regex_Match_Result(X) -> Int;                         # Return the number of submatches included in the match tree 
};



package regex_match_result
:       Regex_Match_Result
{
    Regex_Match_Result(X)
        =
        REGEX_MATCH_RESULT  (X, List( Regex_Match_Result(X) ));

    fun match_count  m
        = 
        (count_list [m]) - 1
        where
            fun count_list [] =>   0;

                count_list ((REGEX_MATCH_RESULT (x, l)) ! ms)
                    =>
                    1  +  count_list (l)  +  count_list (ms);
            end;
        end;


    # Return the root (outermost) match in the tree:
    #
    fun root (REGEX_MATCH_RESULT (x, _))
        =
        x;



    # Return the nth match in the tree;
    # matches are labeled in pre-order
    # starting at 0.
    #
    fun nth (t, n)
        =
        case (walk (n, t))
          
             INR x =>  x;
             INL _ =>  raise exception INDEX_OUT_OF_BOUNDS;
        esac
        where

            Sum X = INL  Int
                  | INR  X;

            fun walk (0, REGEX_MATCH_RESULT (x, _)) => INR x;

                walk (i, REGEX_MATCH_RESULT (_, children))
                    =>
                    {   fun walk_list (i, []) => INL i;

                            walk_list (i, m ! r)
                                =>
                                case (walk (i, m))
                                  
                                     INL j  =>  walk_list (j, r);
                                     result =>  result;
                                 esac;

                        end;

                        walk_list (i - 1, children);
                   };
            end;
        end;


    # Map a function over the tree (in preorder):
    #
    fun map f
        =
        mapf
        where
            fun mapf (REGEX_MATCH_RESULT (x, children))
                =
                REGEX_MATCH_RESULT (f x, mapl children)

            also
            fun mapl []         =>  [];
                mapl (x ! rest) =>  (mapf x) ! (mapl rest);
            end;
        end;


    fun apply f (REGEX_MATCH_RESULT (c, children))
        =
        {   f c;
            list::apply (apply f) children;
        };


    # Find the first match that satisfies the predicate:
    #
    fun find prior
        =
        find_p
        where
            fun find_p (REGEX_MATCH_RESULT (x, children))
                =
                if   (prior x)
                     THE x;
                else find_list children;
                fi

            also
            fun find_list [] => NULL;

                find_list (m ! r)
                    =>
                    case (find_p m)
                       
                         NULL   =>  find_list r;
                         result =>  result;
                     esac;
            end;
        end;

};                              # package regex_match_result 



Comments and suggestions to: bugs@mythryl.org

PreviousUpNext