Compare commits
No commits in common. "0c3e6b211c74f79a68d7ef8ab16f86c9f14f0a80" and "bea790368615d7c7648559e2b7d51aff7045e96f" have entirely different histories.
0c3e6b211c
...
bea7903686
1 changed files with 22 additions and 42 deletions
48
harness.py
48
harness.py
|
|
@ -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,7 +322,6 @@ 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
|
||||||
|
|
@ -339,21 +329,14 @@ class Parser:
|
||||||
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(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue