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

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

Issue 68803002: Experimental lexer generator: Code generator skeleton. (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 | « no previous file | tools/lexer_generator/generator.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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 def actions(self): 46 def actions(self):
47 return self.__actions 47 return self.__actions
48 48
49 def add_transition(self, key, state): 49 def add_transition(self, key, state):
50 assert not self.__transitions.has_key(key) 50 assert not self.__transitions.has_key(key)
51 self.__transitions[key] = state 51 self.__transitions[key] = state
52 52
53 def transitions(self): 53 def transitions(self):
54 return self.__transitions 54 return self.__transitions
55 55
56 def to_code(self):
57 # FIXME: add different check types (if, switch, lookup table)
58 # FIXME: add action + break / continue
59 # FIXME: add default action
60 code = '''
61 code_%s:
62 fprintf(stderr, "state %s, char at hand is %%c\\n", c);
63 ''' % (self.node_number(), self.node_number())
64
65 for key, state in self.__transitions.items():
66 code += key.to_code()
67 code += ''' {
68 c = *(++cursor);
69 goto code_%s;
70 }''' % state.node_number()
71 return code
72
56 class Dfa(Automaton): 73 class Dfa(Automaton):
57 74
58 def __init__(self, start_name, mapping): 75 def __init__(self, start_name, mapping):
59 super(Dfa, self).__init__() 76 super(Dfa, self).__init__()
60 self.__terminal_set = set() 77 self.__terminal_set = set()
61 name_map = {} 78 self.__name_map = {}
62 for i, (name, node_data) in enumerate(mapping.items()): 79 for i, (name, node_data) in enumerate(mapping.items()):
63 node = DfaState(name, i, node_data['actions']) 80 node = DfaState(name, i, node_data['actions'])
64 name_map[name] = node 81 self.__name_map[name] = node
65 if node_data['terminal']: 82 if node_data['terminal']:
66 self.__terminal_set.add(node) 83 self.__terminal_set.add(node)
67 for name, node_data in mapping.items(): 84 for name, node_data in mapping.items():
68 node = name_map[name] 85 node = self.__name_map[name]
69 inversion = {} 86 inversion = {}
70 for key, state in node_data['transitions'].items(): 87 for key, state in node_data['transitions'].items():
71 if not state in inversion: 88 if not state in inversion:
72 inversion[state] = [] 89 inversion[state] = []
73 inversion[state].append(key) 90 inversion[state].append(key)
74 for state, keys in inversion.items(): 91 for state, keys in inversion.items():
75 merged_key = TransitionKey.merged_key(keys) 92 merged_key = TransitionKey.merged_key(keys)
76 node.add_transition(merged_key, name_map[state]) 93 node.add_transition(merged_key, self.__name_map[state])
77 self.__start = name_map[start_name] 94 self.__start = self.__name_map[start_name]
78 assert self.__terminal_set 95 assert self.__terminal_set
79 96
80 @staticmethod 97 @staticmethod
81 def __match_char(state, char): 98 def __match_char(state, char):
82 match = [s for k, s in state.transitions().items() if k.matches_char(char)] 99 match = [s for k, s in state.transitions().items() if k.matches_char(char)]
83 if not match: return None 100 if not match: return None
84 assert len(match) == 1 101 assert len(match) == 1
85 return match[0] 102 return match[0]
86 103
87 def collect_actions(self, string): 104 def collect_actions(self, string):
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 137
121 def __visit_all_edges(self, visitor, state): 138 def __visit_all_edges(self, visitor, state):
122 edge = set([self.__start]) 139 edge = set([self.__start])
123 next_edge = lambda node: set(node.transitions().values()) 140 next_edge = lambda node: set(node.transitions().values())
124 return self.visit_edges(edge, next_edge, visitor, state) 141 return self.visit_edges(edge, next_edge, visitor, state)
125 142
126 def to_dot(self): 143 def to_dot(self):
127 iterator = lambda visitor, state: self.__visit_all_edges(visitor, state) 144 iterator = lambda visitor, state: self.__visit_all_edges(visitor, state)
128 state_iterator = lambda x : [x] 145 state_iterator = lambda x : [x]
129 return self.generate_dot(self.__start, self.__terminal_set, iterator, state_ iterator) 146 return self.generate_dot(self.__start, self.__terminal_set, iterator, state_ iterator)
147
148 def to_code(self):
149 code = '''
150 char c = *cursor;
151 goto code_%s;
152 ''' % (self.__start.node_number())
153 for n in self.__name_map.values():
154 code += n.to_code()
155 return code
OLDNEW
« no previous file with comments | « no previous file | tools/lexer_generator/generator.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698