| |
| |
| |
| |
| |
|
|
| |
| from io import StringIO |
| from antlr4 import DFA |
| from antlr4.Utils import str_list |
| from antlr4.dfa.DFAState import DFAState |
|
|
|
|
| class DFASerializer(object): |
| __slots__ = ('dfa', 'literalNames', 'symbolicNames') |
|
|
| def __init__(self, dfa:DFA, literalNames:list=None, symbolicNames:list=None): |
| self.dfa = dfa |
| self.literalNames = literalNames |
| self.symbolicNames = symbolicNames |
|
|
| def __str__(self): |
| if self.dfa.s0 is None: |
| return None |
| with StringIO() as buf: |
| for s in self.dfa.sortedStates(): |
| n = 0 |
| if s.edges is not None: |
| n = len(s.edges) |
| for i in range(0, n): |
| t = s.edges[i] |
| if t is not None and t.stateNumber != 0x7FFFFFFF: |
| buf.write(self.getStateString(s)) |
| label = self.getEdgeLabel(i) |
| buf.write("-") |
| buf.write(label) |
| buf.write("->") |
| buf.write(self.getStateString(t)) |
| buf.write('\n') |
| output = buf.getvalue() |
| if len(output)==0: |
| return None |
| else: |
| return output |
|
|
| def getEdgeLabel(self, i:int): |
| if i==0: |
| return "EOF" |
| if self.literalNames is not None and i<=len(self.literalNames): |
| return self.literalNames[i-1] |
| elif self.symbolicNames is not None and i<=len(self.symbolicNames): |
| return self.symbolicNames[i-1] |
| else: |
| return str(i-1) |
|
|
| def getStateString(self, s:DFAState): |
| n = s.stateNumber |
| baseStateStr = ( ":" if s.isAcceptState else "") + "s" + str(n) + ( "^" if s.requiresFullContext else "") |
| if s.isAcceptState: |
| if s.predicates is not None: |
| return baseStateStr + "=>" + str_list(s.predicates) |
| else: |
| return baseStateStr + "=>" + str(s.prediction) |
| else: |
| return baseStateStr |
|
|
| class LexerDFASerializer(DFASerializer): |
|
|
| def __init__(self, dfa:DFA): |
| super().__init__(dfa, None) |
|
|
| def getEdgeLabel(self, i:int): |
| return "'" + chr(i) + "'" |
|
|