mirror of
https://github.com/davidhalter/parso.git
synced 2025-12-10 14:41:58 +08:00
Use the name first_terminals instead of first
This commit is contained in:
@@ -29,19 +29,21 @@ class ParserGenerator(object):
|
|||||||
self._nonterminal_to_dfas = rule_to_dfas
|
self._nonterminal_to_dfas = rule_to_dfas
|
||||||
|
|
||||||
def make_grammar(self, grammar):
|
def make_grammar(self, grammar):
|
||||||
self._first = {} # map from symbol name to set of tokens
|
self._first_terminals = {} # map from symbol name to set of tokens
|
||||||
|
|
||||||
names = list(self._nonterminal_to_dfas.keys())
|
names = list(self._nonterminal_to_dfas.keys())
|
||||||
names.sort()
|
names.sort()
|
||||||
for name in names:
|
for name in names:
|
||||||
if name not in self._first:
|
if name not in self._first_terminals:
|
||||||
self._calcfirst(name)
|
self._calculate_first_terminals(name)
|
||||||
#print name, self._first[name].keys()
|
|
||||||
|
|
||||||
i = 256 + len(grammar.symbol2number)
|
i = 256 + len(grammar.symbol2number)
|
||||||
grammar.symbol2number[name] = i
|
grammar.symbol2number[name] = i
|
||||||
grammar.number2symbol[i] = name
|
grammar.number2symbol[i] = name
|
||||||
|
|
||||||
|
# Now that we have calculated the first terminals, we are sure that
|
||||||
|
# there is no left recursion or ambiguities.
|
||||||
|
|
||||||
for name in names:
|
for name in names:
|
||||||
dfas = self._nonterminal_to_dfas[name]
|
dfas = self._nonterminal_to_dfas[name]
|
||||||
states = []
|
states = []
|
||||||
@@ -57,7 +59,7 @@ class ParserGenerator(object):
|
|||||||
return grammar
|
return grammar
|
||||||
|
|
||||||
def _make_first(self, grammar, name):
|
def _make_first(self, grammar, name):
|
||||||
rawfirst = self._first[name]
|
rawfirst = self._first_terminals[name]
|
||||||
first = set()
|
first = set()
|
||||||
for label in rawfirst:
|
for label in rawfirst:
|
||||||
ilabel = self._make_label(grammar, label)
|
ilabel = self._make_label(grammar, label)
|
||||||
@@ -111,9 +113,11 @@ class ParserGenerator(object):
|
|||||||
grammar.tokens[itoken] = ilabel
|
grammar.tokens[itoken] = ilabel
|
||||||
return ilabel
|
return ilabel
|
||||||
|
|
||||||
def _calcfirst(self, name):
|
def _calculate_first_terminals(self, name):
|
||||||
dfas = self._nonterminal_to_dfas[name]
|
dfas = self._nonterminal_to_dfas[name]
|
||||||
self._first[name] = None # dummy to detect left recursion
|
self._first_terminals[name] = None # dummy to detect left recursion
|
||||||
|
# We only need to check the first dfa. All the following ones are not
|
||||||
|
# interesting to find first terminals.
|
||||||
state = dfas[0]
|
state = dfas[0]
|
||||||
totalset = set()
|
totalset = set()
|
||||||
overlapcheck = {}
|
overlapcheck = {}
|
||||||
@@ -122,10 +126,10 @@ class ParserGenerator(object):
|
|||||||
# It's a nonterminal and we have either a left recursion issue
|
# It's a nonterminal and we have either a left recursion issue
|
||||||
# in the grammare or we have to recurse.
|
# in the grammare or we have to recurse.
|
||||||
try:
|
try:
|
||||||
fset = self._first[nonterminal_or_string]
|
fset = self._first_terminals[nonterminal_or_string]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
self._calcfirst(nonterminal_or_string)
|
self._calculate_first_terminals(nonterminal_or_string)
|
||||||
fset = self._first[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" % name)
|
||||||
@@ -143,7 +147,7 @@ class ParserGenerator(object):
|
|||||||
" first sets of %s as well as %s" %
|
" first sets of %s as well as %s" %
|
||||||
(name, symbol, nonterminal_or_string, inverse[symbol]))
|
(name, symbol, nonterminal_or_string, inverse[symbol]))
|
||||||
inverse[symbol] = nonterminal_or_string
|
inverse[symbol] = nonterminal_or_string
|
||||||
self._first[name] = totalset
|
self._first_terminals[name] = totalset
|
||||||
|
|
||||||
|
|
||||||
class DFAState(object):
|
class DFAState(object):
|
||||||
|
|||||||
Reference in New Issue
Block a user