Fixed mysterious 'unknown conflict' error
This commit is contained in:
parent
a728a23adf
commit
5bf4d9707d
5
CHANGES
5
CHANGES
@ -1,5 +1,10 @@
|
|||||||
Version 0.4
|
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.
|
11/18/2018 Various usability fixes observed from last compilers course.
|
||||||
|
|
||||||
- Errors encountered during grammar construction are now
|
- Errors encountered during grammar construction are now
|
||||||
|
@ -11,52 +11,65 @@ import enum
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import json
|
import json
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# Low level encoding of values
|
|
||||||
|
|
||||||
def encode_unsigned(value):
|
def encode_unsigned(value):
|
||||||
'''
|
'''
|
||||||
Produce an LEB128 encoded unsigned integer.
|
Produce an LEB128 encoded unsigned integer.
|
||||||
'''
|
'''
|
||||||
bits = bin(value)[2:]
|
parts = []
|
||||||
if len(bits) % 7:
|
while value:
|
||||||
bits = '0'*(7 - len(bits) % 7) + bits
|
parts.append((value & 0x7f) | 0x80)
|
||||||
|
value >>= 7
|
||||||
parts = [ bits[i:i+7] for i in range(0,len(bits), 7) ]
|
if not parts:
|
||||||
parts = [ parts[0], *['1'+p for p in parts[1:]] ]
|
parts.append(0)
|
||||||
parts = [ int(p, 2) for p in parts ]
|
parts[-1] &= 0x7f
|
||||||
return bytes(parts[::-1])
|
return bytes(parts)
|
||||||
|
|
||||||
assert encode_unsigned(624485) == bytes([0xe5, 0x8e, 0x26])
|
|
||||||
|
|
||||||
def encode_signed(value):
|
def encode_signed(value):
|
||||||
'''
|
'''
|
||||||
Produce a LEB128 encoded signed integer.
|
Produce a LEB128 encoded signed integer.
|
||||||
'''
|
'''
|
||||||
if value > 0:
|
parts = [ ]
|
||||||
return encode_unsigned(value)
|
if value < 0:
|
||||||
|
# Sign extend the value up to a multiple of 7 bits
|
||||||
bits = bin(~(~0 << value.bit_length()) & value)[2:]
|
value = (1 << (value.bit_length() + (7 - value.bit_length() % 7))) + value
|
||||||
bits = '1'+ '0'*(value.bit_length() - len(bits)) + bits
|
negative = True
|
||||||
if len(bits) % 7:
|
else:
|
||||||
bits = '1'*(7 - len(bits) % 7) + bits
|
negative = False
|
||||||
return encode_unsigned(int(bits,2))
|
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(-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('<d', value)
|
return struct.pack('<d', value)
|
||||||
|
|
||||||
def encode_float32(value):
|
def encode_f32(value):
|
||||||
|
'''
|
||||||
|
Encode a 32-bit floating point as little endian.
|
||||||
|
'''
|
||||||
return struct.pack('<f', value)
|
return struct.pack('<f', value)
|
||||||
|
|
||||||
def encode_name(value):
|
def encode_name(value):
|
||||||
|
'''
|
||||||
|
Encode a name as UTF-8
|
||||||
|
'''
|
||||||
data = value.encode('utf-8')
|
data = value.encode('utf-8')
|
||||||
return encode_vector(list(data[i:i+1] for i in range(len(data))))
|
return encode_vector(data)
|
||||||
|
|
||||||
def encode_vector(items):
|
def encode_vector(items):
|
||||||
'''
|
'''
|
||||||
Items is a list of encoded values
|
Items is a list of encoded value or bytess
|
||||||
'''
|
'''
|
||||||
if isinstance(items, bytes):
|
if isinstance(items, bytes):
|
||||||
return encode_unsigned(len(items)) + items
|
return encode_unsigned(len(items)) + items
|
||||||
@ -409,13 +422,13 @@ class F32OpBuilder(OpBuilder):
|
|||||||
_optable = f32
|
_optable = f32
|
||||||
|
|
||||||
def const(self, value):
|
def const(self, value):
|
||||||
self._append([self._optable.const, *encode_float32(value)])
|
self._append([self._optable.const, *encode_f32(value)])
|
||||||
|
|
||||||
class F64OpBuilder(OpBuilder):
|
class F64OpBuilder(OpBuilder):
|
||||||
_optable = f64
|
_optable = f64
|
||||||
|
|
||||||
def const(self, value):
|
def const(self, value):
|
||||||
self._append([self._optable.const, *encode_float64(value)])
|
self._append([self._optable.const, *encode_f64(value)])
|
||||||
|
|
||||||
def _flatten(instr):
|
def _flatten(instr):
|
||||||
for x in instr:
|
for x in instr:
|
||||||
|
@ -1414,7 +1414,7 @@ class LRTable(object):
|
|||||||
if not rlevel:
|
if not rlevel:
|
||||||
descrip.append(f' ! shift/reduce conflict for {a} resolved as shift')
|
descrip.append(f' ! shift/reduce conflict for {a} resolved as shift')
|
||||||
self.sr_conflicts.append((st, a, 'shift'))
|
self.sr_conflicts.append((st, a, 'shift'))
|
||||||
elif r < 0:
|
elif r <= 0:
|
||||||
# Reduce/reduce conflict. In this case, we favor the rule
|
# Reduce/reduce conflict. In this case, we favor the rule
|
||||||
# that was defined first in the grammar file
|
# that was defined first in the grammar file
|
||||||
oldp = Productions[-r]
|
oldp = Productions[-r]
|
||||||
@ -1451,7 +1451,7 @@ class LRTable(object):
|
|||||||
if r > 0:
|
if r > 0:
|
||||||
if r != j:
|
if r != j:
|
||||||
raise LALRError(f'Shift/shift conflict in state {st}')
|
raise LALRError(f'Shift/shift conflict in state {st}')
|
||||||
elif r < 0:
|
elif r <= 0:
|
||||||
# Do a precedence check.
|
# Do a precedence check.
|
||||||
# - if precedence of reduce rule is higher, we reduce.
|
# - if precedence of reduce rule is higher, we reduce.
|
||||||
# - if precedence of reduce is same and left assoc, we reduce.
|
# - if precedence of reduce is same and left assoc, we reduce.
|
||||||
|
Loading…
Reference in New Issue
Block a user