On Apr 17, 7:37 am, prueba...@latinmail.com wrote: > On Apr 16, 3:59 pm, Aaron Brady <castiro...@gmail.com> wrote: > > > > > On Apr 16, 10:57 am, prueba...@latinmail.com wrote: > > > > Another interesting task for those that are looking for some > > > interesting problem: > > > I inherited some rule system that checks for programmers program > > > outputs that to be ported: given some simple rules and the values it > > > has to determine if the program is still working correctly and give > > > the details of what the values are. If you have a better idea of how > > > to do this kind of parsing please chime in. I am using tokenize but > > > that might be more complex than it needs to be. This is what I have > > > come up so far: > snip > > > def main(): > > > for cur_rule in rules[20:26]: > > > tokens=get_tokens(cur_rule) > > > normal=replace_comps(tokens,COMP_REPLACERS) > > > subst=replace_names(normal,vars_) > > > groups=split_seccions(subst,COMP_REPLACERS.values()) > > > rep=all_seccions(groups) > > > rep_out=''.join(x[0]+x[1] for x in rep) > > > calc=calc_seccions(rep) > > > calc_out=''.join(x[0]+x[1] for x in calc) > > > deltas=calc_deltas(calc) > > > result=eval(calc_out,{},{}) > > > snip > snip > > >>> a= '-1000.00 < A < 0.00' > > >>> eval( a, { 'A': -100 } ) snip > > >>> a= '-1000.00 LE A LE 0.00' > > >>> b= a.replace( ' LE ', ' <= ' ) snip > > I know about evals implication of safety. Rules are defined by the > programmers so I don't worry too much about it at this point. They > should know better than messing up their application server. Unless > there is some easier way to do it I am willing to take the risk. > Precedence is standard math, we can always add some extra parenthesis > to the rules, I don't thing the old system would mind. > > I thought about using eval with a locals dictionary, but they want > output of the intermediate values. I want to avoid the situation where > the intermediate output does not match what eval is doing.
I take you to need the operands to the individual comparison operators; that is, each side of each comparison. There might be a way using abstract syntax trees. Or, a basic 're' split can simplify it. >>> import re >>> a= '-1000.00 LE A LE 0.00' >>> b= re.split( r'\s(LT|GT|LE|GE|=|<|>|<=|>=)\s', a ) >>> b ['-1000.00', 'LE', 'A', 'LE', '0.00'] >>> COMP_REPLACERS={'LT':'<', 'GT':'>', 'LE':'<=', 'GE':'>=', '=':'=='} >>> c= [ COMP_REPLACERS.get( x, x ) for x in b ] >>> c ['-1000.00', '<=', 'A', '<=', '0.00'] >>> vars_={'A': 0, 'B': 1.1, 'C': 2.2, 'D': 3.3, 'E': 4.4, 'F': 5.5, 'G': ... 6.6, 'H':7.7, 'I':8.8, 'J':9.9} >>> d= [ str( vars_.get( x, x ) ) for x in c ] >>> d ['-1000.00', '<=', '0', '<=', '0.00'] >>> eval( ''.join( d ) ) True The 'dict.get( x, x )' expression returns the value of the entry for x, or x itself if it is not present. No promises. I didn't think it all the way through. -- http://mail.python.org/mailman/listinfo/python-list