mirror of
https://github.com/davidhalter/parso.git
synced 2026-08-12 02:42:49 +08:00
name -> nonterminal
This commit is contained in:
+19
-19
@@ -32,21 +32,21 @@ class ParserGenerator(object):
|
|||||||
# Map from grammar rule (nonterminal) name to a set of tokens.
|
# Map from grammar rule (nonterminal) name to a set of tokens.
|
||||||
self._first_terminals = {}
|
self._first_terminals = {}
|
||||||
|
|
||||||
names = list(self._nonterminal_to_dfas.keys())
|
nonterminals = list(self._nonterminal_to_dfas.keys())
|
||||||
names.sort()
|
nonterminals.sort()
|
||||||
for name in names:
|
for nonterminal in nonterminals:
|
||||||
if name not in self._first_terminals:
|
if nonterminal not in self._first_terminals:
|
||||||
self._calculate_first_terminals(name)
|
self._calculate_first_terminals(nonterminal)
|
||||||
|
|
||||||
i = 256 + len(grammar.nonterminal2number)
|
i = 256 + len(grammar.nonterminal2number)
|
||||||
grammar.nonterminal2number[name] = i
|
grammar.nonterminal2number[nonterminal] = i
|
||||||
grammar.number2nonterminal[i] = name
|
grammar.number2nonterminal[i] = nonterminal
|
||||||
|
|
||||||
# Now that we have calculated the first terminals, we are sure that
|
# Now that we have calculated the first terminals, we are sure that
|
||||||
# there is no left recursion or ambiguities.
|
# there is no left recursion or ambiguities.
|
||||||
|
|
||||||
for name in names:
|
for nonterminal in nonterminals:
|
||||||
dfas = self._nonterminal_to_dfas[name]
|
dfas = self._nonterminal_to_dfas[nonterminal]
|
||||||
states = []
|
states = []
|
||||||
for state in dfas:
|
for state in dfas:
|
||||||
arcs = []
|
arcs = []
|
||||||
@@ -56,11 +56,11 @@ class ParserGenerator(object):
|
|||||||
arcs.append((0, dfas.index(state)))
|
arcs.append((0, dfas.index(state)))
|
||||||
states.append(arcs)
|
states.append(arcs)
|
||||||
grammar.states.append(states)
|
grammar.states.append(states)
|
||||||
grammar.dfas[grammar.nonterminal2number[name]] = (states, self._make_first(grammar, name))
|
grammar.dfas[grammar.nonterminal2number[nonterminal]] = (states, self._make_first(grammar, nonterminal))
|
||||||
return grammar
|
return grammar
|
||||||
|
|
||||||
def _make_first(self, grammar, name):
|
def _make_first(self, grammar, nonterminal):
|
||||||
rawfirst = self._first_terminals[name]
|
rawfirst = self._first_terminals[nonterminal]
|
||||||
first = set()
|
first = set()
|
||||||
for label in rawfirst:
|
for label in rawfirst:
|
||||||
ilabel = self._make_label(grammar, label)
|
ilabel = self._make_label(grammar, label)
|
||||||
@@ -74,7 +74,7 @@ class ParserGenerator(object):
|
|||||||
if label[0].isalpha():
|
if label[0].isalpha():
|
||||||
# Either a nonterminal name or a named token
|
# Either a nonterminal name or a named token
|
||||||
if label in grammar.nonterminal2number:
|
if label in grammar.nonterminal2number:
|
||||||
# A nonterminal name (a non-terminal)
|
# A nonterminal name
|
||||||
if label in grammar.nonterminal2label:
|
if label in grammar.nonterminal2label:
|
||||||
return grammar.nonterminal2label[label]
|
return grammar.nonterminal2label[label]
|
||||||
else:
|
else:
|
||||||
@@ -114,9 +114,9 @@ class ParserGenerator(object):
|
|||||||
grammar.tokens[itoken] = ilabel
|
grammar.tokens[itoken] = ilabel
|
||||||
return ilabel
|
return ilabel
|
||||||
|
|
||||||
def _calculate_first_terminals(self, name):
|
def _calculate_first_terminals(self, nonterminal):
|
||||||
dfas = self._nonterminal_to_dfas[name]
|
dfas = self._nonterminal_to_dfas[nonterminal]
|
||||||
self._first_terminals[name] = None # dummy to detect left recursion
|
self._first_terminals[nonterminal] = None # dummy to detect left recursion
|
||||||
# We only need to check the first dfa. All the following ones are not
|
# We only need to check the first dfa. All the following ones are not
|
||||||
# interesting to find first terminals.
|
# interesting to find first terminals.
|
||||||
state = dfas[0]
|
state = dfas[0]
|
||||||
@@ -133,7 +133,7 @@ class ParserGenerator(object):
|
|||||||
fset = self._first_terminals[nonterminal_or_string]
|
fset = self._first_terminals[nonterminal_or_string]
|
||||||
else:
|
else:
|
||||||
if fset is None:
|
if fset is None:
|
||||||
raise ValueError("left recursion for rule %r" % name)
|
raise ValueError("left recursion for rule %r" % nonterminal)
|
||||||
totalset.update(fset)
|
totalset.update(fset)
|
||||||
overlapcheck[nonterminal_or_string] = fset
|
overlapcheck[nonterminal_or_string] = fset
|
||||||
else:
|
else:
|
||||||
@@ -147,9 +147,9 @@ class ParserGenerator(object):
|
|||||||
if terminal in inverse:
|
if terminal 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" %
|
||||||
(name, terminal, nonterminal_or_string, inverse[terminal]))
|
(nonterminal, terminal, nonterminal_or_string, inverse[terminal]))
|
||||||
inverse[terminal] = nonterminal_or_string
|
inverse[terminal] = nonterminal_or_string
|
||||||
self._first_terminals[name] = totalset
|
self._first_terminals[nonterminal] = totalset
|
||||||
|
|
||||||
|
|
||||||
class DFAState(object):
|
class DFAState(object):
|
||||||
|
|||||||
Reference in New Issue
Block a user