mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Make grammar generation deterministic.
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
# Pgen imports
|
# Pgen imports
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ class ParserGenerator(object):
|
|||||||
def make_first(self, c, name):
|
def make_first(self, c, name):
|
||||||
rawfirst = self.first[name]
|
rawfirst = self.first[name]
|
||||||
first = {}
|
first = {}
|
||||||
for label in rawfirst:
|
for label in sorted(rawfirst):
|
||||||
ilabel = self.make_label(c, label)
|
ilabel = self.make_label(c, label)
|
||||||
##assert ilabel not in first # X X X failed on <> ... !=
|
##assert ilabel not in first # X X X failed on <> ... !=
|
||||||
first[ilabel] = 1
|
first[ilabel] = 1
|
||||||
@@ -138,8 +139,8 @@ class ParserGenerator(object):
|
|||||||
totalset[label] = 1
|
totalset[label] = 1
|
||||||
overlapcheck[label] = {label: 1}
|
overlapcheck[label] = {label: 1}
|
||||||
inverse = {}
|
inverse = {}
|
||||||
for label, itsfirst in iteritems(overlapcheck):
|
for label, itsfirst in sorted(overlapcheck.items()):
|
||||||
for symbol in itsfirst:
|
for symbol in sorted(itsfirst):
|
||||||
if symbol in inverse:
|
if symbol in inverse:
|
||||||
raise ValueError("rule %s is ambiguous; %s is in the"
|
raise ValueError("rule %s is ambiguous; %s is in the"
|
||||||
" first sets of %s as well as %s" %
|
" first sets of %s as well as %s" %
|
||||||
@@ -349,6 +350,9 @@ class NFAState(object):
|
|||||||
assert isinstance(next, NFAState)
|
assert isinstance(next, NFAState)
|
||||||
self.arcs.append((label, next))
|
self.arcs.append((label, next))
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(tuple(x[0] for x in self.arcs))
|
||||||
|
|
||||||
class DFAState(object):
|
class DFAState(object):
|
||||||
|
|
||||||
def __init__(self, nfaset, final):
|
def __init__(self, nfaset, final):
|
||||||
@@ -357,7 +361,10 @@ class DFAState(object):
|
|||||||
assert isinstance(final, NFAState)
|
assert isinstance(final, NFAState)
|
||||||
self.nfaset = nfaset
|
self.nfaset = nfaset
|
||||||
self.isfinal = final in nfaset
|
self.isfinal = final in nfaset
|
||||||
self.arcs = {} # map from label to DFAState
|
self.arcs = OrderedDict() # map from label to DFAState
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(tuple(self.arcs))
|
||||||
|
|
||||||
def addarc(self, next, label):
|
def addarc(self, next, label):
|
||||||
assert isinstance(label, str)
|
assert isinstance(label, str)
|
||||||
|
|||||||
Reference in New Issue
Block a user