I'm a "cheat early, cheat often" kind of guy. The following translates your input code into a Python expression, parses it using the normal mechanism, then prints out the structure.
import ast, re
source = "((x='a' OR x= 'b') AND(y ='c' OR y = 'd' ))"
# turn source '=' into Python '==', unless it's part of a compound
# IE: <= >= != => =< =!
py_source = re.compile(
r'(?<= [^<>!] )'
r'='
r'(?<= [^<>!] )',
re.VERBOSE).sub('==', source.lower())
print 'SOURCE:', source
print 'PYTHON:', py_source
print ast.dump( ast.parse(py_source) )
Example output:
SOURCE: ((x='a' OR x= 'b') AND(y ='c' OR y = 'd' ))
PYTHON: ((x=='a' or x== 'b') and(y =='c' or y == 'd' ))
Module(body=[Expr(value=BoolOp(op=And(), values=[BoolOp(op=Or(), values=[Compare(left=Name(id='x', ctx=Load()), ops=[Eq()], comparators=[Str(s='a')]), Compare(left=Name(id='x', ctx=Load()), ops=[Eq()], comparators=[Str(s='b')])]), BoolOp(op=Or(), values=[Compare(left=Name(id='y', ctx=Load()), ops=[Eq()], comparators=[Str(s='c')]), Compare(left=Name(id='y', ctx=Load()), ops=[Eq()], comparators=[Str(s='d')])])]))])