lep.py

'''\
Logical Expression Parser.

Parses logical expression into an object tree and generates a truth table
covering all combinations of detected input variables.

Example: (a | not b) & not (c | not d)

The example above would generate a truth table for the 16 possible input
combinations for a, b, c, and d. (Assuming each could be true or false.)

Test run:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
command: main
args: 1
Main:
source: (not a | b) & not (not c & d)

Parse...
expr.NOT:
term.name: a (NEW)
expr.t1: a
expr.t1: NOT a
expr.op: OR
term.name: b (NEW)
expr.t2: b
term.expr: (NOT a OR b)
expr.t1: (NOT a OR b)
expr.op: AND
expr.NOT:
expr.NOT:
term.name: c (NEW)
expr.t1: c
expr.t1: NOT c
expr.op: AND
term.name: d (NEW)
expr.t2: d
term.expr: (NOT c AND d)
expr.t1: (NOT c AND d)
expr.t2: NOT (NOT c AND d)

Terms...
['a', 'c', 'b', 'd']

expression: ((NOT a OR b) AND NOT (NOT c AND d))
Truth Table:
  | a      c      b      d       | OUT
 0: False  False  False  False   = True
 1: True   False  False  False   = False
 2: False  True   False  False   = True
 3: True   True   False  False   = False
 4: False  False  True   False   = True
 5: True   False  True   False   = True
 6: False  True   True   False   = True
 7: True   True   True   False   = True
 8: False  False  False  True    = False
 9: True   False  False  True    = False
10: False  True   False  True    = True
11: True   True   False  True    = False
12: False  False  True   True    = False
13: True   False  True   True    = False
14: False  True   True   True    = True
15: True   True   True   True    = True

--
done: <type 'tuple'> (2)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

'''
####################################################################################################
from sys import stdoutstderrargv
from lep_objects import *
from lep_parser import *
####################################################################################################
ListToString = lambda lst: reduce(lambda acc,s: acc+slst'')


##------------------------------------------------------------------------------------------------##
samples = []
samples.append('not foo and not bar')
samples.append('(a | b) & not (a & b)')
samples.append('(a & not b) | (not a & b)')
samples.append('(a and not b) or (not a and b)')
samples.append('(not a | b) & not (not c & d)')
samples.append('(foo and bar) xor not (boo or far)')
samples.append('not ((not (foo & not bar) | not (foo & baz)) | ((bar & zip) | not (foo | zip)))')

sample_text = samples[0]

##================================================================================================##
def gen_truth_table (exprterms):
    print 'Truth Table:'

    ns = []
    for ix in range(len(terms)):
        ns.append('%-5s  ' % terms[ix].n)
    s = ListToString(ns)
    h1 = '   |  %s | =' % s
    h2 = '---|--%s-|------' % ('-' * len(s))

    print h1
    print h2
    for bx in range(2 ** len(terms)):
        ts = []
        for ix in range(len(terms)):
            terms[ix].v = True if (bx & (2 ** ix)) else False
            ts.append('%-5s  ' % terms[ix].v)
        v = expr()
        print '%3d|  %s = %-5s' % (bxListToString(ts), v)
    print h2
    print


##================================================================================================##
def do_test (*args):
    print 'Test:'
    print 'test/parameters: %d' % len(args)
    txt = args[0if 0 < len(argselse sample_text
    src = source(txt)

    print 'parse: "%s"' % src
    try:
        expr = parse_expression(src)
    except Exception as e:
        print e
        raise

    print 'terms: %s' % src.lib.keys()
    ts = []
    for t in src.lib.values():
        ts.append(t)
    print map(lambda t: str(t), ts)

    print
    print 'expression: %s' % expr
    gen_truth_table(exprts)

    return [srcexprts]
##================================================================================================##
def do_main (*args):
    print 'main/parameters: %d' % len(args)
    txt = args[0if 0 < len(argselse sample_text
    return [Nonetxt]
####################################################################################################
def dispatch (command, *args):
    print 'command: %s' % cmd
    print 'arguments: %d' % len(args)
    if command == 'test': return do_test(*args)
    if command == 'main': return do_main(*args)
    return [Nonecommandargs]
####################################################################################################
if __name__ == '__main__':
    print 'autorun: %s' % argv[0]
    cmd = argv[1]  if 1 < len(argvelse ''
    etc = argv[2:if 2 < len(argvelse [sample_text]
    obj = dispatch(cmd, *etc)
    print ''
    print 'exit/type: %s (length: %d)' % (type(obj), len(obj))
####################################################################################################
'''eof'''