From da6c32255ed4a8e33e99c01986d0922dc1601a2e Mon Sep 17 00:00:00 2001 From: Jan Lindemann Date: Thu, 27 Jul 2017 16:51:48 +0200 Subject: [PATCH] Make jwutils.algo.Operator a class This was a namedtuple before, but I couldn't figure out how to ex-/import it over module boundaries, so I've made it a class. Signed-off-by: Jan Lindemann --- tools/python/jwutils/algo/ShuntingYard.py | 32 ++++++++++++++++------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/tools/python/jwutils/algo/ShuntingYard.py b/tools/python/jwutils/algo/ShuntingYard.py index 2242720..6edc5b3 100644 --- a/tools/python/jwutils/algo/ShuntingYard.py +++ b/tools/python/jwutils/algo/ShuntingYard.py @@ -1,10 +1,17 @@ from collections import namedtuple import re -Operator = namedtuple("Operator", [ "func", "nargs" , "prec", "assoc" ]) # export L, R = 'Left Right'.split() ARG, KEYW, LPAREN, RPAREN = 'arg kw ( )'.split() +class Operator: # export + + def __init__(self, func=None, nargs=2, precedence=3, assoc=L): + self.func = func + self.nargs = nargs + self.prec = precedence + self.assoc = assoc + class Stack: def __init__(self, itemlist=[]): @@ -34,12 +41,17 @@ class ShuntingYard(object): # export for k, v in operators.iteritems(): self.add_operator(k, v.func, v.nargs, v.prec, v.assoc) - def token_string(): - for k, v in self.__ops: - buf = ", " + k - if v.nargs > 1: - buf += "xxx" + def token_string(self): + r = "" + for k, v in self.__ops.iteritems(): + buf = ", \"" + k + if v.nargs == 1: + if k[len(k)-1].isalnum(): + buf = buf + ' ' + buf = buf + "xxx" + buf = buf + "\"" r = r + buf + if len(r): return r[2:] return r @@ -87,12 +99,12 @@ class ShuntingYard(object): # export table.append( (token, action, ' '.join(outq), ' '.join(s[0] for s in stack), note) ) elif toktype == KEYW: val = self.__ops[token] - t1, (f1, n1, p1, a1) = token, val + t1, op1 = token, val v = t1 note = 'Pop ops from stack to output' while stack: - t2, (f2, n2, p2, a2) = stack[-1] - if (a1 == L and p1 <= p2) or (a1 == R and p1 < p2): + t2, op2 = stack[-1] + if (op1.assoc == L and op1.prec <= op2.prec) or (op1.assoc == R and op1.prec < op2.prec): if t1 != RPAREN: if t2 != LPAREN: stack.pop() @@ -126,7 +138,7 @@ class ShuntingYard(object): # export note = 'Drain stack to output' while stack: v = '' - t2, (f2, n2, p2, a2) = stack[-1] + t2, op2 = stack[-1] action = '(Pop op)' stack.pop() outq.append(t2)