skyem123 / StringMatcher1

A matching thing written in Kotlin, because RegEx is too painful on it's own. (and I wanted to try Kotlin). Now abandoned.
BSD 2-Clause "Simplified" License
0 stars 0 forks source link

Switch Matcher #15

Open SoniEx2 opened 9 years ago

SoniEx2 commented 9 years ago

Can we get a switch matcher? It's a set of key-value pairs (aka a HashMap (but not necessarily)) that is much faster than alternations (O(1) vs O(n)).

First you need a pattern. This pattern will be used to lookup a pattern in the map. After matching the pattern, and looking up the result in the map, there are 2 possible outcomes:

Constructing and using switch matchers could be done as in switch(pattern).setCase(string, pattern).setCase(string, pattern).setCase(null, pattern).

Removing cases could be done with setCase(string, null).

skyem123 commented 9 years ago

I do not like the idea of using a null, hmm...

skyem123 commented 9 years ago

So... with setCase(string, pattern), is string the ID of the pattern?

skyem123 commented 9 years ago

Also, instead of pattern, it would be matcher. :wink:

SoniEx2 commented 9 years ago

I do not like the idea of using a null, hmm...

"null" means "none". See also Python. (Do note that I only decided this because it's map-backed, and maps return null for missing keys.)

So... with setCase(string, pattern), is string the ID of the pattern?

string is a string. If the pattern you're switching on (the one you passed to switch()) matches "abc", the case you're looking for has "abc" as string.

Basically, this is backed by a HashMap<String, Matcher>. The basic idea is this:

Find match for the switch pattern (the one you passed to switch()), map.get(<the match>), if it's null you look for a default case with map.get(null), either way you now have a matcher (or null if there's no default either). If it's null the switch doesn't match, otherwise you match the retrieved matcher.

Something like this: (simplified lazy pseudocode - I don't know what your codebase looks like)

// Java because I'm lazy
private HashMap map = new HashMap<String, Matcher>();
private Matcher matcher; // this is what you switch on

public void setCase(String string, Matcher matcher) {
    map.put(string, matcher);
}

public boolean match(State s) {
    if (matcher.match(s)) {
        Matcher m = map.get(s.getMatch()); // try case
        if (m == null) m = map.get(null); // try default
        if (m == null) return false; // didn't match
        return m.match(s); // run case (or default) matcher
    }
    return false;
}

Also, instead of pattern, it would be matcher. :wink:

Same thing.

skyem123 commented 9 years ago

Hm... Maybe I should have a FilteredMatch class, that can filter based on the string, start position range and end position range, as that would allow for more detailed filtering.

SoniEx2 commented 9 years ago

That's already possible.

skyem123 commented 9 years ago

huh?

SoniEx2 commented 9 years ago

Anchor a match to the start of the string, add garbage/ignored characters (optionally make them optional), then follow it with a switcher.

You do a position range with the garbage chars, you do the "filter based on the string" with a switcher.

skyem123 commented 9 years ago

so you're saying to modify the string?

SoniEx2 commented 9 years ago

What? No I mean like, add as many "matcher for any character" as you need.

skyem123 commented 9 years ago

Can you describe how to match ranges instead of strings themselves will work? I didn't quite understand you there.

SoniEx2 commented 9 years ago

You said start/end pos ranges.

You add "any character" until you hit the desired start pos, then add "any character (optional)" (aka ".?" in regex) endpos-startpos times. This means it can match in any position between startpos and endpos, but not outside that. Obviously you have to anchor it to match only at the start of the string.

skyem123 commented 9 years ago

hmm..

skyem123 commented 9 years ago

While this would be nice for a first alpha, I don't think that my motivation will survive that long.