#coding=utf-8
#------------------------------------------------------------------------------#
import re
#------------------------------------------------------------------------------#
#算术表达式规则
ARITEXP_RULE = \
{
'PARA': '[\.\w]+', #参数匹配正则表达式
'OP': '[\+\-\*\/\(\)]', #运算符匹配正则表达式
"PRI": {'*':2, '/':2, '+':1, '-':1} #运算符优先级(从高到低)
}
#关系表达式规则
RELATEXP_RULE = \
{
'PARA': '[^\&\|\!\(\)]+', #参数匹配正则表达式
'OP': '[\&\|\!\(\)]', #运算符匹配正则表达式
'PRI': {'!':3, '&':2, '|':1} #运算符优先级
}
#------------------------------------------------------------------------------#
#常规表达式转换为后缀表达式
class CConvExp(object):
def __init__(self, strexp, exprule):
self.rule = exprule
self.exp = self.conv(strexp)
def conv(self, exp):
newexp = []
stack = []
for e,t in self.get_elem(exp):
if t == 'para':
newexp.append(e)
elif t == 'op':
if stack==[] or e=='(':
stack.append(e)
elif e == ')':
if '(' not in stack:
print 'ERROR: The expression: %s is wrong!' % exp
return
op = stack.pop()
while op != '(':
newexp.append(op)
op = stack.pop()
elif stack[-1]=='(':
stack.append(e)
else:
while(True):
if self.high_op(e, stack):
stack.append(e)
break
else:
newexp.append(stack.pop())
for op in reversed(stack):
newexp.append(op)
return newexp
def get_elem(self, exp):
idx, length = 0, len(exp)
while idx < length:
if exp[idx] == ' ':
continue
elif re.match(self.rule['OP'], exp[idx]):
yield exp[idx], 'op'
elif re.match(self.rule['PARA'], exp[idx:]):
para = re.findall(self.rule['PARA'], exp[idx:])[0]
idx += len(para)-1
yield para, 'para'
else:
print 'ERROR: The expression: %s is wrong!' % exp
return
idx += 1
return
def high_op(self, op, stack):
if stack == []:
return True
if self.rule['PRI'][op] > self.rule['PRI'][stack[-1]]:
return True
return False
#------------------------------------------------------------------------------#
if __name__ == '__main__':
str1 = r'a+b*(c-(d+e))'
str2 = r'!(a+b)|c&d[0:3]'
exp1 = CConvExp(str1, ARITEXP_RULE)
exp2 = CConvExp(str2, RELATEXP_RULE)
print exp1.exp
print exp2.exp