started refactoring of dicerolling to use a context-free grammar.

This commit is contained in:
2020-07-29 20:31:10 +03:00
parent 48167cfd10
commit d2654fac24
4 changed files with 81 additions and 17 deletions

75
dice/dice.py Normal file
View File

@@ -0,0 +1,75 @@
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