design a Condition class

Paul McGuire ptmcg at austin.rr._bogus_.com
Wed May 10 18:04:32 EDT 2006


<joh12005 at yahoo.fr> wrote in message
news:1147297217.372888.167960 at v46g2000cwv.googlegroups.com...
> Hello,
>
> i posted for suggestions a little idea even if it still needs further
> thoughts but as i'm sure you could help :)
>
> if would like to implement some kind of Condition class which i coud
> use to build bricks of more complex condition, conditions are based on
> fields by using regexp
>
> class Condition:
> def __init__(self, field0, field1, field2):
> self.field0 = field0
> self.field1 = field1
> self.field2 = field2
> def match(self, against):
> w, t, l = against
> f0 = False
> if self.field0 is None:
> f0 = True
> else:
> f0 = self.field0.search(w)
> if self.field1 is None:
> f1 = True
> else:
> f1 = self.field1.search(t)
> if self.field2 is None:
> f2 = True
> else:
> f2 = self.field2.search(l)
> return f0 and f1 and f2
>
> c0 = Condition(re.compile("something"), None,
> re.compile("somethingelse"))
> c1 = Condition(re.compile("another"), None, None)
>
> i can use
>
> if c0.search(myitem)
>
> but i would like to be able to have composition such as :
>
> c2 = c0 | c1
>
> which should be understood as defining a new c2 which is able to match
> (c0 or c1) from c0 and c1 already defined.
>
> actually i can imagine a
>
> def OR(c0, c1):
>      # here => missing None support 'a or None' is 'a'
>      return Condition(re.compile("|".join((c0.field0.pattern,
> c1.field0.pattern)),
>               re.compile("|".join((c0.field1.pattern,
> c1.field1.pattern)),
>               re.compile("|".join((c0.field2.pattern,
> c1.field2.pattern))
>
> the idea is to build c2 = Condition(re.compile("something|another"),
> None, re.compile("somethingelse"))
> c2 = OR(c0, c1)
>
> but maybe have you clever suggestions ?
>
> best regards.
>

Your composition of expressions to match is very similar to the definition
of grammars in pyparsing.  Here's a small example, to parse "Hello,
World!"-type strings.


from pyparsing import Word, alphas

# define grammar
greet = Word( alphas ) + "," + Word( alphas ) + "!"

# input string
hello = "Hello, World!"

# parse input string
print hello, "->", greet.parseString( hello )


The Word class matches any group of characters composed of the letters in
the string passed to the constructor.  alphas is a string constant of the
upper and lower case letters A thru Z.  This sample program prints out:

Hello, World! -> ['Hello', ',', 'World', '!']

pyparsing has many more expression types, including Literal,
CaselessLiteral, Optional, ZeroOrMore, and OneOrMore.  There are also
combining forms, And, Or, MatchFirst, and Each.  The handy part of these
combining forms is that there are operator short-cuts:
a + b  is the same as And([a,b]) (that is, a followed by b)
a | b is the same as MatchFirst([a,b]) (if not match a, then try to match b)
a ^ b is the same as Or([a,b]) (try matching a and b, choose longest match)
a @ b is the same as Each([a,b]) (match a and b in any order - good for
matching options that can be specified in any order)

The resulting grammar expressions are fairly readable.  The greet expression
above translates to

greet is a word group of alphabetic characters, followed by a ",", followed
by another word group of alphabetic characters, followed by a "!".  Note
that there is no explicit specification of whitespace - whitespace will
terminate a word group, but is not necessary if the grammar is unambiguous
without it.  For instance, this expression will match any of:

Hello,World!
Hello , World !
Hello ,World     !
... and so on.

Of course it will also match:
Howdy, pardner!
Greetings, Earthling!
Aloha, wahini!

The matched results are returned as an object of type ParseResults, which
can be accessed like a list, a dictionary, or an object with attributes (if
you associated names with individual elements of the parse expression).

You can get more info and download info at pyparsing.wikispaces.com.  Even
if you choose not to use pyparsing, you might get some ideas on your own
implementation.

-- Paul





More information about the Python-list mailing list