Skip to content

Commit f49ce44

Browse files
committed
Defines conflict model
1 parent 8bc83b2 commit f49ce44

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
from .entry import Entry
2+
from .conflict import Conflict, ConflictType
23
from .table import LR0ParsingTable, SLRParsingTable
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
from enum import Enum
2+
3+
from syntactes import Token
4+
from syntactes._action import Action, ActionType
5+
from syntactes._state import LR0State
6+
7+
8+
class ConflictType(Enum):
9+
SHIFT_SHIFT = "shift/shift"
10+
SHIFT_REDUCE = "shift/reduce"
11+
REDUCE_REDUCE = "reduce/reduce"
12+
NO_CONFLICT = "NO_CONFLICT"
13+
14+
15+
class Conflict:
16+
def __init__(self, state: LR0State, token: Token, actions: list[Action]) -> None:
17+
self.state = state
18+
self.token = token
19+
self.actions = actions
20+
self._conflict_type = None
21+
22+
def pretty_str(self) -> str:
23+
"""
24+
Returns a pretty-formatted string with conflict details.
25+
"""
26+
string = f"{self.conflict_type.value} conflict in state {self.state}\n"
27+
string += f"Available actions on input token '{self.token}':\n"
28+
for action in self.actions:
29+
if action.action_type == ActionType.SHIFT:
30+
string += f"shift to {action.actionable}\n"
31+
elif action.action_type == ActionType.REDUCE:
32+
string += f"reduce by {action.actionable}\n"
33+
else:
34+
string += f"{action.action_type}, {action.actionable}\n"
35+
36+
return string
37+
38+
@property
39+
def conflict_type(self) -> ConflictType:
40+
if self._conflict_type is None:
41+
self._conflict_type = self._create_type()
42+
43+
return self._conflict_type
44+
45+
def _create_type(self) -> ConflictType:
46+
if not len(self.actions) > 1:
47+
return ConflictType.NO_CONFLICT
48+
49+
action_types = set(map(lambda a: a.action_type, self.actions))
50+
51+
if ActionType.SHIFT not in action_types:
52+
if ActionType.REDUCE not in action_types:
53+
return ConflictType.NO_CONFLICT
54+
55+
return ConflictType.REDUCE_REDUCE
56+
57+
if ActionType.REDUCE not in action_types:
58+
return ConflictType.SHIFT_SHIFT
59+
60+
return ConflictType.SHIFT_REDUCE
61+
62+
def __repr__(self) -> str:
63+
return f"<Conflict: {str(self)}>"
64+
65+
def __str__(self) -> str:
66+
return f"{self.state}, {self.token}, {self.actions}"

0 commit comments

Comments
 (0)