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

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

Issue 82983002: Experimental parser: KeyEncoding class added (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
« no previous file with comments | « tools/lexer_generator/nfa_builder.py ('k') | tools/lexer_generator/rule_parser_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 13 matching lines...) Expand all
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 import ply.yacc as yacc 28 import ply.yacc as yacc
29 from automaton import Action 29 from automaton import Action
30 from rule_lexer import RuleLexer 30 from rule_lexer import RuleLexer
31 from regex_parser import RegexParser 31 from regex_parser import RegexParser
32 from nfa_builder import NfaBuilder 32 from nfa_builder import NfaBuilder
33 from dfa import Dfa 33 from dfa import Dfa
34 from transition_keys import TransitionKey 34 from transition_keys import TransitionKey, KeyEncoding
35 35
36 class RuleParserState: 36 class RuleParserState:
37 37
38 def __init__(self): 38 def __init__(self, encoding):
39 self.aliases = {} 39 self.aliases = {}
40 self.character_classes = {} 40 self.character_classes = {}
41 self.current_state = None 41 self.current_state = None
42 self.rules = {} 42 self.rules = {}
43 self.transitions = set() 43 self.transitions = set()
44 self.encoding = encoding
44 45
45 def parse(self, string): 46 def parse(self, string):
46 return RuleParser.parse(string, self) 47 return RuleParser.parse(string, self)
47 48
48 class RuleParser: 49 class RuleParser:
49 50
50 tokens = RuleLexer.tokens 51 tokens = RuleLexer.tokens
51 __rule_precedence_counter = 0 52 __rule_precedence_counter = 0
52 __keyword_transitions = set(['continue']) 53 __keyword_transitions = set(['continue'])
53 54
54 def __init__(self): 55 def __init__(self):
55 self.__state = None 56 self.__state = None
56 57
57 def p_statements(self, p): 58 def p_statements(self, p):
58 'statements : aliases rules' 59 'statements : aliases rules'
59 60
60 def p_aliases(self, p): 61 def p_aliases(self, p):
61 '''aliases : alias_rule aliases 62 '''aliases : alias_rule aliases
62 | empty''' 63 | empty'''
63 64
64 def p_alias_rule(self, p): 65 def p_alias_rule(self, p):
65 'alias_rule : IDENTIFIER EQUALS composite_regex SEMICOLON' 66 'alias_rule : IDENTIFIER EQUALS composite_regex SEMICOLON'
66 state = self.__state 67 state = self.__state
67 assert not p[1] in state.aliases 68 assert not p[1] in state.aliases
68 graph = p[3] 69 graph = p[3]
69 state.aliases[p[1]] = graph 70 state.aliases[p[1]] = graph
70 if graph[0] == 'CLASS' or graph[0] == 'NOT_CLASS': 71 if graph[0] == 'CLASS' or graph[0] == 'NOT_CLASS':
71 classes = state.character_classes 72 classes = state.character_classes
72 assert not p[1] in classes 73 assert not p[1] in classes
73 classes[p[1]] = TransitionKey.character_class(graph, classes) 74 encoding = state.encoding
75 classes[p[1]] = TransitionKey.character_class(encoding, graph, classes)
74 76
75 def p_rules(self, p): 77 def p_rules(self, p):
76 '''rules : state_change transition_rules rules 78 '''rules : state_change transition_rules rules
77 | empty''' 79 | empty'''
78 80
79 def p_state_change(self, p): 81 def p_state_change(self, p):
80 'state_change : GRAPH_OPEN IDENTIFIER GRAPH_CLOSE' 82 'state_change : GRAPH_OPEN IDENTIFIER GRAPH_CLOSE'
81 state = self.__state 83 state = self.__state
82 state.current_state = p[2] 84 state.current_state = p[2]
83 assert state.current_state 85 assert state.current_state
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 parser.__state = None 255 parser.__state = None
254 assert parser_state.transitions <= set(parser_state.rules.keys()) 256 assert parser_state.transitions <= set(parser_state.rules.keys())
255 257
256 class RuleProcessor(object): 258 class RuleProcessor(object):
257 259
258 def __init__(self, parser_state): 260 def __init__(self, parser_state):
259 self.__automata = {} 261 self.__automata = {}
260 self.__process_parser_state(parser_state) 262 self.__process_parser_state(parser_state)
261 263
262 @staticmethod 264 @staticmethod
263 def parse(string): 265 def parse(string, encoding_name):
264 parser_state = RuleParserState() 266 parser_state = RuleParserState(KeyEncoding.get(encoding_name))
265 RuleParser.parse(string, parser_state) 267 RuleParser.parse(string, parser_state)
266 return RuleProcessor(parser_state) 268 return RuleProcessor(parser_state)
267 269
268 def automata_iter(self): 270 def automata_iter(self):
269 return iter(self.__automata.items()) 271 return iter(self.__automata.items())
270 272
271 def default_automata(self): 273 def default_automata(self):
272 return self.__automata['default'] 274 return self.__automata['default']
273 275
274 class Automata(object): 276 class Automata(object):
275 277
276 def __init__(self, builder, graph): 278 def __init__(self, builder, graph):
277 self.__builder = builder 279 self.__builder = builder
278 self.__graph = graph 280 self.__graph = graph
279 self.__nfa = None 281 self.__nfa = None
280 self.__dfa = None 282 self.__dfa = None
281 self.__minimial_dfa = None 283 self.__minimial_dfa = None
282 284
283 def nfa(self): 285 def nfa(self):
284 if not self.__nfa: 286 if not self.__nfa:
285 self.__nfa = self.__builder.nfa(self.__graph) 287 self.__nfa = self.__builder.nfa(self.__graph)
286 return self.__nfa 288 return self.__nfa
287 289
288 def dfa(self): 290 def dfa(self):
289 if not self.__dfa: 291 if not self.__dfa:
290 (start, dfa_nodes) = self.nfa().compute_dfa() 292 (start, dfa_nodes) = self.nfa().compute_dfa()
291 self.__dfa = Dfa(start, dfa_nodes) 293 self.__dfa = Dfa(self.nfa().encoding(), start, dfa_nodes)
292 return self.__dfa 294 return self.__dfa
293 295
294 def minimal_dfa(self): 296 def minimal_dfa(self):
295 if not self.__minimial_dfa: 297 if not self.__minimial_dfa:
296 self.__minimial_dfa = self.dfa().minimize() 298 self.__minimial_dfa = self.dfa().minimize()
297 return self.__minimial_dfa 299 return self.__minimial_dfa
298 300
299 def __process_parser_state(self, parser_state): 301 def __process_parser_state(self, parser_state):
300 rule_map = {} 302 rule_map = {}
301 builder = NfaBuilder() 303 builder = NfaBuilder(parser_state.encoding, parser_state.character_classes)
302 builder.set_character_classes(parser_state.character_classes)
303 assert 'default' in parser_state.rules 304 assert 'default' in parser_state.rules
304 def process(subgraph, v): 305 def process(subgraph, v):
305 graphs = [] 306 graphs = []
306 continues = 0 307 continues = 0
307 for graph, precedence, action in v['regex']: 308 for graph, precedence, action in v['regex']:
308 (entry_action, match_action, transition) = action 309 (entry_action, match_action, transition) = action
309 if entry_action or match_action: 310 if entry_action or match_action:
310 action = Action(entry_action, match_action, precedence) 311 action = Action(entry_action, match_action, precedence)
311 graph = NfaBuilder.add_action(graph, action) 312 graph = NfaBuilder.add_action(graph, action)
312 if not transition: 313 if not transition:
(...skipping 19 matching lines...) Expand all
332 for k, v in parser_state.rules.items(): 333 for k, v in parser_state.rules.items():
333 if k == 'default': continue 334 if k == 'default': continue
334 process(k, v) 335 process(k, v)
335 process('default', parser_state.rules['default']) 336 process('default', parser_state.rules['default'])
336 # build the automata 337 # build the automata
337 for rule_name, graph in rule_map.items(): 338 for rule_name, graph in rule_map.items():
338 self.__automata[rule_name] = RuleProcessor.Automata(builder, graph) 339 self.__automata[rule_name] = RuleProcessor.Automata(builder, graph)
339 # process default_action 340 # process default_action
340 default_action = parser_state.rules['default']['default_action'] 341 default_action = parser_state.rules['default']['default_action']
341 self.default_action = Action(None, default_action[1]) if default_action else None 342 self.default_action = Action(None, default_action[1]) if default_action else None
OLDNEW
« no previous file with comments | « tools/lexer_generator/nfa_builder.py ('k') | tools/lexer_generator/rule_parser_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698