Compare commits

..

No commits in common. "0c3e6b211c74f79a68d7ef8ab16f86c9f14f0a80" and "bea790368615d7c7648559e2b7d51aff7045e96f" have entirely different histories.

View file

@ -112,19 +112,19 @@ class RepairStack(typing.NamedTuple):
match action: match action:
case parser.Shift(): case parser.Shift():
rl.debug(f"{stack.state}: SHIFT -> {action.state}") rl.info(f"{stack.state}: SHIFT -> {action.state}")
return stack.push(action.state), False return stack.push(action.state), False
case parser.Accept(): case parser.Accept():
rl.debug(f"{stack.state}: ACCEPT") rl.info(f"{stack.state}: ACCEPT")
return stack, True # ? return stack, True # ?
case parser.Reduce(): case parser.Reduce():
rl.debug(f"{stack.state}: REDUCE {action.name} {action.count} ") rl.info(f"{stack.state}: REDUCE {action.name} {action.count} ")
new_stack = stack.pop(action.count) new_stack = stack.pop(action.count)
rl.debug(f" -> {new_stack.state}") rl.info(f" -> {new_stack.state}")
new_state = table.gotos[new_stack.state][action.name] new_state = table.gotos[new_stack.state][action.name]
rl.debug(f" goto {new_state}") rl.info(f" goto {new_state}")
stack = new_stack.push(new_state) stack = new_stack.push(new_state)
case parser.Error(): case parser.Error():
@ -159,10 +159,6 @@ class Repair:
if self.advance >= 3: if self.advance >= 3:
self.success = True self.success = True
def __repr__(self):
valstr = f"({self.value})" if self.value is not None else ""
return f"<Repair {self.repair.value}{valstr} cost:{self.cost} advance:{self.advance}>"
def neighbors( def neighbors(
self, self,
table: parser.ParseTable, table: parser.ParseTable,
@ -177,8 +173,8 @@ class Repair:
if rl.isEnabledFor(logging.INFO): if rl.isEnabledFor(logging.INFO):
valstr = f"({self.value})" if self.value is not None else "" valstr = f"({self.value})" if self.value is not None else ""
rl.debug(f"{self.repair.value}{valstr} @ {self.cost} input:{input_index}") rl.info(f"{self.repair.value}{valstr} @ {self.cost} input:{input_index}")
rl.debug(f" {','.join(str(s) for s in self.stack.flatten())}") rl.info(f" {','.join(str(s) for s in self.stack.flatten())}")
state = self.stack.state state = self.stack.state
@ -192,7 +188,7 @@ class Repair:
# necessary, producing a new version of the stack. Count up the # necessary, producing a new version of the stack. Count up the
# number of successful shifts. # number of successful shifts.
for token in table.actions[state].keys(): for token in table.actions[state].keys():
rl.debug(f" token: {token}") rl.info(f" token: {token}")
new_stack, success = self.stack.handle_token(table, token) new_stack, success = self.stack.handle_token(table, token)
if new_stack is None: if new_stack is None:
# Not clear why this is necessary, but I think state merging # Not clear why this is necessary, but I think state merging
@ -201,7 +197,7 @@ class Repair:
continue continue
if token == input[input_index].kind: if token == input[input_index].kind:
rl.debug(f" generate shift {token}") rl.info(f" generate shift {token}")
yield Repair( yield Repair(
repair=RepairAction.Shift, repair=RepairAction.Shift,
parent=self, parent=self,
@ -210,7 +206,7 @@ class Repair:
advance=1, # Move forward by one. advance=1, # Move forward by one.
) )
rl.debug(f" generate insert {token}") rl.info(f" generate insert {token}")
yield Repair( yield Repair(
repair=RepairAction.Insert, repair=RepairAction.Insert,
value=token, value=token,
@ -227,7 +223,7 @@ class Repair:
# delete-insert pairs, not insert-delete, because they are # delete-insert pairs, not insert-delete, because they are
# symmetrical and therefore a waste of time and memory.) # symmetrical and therefore a waste of time and memory.)
if self.repair != RepairAction.Insert: if self.repair != RepairAction.Insert:
rl.debug(f" generate delete") rl.info(f" generate delete")
yield Repair( yield Repair(
repair=RepairAction.Delete, repair=RepairAction.Delete,
parent=self, parent=self,
@ -238,7 +234,6 @@ class Repair:
def recover(table: parser.ParseTable, input: list[TokenValue], start: int, stack: ParseStack): def recover(table: parser.ParseTable, input: list[TokenValue], start: int, stack: ParseStack):
rl = recover_log
initial = Repair( initial = Repair(
repair=RepairAction.Base, repair=RepairAction.Base,
cost=0, cost=0,
@ -264,10 +259,6 @@ def recover(table: parser.ParseTable, input: list[TokenValue], start: int, stack
repairs.append(repair) repairs.append(repair)
repair = repair.parent repair = repair.parent
repairs.reverse() repairs.reverse()
if rl.isEnabledFor(logging.INFO):
rl.info("Recovered with actions:")
for repair in repairs:
rl.info(" " + repr(repair))
return repairs return repairs
for neighbor in repair.neighbors(table, input, start): for neighbor in repair.neighbors(table, input, start):
@ -331,29 +322,21 @@ class Parser:
case parser.Reduce(name=name, count=size, transparent=transparent): case parser.Reduce(name=name, count=size, transparent=transparent):
children: list[TokenValue | Tree] = [] children: list[TokenValue | Tree] = []
if size > 0: for _, c in stack[-size:]:
for _, c in stack[-size:]: if c is None:
if c is None: continue
continue elif isinstance(c, Tree) and c.name is None:
elif isinstance(c, Tree) and c.name is None: children.extend(c.children)
children.extend(c.children) else:
else: children.append(c)
children.append(c)
del stack[-size:]
start = children[0].start
end = children[-1].end
else:
start = end = current_token.start
value = Tree( value = Tree(
name=name if not transparent else None, name=name if not transparent else None,
start=start, start=children[0].start,
end=end, end=children[-1].end,
children=tuple(children), children=tuple(children),
) )
del stack[-size:]
goto = self.table.gotos[stack[-1][0]].get(name) goto = self.table.gotos[stack[-1][0]].get(name)
assert goto is not None assert goto is not None
stack.append((goto, value)) stack.append((goto, value))
@ -747,10 +730,7 @@ class Harness:
# Now that we know how many lines there are we can figure out how # Now that we know how many lines there are we can figure out how
# many characters we need for the line number... # many characters we need for the line number...
if len(lines) > 0: line_number_chars = int(math.log(len(lines), 10)) + 1
line_number_chars = int(math.log(len(lines), 10)) + 1
else:
line_number_chars = 1
# ...which lets us wrap the lines appropriately. # ...which lets us wrap the lines appropriately.
wrapper = textwrap.TextWrapper( wrapper = textwrap.TextWrapper(