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 <jan@janware.com>
This commit is contained in:
Jan Lindemann 2017-07-27 16:51:48 +02:00
commit da6c32255e

View file

@ -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)