Revision: 18729
Author: [email protected]
Date: Wed Jan 22 09:26:03 2014 UTC
Log: Experimental parser: handling unique keys in merges
[email protected]
BUG=
Review URL: https://codereview.chromium.org/132693018
http://code.google.com/p/v8/source/detail?r=18729
Modified:
/branches/experimental/parser/tools/lexer_generator/nfa_builder.py
/branches/experimental/parser/tools/lexer_generator/rule_parser.py
/branches/experimental/parser/tools/lexer_generator/transition_keys.py
=======================================
--- /branches/experimental/parser/tools/lexer_generator/nfa_builder.py Tue
Jan 21 16:05:51 2014 UTC
+++ /branches/experimental/parser/tools/lexer_generator/nfa_builder.py Wed
Jan 22 09:26:03 2014 UTC
@@ -150,8 +150,8 @@
self.__patch_ends(ends, state['start_node'])
return (start, [])
- def __catch_all(self, graph):
- return self.__key_state(TransitionKey.unique('catch_all'))
+ def __unique_key(self, graph):
+ return self.__key_state(TransitionKey.unique(graph[1]))
def __join(self, graph):
(graph, name, subgraph) = graph[1:]
@@ -311,8 +311,8 @@
return ('CONTINUE', graph)
@staticmethod
- def catch_all():
- return ('CATCH_ALL',)
+ def unique_key(name):
+ return ('UNIQUE_KEY', name)
@staticmethod
def join_subgraph(graph, name, subgraph):
=======================================
--- /branches/experimental/parser/tools/lexer_generator/rule_parser.py Tue
Jan 21 15:06:44 2014 UTC
+++ /branches/experimental/parser/tools/lexer_generator/rule_parser.py Wed
Jan 22 09:26:03 2014 UTC
@@ -87,7 +87,7 @@
if not state.current_state in state.rules:
state.rules[state.current_state] = {
'default_action': None,
- 'catch_all' : None,
+ 'uniques' : {},
'regex' : []
}
p[0] = state.current_state
@@ -113,8 +113,9 @@
assert not rules['default_action']
rules['default_action'] = action
elif p[1] == 'catch_all':
- assert not rules['catch_all']
- rules['catch_all'] = (precedence, action)
+ assert p[1] not in rules['uniques']
+ rules['uniques'][p[1]] = True
+ rules['regex'].append((NfaBuilder.unique_key(p[1]), precedence,
action))
else:
regex = p[1]
rules['regex'].append((regex, precedence, action))
@@ -317,10 +318,6 @@
graph = NfaBuilder.join_subgraph(
graph, transition, rule_map[transition])
graphs.append(graph)
- if v['catch_all']:
- (precedence, catch_all) = v['catch_all']
- assert catch_all == (None, None, 'continue'), "unimplemented"
- graphs.append(NfaBuilder.add_continue(NfaBuilder.catch_all()))
graph = NfaBuilder.or_graphs(graphs)
rule_map[subgraph] = graph
# process first the subgraphs, then the default graph
=======================================
--- /branches/experimental/parser/tools/lexer_generator/transition_keys.py
Mon Nov 25 12:18:26 2013 UTC
+++ /branches/experimental/parser/tools/lexer_generator/transition_keys.py
Wed Jan 22 09:26:03 2014 UTC
@@ -126,19 +126,17 @@
@staticmethod
def __verify_ranges(encoding, ranges, check_merged):
assert ranges
- if len(ranges) == 1 and TransitionKey.__is_unique_range(ranges[0]):
- return
last = None
for r in ranges:
- assert not TransitionKey.__is_unique_range(r)
- r_is_class = encoding.is_class_range(r)
+ r_is_class = (TransitionKey.__is_unique_range(r) or
+ encoding.is_class_range(r))
# Assert that the ranges are in order.
if last != None and check_merged:
assert last[1] + 1 < r[0] or r_is_class
- last = r
-
- def __is_unique(self):
- return len(self.__ranges) == 1 and
self.__is_unique_range(self.__ranges[0])
+ if r_is_class:
+ last = None
+ else:
+ last = r
@staticmethod
def __cached_key(encoding, name, bounds_getter):
@@ -237,7 +235,7 @@
def is_superset_of_key(self, key):
'''Returns true if 'key' is a sub-key of this TransitionKey.'''
assert isinstance(key, self.__class__)
- assert key != TransitionKey.epsilon() and not key.__is_unique()
+ assert key != TransitionKey.epsilon()
assert len(key.__ranges) == 1
subkey = key.__ranges[0]
matches = False
@@ -278,14 +276,24 @@
@staticmethod
def __class_name(encoding, r):
for name, v in encoding.class_range_iter():
- if r == v: return name
+ if r == v:
+ return name
+ assert False
+
+ @staticmethod
+ def __unique_name(r):
+ for name, v in TransitionKey.__cached_keys['no_encoding'].items():
+ if v.__ranges and r == v.__ranges[0]:
+ return name[2:]
assert False
def range_iter(self, encoding):
- assert not self == TransitionKey.epsilon() and not self.__is_unique()
+ assert not self == TransitionKey.epsilon()
for r in self.__ranges:
- if encoding.is_class_range(r):
- yield ('CLASS', TransitionKey.__class_name(encoding, r))
+ if self.__is_unique_range(r):
+ yield ('UNIQUE', self.__unique_name(r))
+ elif encoding.is_class_range(r):
+ yield ('CLASS', self.__class_name(encoding, r))
else:
yield ('PRIMARY_RANGE', r)
@@ -297,6 +305,8 @@
@staticmethod
def __range_str(encoding, r):
+ if TransitionKey.__is_unique_range(r):
+ return TransitionKey.__unique_name(r)
if encoding and encoding.is_class_range(r):
return TransitionKey.__class_name(encoding, r)
def to_str(x):
@@ -364,7 +374,6 @@
return []
range_map = {}
for x in key_set:
- assert not x.__is_unique()
assert x != TransitionKey.epsilon()
for r in x.__ranges:
if not r[0] in range_map:
@@ -404,6 +413,7 @@
def __key_from_ranges(encoding, invert, ranges):
range_map = {}
for r in ranges:
+ assert r
if not r[0] in range_map:
range_map[r[0]] = []
range_map[r[0]].append(r[1])
@@ -418,10 +428,11 @@
merged = []
last = None
for r in ranges:
- assert not TransitionKey.__is_unique_range(r)
if last == None:
last = r
- elif (last[1] + 1 == r[0] and not encoding.is_class_range(r)):
+ elif (last[1] + 1 == r[0] and
+ not TransitionKey.__is_unique_range(r) and
+ not encoding.is_class_range(r)):
last = (last[0], r[1])
else:
merged.append(last)
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.