From 5bf4d9707d165fa5ddfe84766f9e8b7f50da5cb7 Mon Sep 17 00:00:00 2001 From: David Beazley Date: Tue, 9 Apr 2019 17:10:00 -0500 Subject: [PATCH] Fixed mysterious 'unknown conflict' error --- CHANGES | 5 ++++ example/wasm/wasm.py | 67 ++++++++++++++++++++++++++------------------ sly/yacc.py | 4 +-- 3 files changed, 47 insertions(+), 29 deletions(-) diff --git a/CHANGES b/CHANGES index b6f34ce..8432ebd 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,10 @@ Version 0.4 ----------- +04/09/2019 Minor refinement to the reporting of reduce/reduce conflicts. + If a top grammar rule wasn't specified, SLY could fail with + a mysterious "unknown conflict" exception. This should be + fixed. + 11/18/2018 Various usability fixes observed from last compilers course. - Errors encountered during grammar construction are now diff --git a/example/wasm/wasm.py b/example/wasm/wasm.py index ddda6f8..585e72e 100644 --- a/example/wasm/wasm.py +++ b/example/wasm/wasm.py @@ -11,52 +11,65 @@ import enum from collections import defaultdict import json -# ------------------------------------------------------------ -# Low level encoding of values - def encode_unsigned(value): ''' Produce an LEB128 encoded unsigned integer. ''' - bits = bin(value)[2:] - if len(bits) % 7: - bits = '0'*(7 - len(bits) % 7) + bits - - parts = [ bits[i:i+7] for i in range(0,len(bits), 7) ] - parts = [ parts[0], *['1'+p for p in parts[1:]] ] - parts = [ int(p, 2) for p in parts ] - return bytes(parts[::-1]) - -assert encode_unsigned(624485) == bytes([0xe5, 0x8e, 0x26]) + parts = [] + while value: + parts.append((value & 0x7f) | 0x80) + value >>= 7 + if not parts: + parts.append(0) + parts[-1] &= 0x7f + return bytes(parts) def encode_signed(value): ''' Produce a LEB128 encoded signed integer. ''' - if value > 0: - return encode_unsigned(value) - - bits = bin(~(~0 << value.bit_length()) & value)[2:] - bits = '1'+ '0'*(value.bit_length() - len(bits)) + bits - if len(bits) % 7: - bits = '1'*(7 - len(bits) % 7) + bits - return encode_unsigned(int(bits,2)) + parts = [ ] + if value < 0: + # Sign extend the value up to a multiple of 7 bits + value = (1 << (value.bit_length() + (7 - value.bit_length() % 7))) + value + negative = True + else: + negative = False + while value: + parts.append((value & 0x7f) | 0x80) + value >>= 7 + if not parts or (not negative and parts[-1] & 0x40): + parts.append(0) + parts[-1] &= 0x7f + return bytes(parts) +assert encode_unsigned(624485) == bytes([0xe5, 0x8e, 0x26]) +assert encode_unsigned(127) == bytes([0x7f]) assert encode_signed(-624485) == bytes([0x9b, 0xf1, 0x59]) +assert encode_signed(127) == bytes([0xff, 0x00]) -def encode_float64(value): +def encode_f64(value): + ''' + Encode a 64-bit floating point as little endian + ''' return struct.pack(' 0: if r != j: raise LALRError(f'Shift/shift conflict in state {st}') - elif r < 0: + elif r <= 0: # Do a precedence check. # - if precedence of reduce rule is higher, we reduce. # - if precedence of reduce is same and left assoc, we reduce.