From 9a246ad6d1861ef10aca1ad88b8134415ea0e618 Mon Sep 17 00:00:00 2001 From: Andrew Zhu Date: Mon, 18 May 2020 11:49:04 -0700 Subject: [PATCH] Handle more possible comment ambiguities Resolves avrae/avrae#1079 --- d20/dice.py | 4 +++- d20/expression.py | 1 - setup.py | 2 +- tests/test_arguments.py | 16 ++++++++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/d20/dice.py b/d20/dice.py index e590a1d..e6c5cae 100644 --- a/d20/dice.py +++ b/d20/dice.py @@ -10,6 +10,8 @@ __all__ = ("CritType", "AdvType", "RollContext", "RollResult", "Roller") +POSSIBLE_COMMENT_AMBIGUITIES = {"k", "p", "rr", "ro", "ra", "e", "mi", "ma", "*", "d"} + class CritType(IntEnum): """ @@ -208,7 +210,7 @@ def _parse_with_comments(self, expr): except lark.UnexpectedInput as ui: # if the statement up to the unexpected token ends with an operator, remove that from the end successful_fragment = expr[:ui.pos_in_stream] - for op in SetOperator.OPERATIONS: + for op in POSSIBLE_COMMENT_AMBIGUITIES: if successful_fragment.endswith(op): successful_fragment = successful_fragment[:-len(op)] force_comment = expr[len(successful_fragment):] diff --git a/d20/expression.py b/d20/expression.py index 61317f7..9a52517 100644 --- a/d20/expression.py +++ b/d20/expression.py @@ -420,7 +420,6 @@ def __repr__(self): class SetOperator: # set_op, dice_op """Represents an operation on a set.""" __slots__ = ("op", "sels") - OPERATIONS = {"k", "p", "rr", "ro", "ra", "e", "mi", "ma"} def __init__(self, op, sels): """ diff --git a/setup.py b/setup.py index e78ed3c..e43424b 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setuptools.setup( name="d20", - version="1.0.2", + version="1.0.3", author="Andrew Zhu", author_email="andrew@zhu.codes", description="A formal grammar-based dice parser and roller for D&D and other dice systems.", diff --git a/tests/test_arguments.py b/tests/test_arguments.py index d97bb7e..6e37904 100644 --- a/tests/test_arguments.py +++ b/tests/test_arguments.py @@ -12,6 +12,8 @@ def test_comments(): with pytest.raises(RollSyntaxError): roll("1d20 foo bar", allow_comments=False) + +def test_conflicting_comments(): # expressions with ambiguity r = roll("1d20 keep something", allow_comments=True) assert 1 <= r.total <= 20 @@ -20,6 +22,20 @@ def test_comments(): with pytest.raises(RollSyntaxError): roll("1d20 keep something", allow_comments=False) + r = roll("1d20 damage", allow_comments=True) + assert 1 <= r.total <= 20 + assert r.comment == "damage" + + with pytest.raises(RollSyntaxError): + roll("1d20 damage", allow_comments=False) + + r = roll("1d20 **bold**", allow_comments=True) + assert 1 <= r.total <= 20 + assert r.comment == "**bold**" + + with pytest.raises(RollSyntaxError): + roll("1d20 **bold**", allow_comments=False) + def test_advantage(): r = roll("1d20", advantage=AdvType.ADV)