Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: tools/lexer_generator/transition_keys.py

Issue 69293005: Experimental parser: add catch all rule (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 # Copyright 2013 the V8 project authors. All rights reserved. 1 # Copyright 2013 the V8 project authors. All rights reserved.
2 # Redistribution and use in source and binary forms, with or without 2 # Redistribution and use in source and binary forms, with or without
3 # modification, are permitted provided that the following conditions are 3 # modification, are permitted provided that the following conditions are
4 # met: 4 # met:
5 # 5 #
6 # * Redistributions of source code must retain the above copyright 6 # * Redistributions of source code must retain the above copyright
7 # notice, this list of conditions and the following disclaimer. 7 # notice, this list of conditions and the following disclaimer.
8 # * Redistributions in binary form must reproduce the above 8 # * Redistributions in binary form must reproduce the above
9 # copyright notice, this list of conditions and the following 9 # copyright notice, this list of conditions and the following
10 # disclaimer in the documentation and/or other materials provided 10 # disclaimer in the documentation and/or other materials provided
(...skipping 24 matching lines...) Expand all
35 "literal" : (257, 257), 35 "literal" : (257, 257),
36 } 36 }
37 __lower_bound = 0 37 __lower_bound = 0
38 __upper_bound = reduce(lambda acc, (k, v): max(acc, v[1]), __class_bounds.item s(), 0) 38 __upper_bound = reduce(lambda acc, (k, v): max(acc, v[1]), __class_bounds.item s(), 0)
39 39
40 __cached_keys = {} 40 __cached_keys = {}
41 41
42 __unique_key_counter = -1 42 __unique_key_counter = -1
43 43
44 @staticmethod 44 @staticmethod
45 def alphabet_iter():
46 for k, (lower, upper) in TransitionKey.__class_bounds.items():
47 for i in range(lower, upper + 1):
48 yield i
49
50 @staticmethod
45 def __in_latin_1(char): 51 def __in_latin_1(char):
46 bound = TransitionKey.__class_bounds["latin_1"] 52 bound = TransitionKey.__class_bounds["latin_1"]
47 return (bound[0] <= char and char <= bound[1]) 53 return (bound[0] <= char and char <= bound[1])
48 54
49 @staticmethod 55 @staticmethod
50 def __is_class_range(r): 56 def __is_class_range(r):
51 return r[0] == r[1] and not TransitionKey.__in_latin_1(r[0]) 57 return r[0] == r[1] and not TransitionKey.__in_latin_1(r[0])
52 58
53 @staticmethod 59 @staticmethod
54 def __is_unique_range(r): 60 def __is_unique_range(r):
(...skipping 24 matching lines...) Expand all
79 assert name == 'epsilon' 85 assert name == 'epsilon'
80 assert not name in TransitionKey.__cached_keys 86 assert not name in TransitionKey.__cached_keys
81 else: 87 else:
82 TransitionKey.__verify_ranges(ranges, True) 88 TransitionKey.__verify_ranges(ranges, True)
83 key = TransitionKey() 89 key = TransitionKey()
84 key.__ranges = tuple(ranges) # immutable 90 key.__ranges = tuple(ranges) # immutable
85 key.__name = name 91 key.__name = name
86 key.__cached_hash = None 92 key.__cached_hash = None
87 return key 93 return key
88 94
95 def __is_unique(self):
96 return len(self.__ranges) == 1 and self.__is_unique_range(self.__ranges[0])
97
89 @staticmethod 98 @staticmethod
90 def __cached_key(name, bounds_getter): 99 def __cached_key(name, bounds_getter):
91 if not name in TransitionKey.__cached_keys: 100 if not name in TransitionKey.__cached_keys:
92 bounds = bounds_getter(name) 101 bounds = bounds_getter(name)
93 TransitionKey.__cached_keys[name] = TransitionKey.__create(bounds, name) 102 TransitionKey.__cached_keys[name] = TransitionKey.__create(bounds, name)
94 return TransitionKey.__cached_keys[name] 103 return TransitionKey.__cached_keys[name]
95 104
96 @staticmethod 105 @staticmethod
97 def epsilon(): 106 def epsilon():
98 return TransitionKey.__cached_key("epsilon", lambda name : []) 107 return TransitionKey.__cached_key("epsilon", lambda name : [])
99 108
100 @staticmethod 109 @staticmethod
101 def any(): 110 def any():
102 return TransitionKey.__cached_key("any", 111 return TransitionKey.__cached_key("any",
103 lambda name : TransitionKey.__class_bounds.values()) 112 lambda name : TransitionKey.__class_bounds.values())
104 113
105 @staticmethod 114 @staticmethod
106 def single_char(char): 115 def single_char(char):
107 char = ord(char) 116 char = ord(char)
108 assert TransitionKey.__in_latin_1(char) 117 assert TransitionKey.__in_latin_1(char)
109 return TransitionKey.__create([(char, char)]) 118 return TransitionKey.__create([(char, char)])
110 119
111 @staticmethod 120 @staticmethod
112 def unique_key(name): 121 def unique(name):
113 def get_bounds(name): 122 def get_bounds(name):
114 bound = TransitionKey.__unique_key_counter 123 bound = TransitionKey.__unique_key_counter
115 TransitionKey.__unique_key_counter -= 1 124 TransitionKey.__unique_key_counter -= 1
116 return [(bound, bound)] 125 return [(bound, bound)]
117 name = "__" + name 126 name = "__" + name
118 return TransitionKey.__cached_key(name, get_bounds) 127 return TransitionKey.__cached_key(name, get_bounds)
119 128
120 @staticmethod 129 @staticmethod
121 def __process_graph(graph, ranges, key_map): 130 def __process_graph(graph, ranges, key_map):
122 key = graph[0] 131 key = graph[0]
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 to_push.append(v) 244 to_push.append(v)
236 else: 245 else:
237 ranges.append((left, v)) 246 ranges.append((left, v))
238 left = v + 1 247 left = v + 1
239 if to_push: 248 if to_push:
240 current = range_map[i + 1] 249 current = range_map[i + 1]
241 range_map[i + 1] = (current[0], sort(current[1] + to_push)) 250 range_map[i + 1] = (current[0], sort(current[1] + to_push))
242 return ranges 251 return ranges
243 252
244 @staticmethod 253 @staticmethod
245 def disjoint_keys(key_set): 254 def __disjoint_ranges_from_key_set(key_set):
246 key_set.discard(TransitionKey.epsilon())
247 if not key_set: 255 if not key_set:
248 return [] 256 return []
249 range_map = {} 257 range_map = {}
250 for x in key_set: 258 for x in key_set:
259 assert not x.__is_unique()
260 assert x != TransitionKey.epsilon
251 for r in x.__ranges: 261 for r in x.__ranges:
252 if not r[0] in range_map: 262 if not r[0] in range_map:
253 range_map[r[0]] = [] 263 range_map[r[0]] = []
254 range_map[r[0]].append(r[1]) 264 range_map[r[0]].append(r[1])
255 ranges = TransitionKey.__disjoint_keys(range_map) 265 ranges = TransitionKey.__disjoint_keys(range_map)
256 TransitionKey.__verify_ranges(ranges, False) 266 TransitionKey.__verify_ranges(ranges, False)
267 return ranges
268
269 @staticmethod
270 def disjoint_keys(key_set):
271 ranges = TransitionKey.__disjoint_ranges_from_key_set(key_set)
257 return map(lambda x : TransitionKey.__create([x]), ranges) 272 return map(lambda x : TransitionKey.__create([x]), ranges)
258 273
259 @staticmethod 274 @staticmethod
275 def inverse_key(key_set):
276 ranges = TransitionKey.__disjoint_ranges_from_key_set(key_set)
277 inverse = TransitionKey.__invert_ranges(ranges)
278 if not inverse:
279 return None
280 return TransitionKey.__create(inverse)
281
282 @staticmethod
260 def __key_from_ranges(invert, ranges): 283 def __key_from_ranges(invert, ranges):
261 range_map = {} 284 range_map = {}
262 for r in ranges: 285 for r in ranges:
263 if not r[0] in range_map: 286 if not r[0] in range_map:
264 range_map[r[0]] = [] 287 range_map[r[0]] = []
265 range_map[r[0]].append(r[1]) 288 range_map[r[0]].append(r[1])
266 ranges = TransitionKey.__disjoint_keys(range_map) 289 ranges = TransitionKey.__disjoint_keys(range_map)
267 ranges = TransitionKey.__merge_ranges(ranges) 290 ranges = TransitionKey.__merge_ranges(ranges)
268 if invert: 291 if invert:
269 ranges = TransitionKey.__invert_ranges(ranges) 292 ranges = TransitionKey.__invert_ranges(ranges)
(...skipping 19 matching lines...) Expand all
289 @staticmethod 312 @staticmethod
290 def merged_key(keys): 313 def merged_key(keys):
291 f = lambda acc, key: acc + list(key.__ranges) 314 f = lambda acc, key: acc + list(key.__ranges)
292 return TransitionKey.__key_from_ranges(False, reduce(f, keys, [])) 315 return TransitionKey.__key_from_ranges(False, reduce(f, keys, []))
293 316
294 @staticmethod 317 @staticmethod
295 def __invert_ranges(ranges): 318 def __invert_ranges(ranges):
296 inverted = [] 319 inverted = []
297 last = None 320 last = None
298 classes = set(TransitionKey.__class_bounds.values()) 321 classes = set(TransitionKey.__class_bounds.values())
299 classes.remove(TransitionKey.__class_bounds["latin_1"]) 322 latin_1 = TransitionKey.__class_bounds["latin_1"]
323 classes.remove(latin_1)
300 for r in ranges: 324 for r in ranges:
301 assert not TransitionKey.__is_unique_range(r) 325 assert not TransitionKey.__is_unique_range(r)
302 if TransitionKey.__is_class_range(r): 326 if TransitionKey.__is_class_range(r):
303 classes.remove(r) 327 classes.remove(r)
304 continue 328 continue
305 if last == None: 329 if last == None:
306 if r[0] != TransitionKey.__lower_bound: 330 if r[0] != TransitionKey.__lower_bound:
307 inverted.append((TransitionKey.__lower_bound, r[0] - 1)) 331 inverted.append((TransitionKey.__lower_bound, r[0] - 1))
308 elif last[1] + 1 < r[0]: 332 elif last[1] + 1 < r[0]:
309 inverted.append((last[1] + 1, r[0] - 1)) 333 inverted.append((last[1] + 1, r[0] - 1))
310 last = r 334 last = r
311 upper_bound = TransitionKey.__class_bounds["latin_1"][1] 335 upper_bound = latin_1[1]
312 if last != None and last[1] < upper_bound: 336 if last == None:
337 inverted.append(latin_1)
338 elif last[1] < upper_bound:
313 inverted.append((last[1] + 1, upper_bound)) 339 inverted.append((last[1] + 1, upper_bound))
314 inverted += list(classes) 340 inverted += list(classes)
315 return inverted 341 return inverted
OLDNEW
« src/lexer/lexer_py.re ('K') | « tools/lexer_generator/rule_parser_test.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698