import pyparsing import math import operator import numpy as np from pyparsing import ( Literal, CaselessLiteral, Word, Optional, Group, Forward, nums, ParseException, ) class Dice: exprStack = [] def __init__(self): pass def roll(self, roll_params): self.exprStack[:] = [] # Reset the stack try: results = self.BNF().parseString(roll_params, parseAll=True) except ParseException as pe: print("Parse exception ", str(pe)) return except Exception as e: print("Exception ", str(e), self.exprStack) return results def push_first(self, tokens): self.exprStack.append(tokens[0]) def BNF(self): integer = Word(nums) plus, minus = map(Literal, "+-") addop = plus | minus rollop = CaselessLiteral('d') # lowop = CaselessLiteral('l') # highop = CaselessLiteral('h') # Define roll as a group roll = Group(Optional(integer, default=1) + rollop + integer) expression = Forward() operand = ( addop[...] + ( # Numbers as a fallback, add everything else as (roll | exception | ...) (roll).setParseAction(self.push_first) | integer ) ) term = operand + (rollop + operand).setParseAction(self.push_first)[...] expression <<= term + (addop + term).setParseAction(self.push_first)[...] bnf = expression return bnf