Skip to content

Commit

Permalink
Fix parsing numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
evhub committed Nov 26, 2023
1 parent 84cc54f commit aa6c431
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 11 deletions.
7 changes: 5 additions & 2 deletions coconut/compiler/grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,11 @@ class Grammar(object):
| integer + Optional(dot + Optional(integer))
)
sci_e = combine((caseless_literal("e") | fixto(Literal("\u23e8"), "e")) + Optional(plus | neg_minus))
numitem = ~(Literal("0") + Word(nums + "_", exact=1)) + combine(basenum + Optional(sci_e + integer))
numitem = combine(
# don't match 0_, 0b_, 0o_, or 0x_
regex_item(r"(?!0([0-9_]|[box][0-9_]))").suppress()
+ basenum + Optional(sci_e + integer)
)
imag_num = combine(numitem + imag_j)
maybe_imag_num = combine(numitem + Optional(imag_j))
bin_num = combine(caseless_literal("0b") + Optional(underscore.suppress()) + binint)
Expand All @@ -812,7 +816,6 @@ class Grammar(object):
hex_num,
bin_num,
oct_num,
use_adaptive=False,
)
# make sure that this gets addspaced not condensed so it doesn't produce a SyntaxError
num_atom = addspace(number + Optional(condense(dot + unsafe_name)))
Expand Down
9 changes: 6 additions & 3 deletions coconut/compiler/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,9 @@ def __str__(self):
def any_of(*exprs, **kwargs):
"""Build a MatchAny of the given MatchFirst."""
use_adaptive = kwargs.pop("use_adaptive", use_adaptive_any_of) and SUPPORTS_ADAPTIVE
reverse = reverse_any_of
if DEVELOP:
reverse = kwargs.pop("reverse", reverse)
internal_assert(not kwargs, "excess keyword arguments passed to any_of", kwargs)

AnyOf = MatchAny if use_adaptive else MatchFirst
Expand All @@ -1116,15 +1119,15 @@ def any_of(*exprs, **kwargs):
for e in exprs:
if (
# don't merge MatchFirsts when we're reversing
not (reverse_any_of and not use_adaptive)
not (reverse and not use_adaptive)
and e.__class__ == AnyOf
and not hasaction(e)
):
flat_exprs.extend(e.exprs)
else:
flat_exprs.append(e)

if reverse_any_of:
if reverse:
flat_exprs = reversed([trace(e) for e in exprs])

return AnyOf(flat_exprs)
Expand Down Expand Up @@ -1228,7 +1231,7 @@ def manage_elem(self, original, loc):
raise ParseException(original, loc, self.errmsg, self)

for elem in elems:
yield Wrap(elem, manage_elem, include_in_packrat_context=True)
yield Wrap(elem, manage_elem)


def disable_outside(item, *elems):
Expand Down
8 changes: 3 additions & 5 deletions coconut/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,7 @@ def get_path_env_var(env_var, default):
# -----------------------------------------------------------------------------------------------------------------------

# set this to False only ever temporarily for ease of debugging
use_fast_pyparsing_reprs = True
assert use_fast_pyparsing_reprs or DEVELOP, "use_fast_pyparsing_reprs should never be disabled on non-develop build"
use_fast_pyparsing_reprs = get_bool_env_var("COCONUT_FAST_PYPARSING_REPRS", True)

enable_pyparsing_warnings = DEVELOP
warn_on_multiline_regex = False
Expand Down Expand Up @@ -168,8 +167,7 @@ def get_path_env_var(env_var, default):
# -----------------------------------------------------------------------------------------------------------------------

# set this to True only ever temporarily for ease of debugging
embed_on_internal_exc = False
assert not embed_on_internal_exc or DEVELOP, "embed_on_internal_exc should never be enabled on non-develop build"
embed_on_internal_exc = get_bool_env_var("COCONUT_EMBED_ON_INTERNAL_EXC", False)

# should be the minimal ref count observed by maybe_copy_elem
temp_grammar_item_ref_count = 4 if PY311 else 5
Expand Down Expand Up @@ -1009,7 +1007,7 @@ def get_path_env_var(env_var, default):

# min versions are inclusive
unpinned_min_versions = {
"cPyparsing": (2, 4, 7, 2, 3, 1),
"cPyparsing": (2, 4, 7, 2, 3, 2),
("pre-commit", "py3"): (3,),
("psutil", "py>=27"): (5,),
"jupyter": (1, 0),
Expand Down
2 changes: 1 addition & 1 deletion coconut/root.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
VERSION = "3.0.4"
VERSION_NAME = None
# False for release, int >= 1 for develop
DEVELOP = 1
DEVELOP = 2
ALPHA = True # for pre releases rather than post releases

assert DEVELOP is False or DEVELOP >= 1, "DEVELOP must be False or an int >= 1"
Expand Down
4 changes: 4 additions & 0 deletions coconut/tests/constants_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ def is_importable(name):

class TestConstants(unittest.TestCase):

def test_defaults(self):
assert constants.use_fast_pyparsing_reprs
assert not constants.embed_on_internal_exc

def test_fixpath(self):
assert os.path.basename(fixpath("CamelCase.py")) == "CamelCase.py"

Expand Down
4 changes: 4 additions & 0 deletions coconut/tests/src/cocotest/agnostic/primary_2.coco
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,10 @@ def primary_test_2() -> bool:
assert collectby(.[0], [(0, 1), (0, 2)], value_func=.[1], reduce_func=(+), reduce_func_init=1) == {0: 4}
assert ident$(1, ?) |> type == ident$(1) |> type
assert 10! == 3628800
assert 0x100 == 256 == 0o400
assert 0x0 == 0 == 0b0
x = 10
assert 0x == 0 == 0 x

with process_map.multiple_sequential_calls(): # type: ignore
assert map((+), range(3), range(4)$[:-1], strict=True) |> list == [0, 2, 4] == process_map((+), range(3), range(4)$[:-1], strict=True) |> list # type: ignore
Expand Down

0 comments on commit aa6c431

Please sign in to comment.