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

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

Issue 73943002: Experimental parser: abstract code generator a bit (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/code_generator_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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 code += 'yych <= %s' % r[1] 45 code += 'yych <= %s' % r[1]
46 elif r[1] == 255: # FIXME: this should depend on the char type maybe?? 46 elif r[1] == 255: # FIXME: this should depend on the char type maybe??
47 code += 'yych >= %s' % r[0] 47 code += 'yych >= %s' % r[0]
48 else: 48 else:
49 code += '(yych >= %s && yych <= %s)' % (r[0], r[1]) 49 code += '(yych >= %s && yych <= %s)' % (r[0], r[1])
50 first = False 50 first = False
51 code += ')' 51 code += ')'
52 return code 52 return code
53 53
54 @staticmethod 54 @staticmethod
55 def dfa_state_to_code(state, start_node_number): 55 def __terminate_code(value):
56 assert value == None
57 return 'PUSH_TOKEN(Token::EOS); return 0;'
58
59 @staticmethod
60 def __terminate_illegal_code(value):
61 assert value == None
62 return 'PUSH_TOKEN(Token::ILLEGAL); return 1;'
63
64 @staticmethod
65 def __skip_code(value):
66 assert value == None
67 return 'SKIP(); goto code_start;'
68
69 @staticmethod
70 def __push_line_terminator_code(value):
71 assert value == None
72 return 'PUSH_LINE_TERMINATOR();'
73
74 @staticmethod
75 def __push_token_code(value):
76 assert value != None
77 return 'PUSH_TOKEN(Token::%s);' % value
78
79 @staticmethod
80 def __code_code(value):
81 assert value != None
82 return '%s\n' % value
83
84 def __init__(self, dfa, default_action):
85 self.__dfa = dfa
86 self.__start_node_number = dfa.start_state().node_number()
87 self.__default_action = default_action
88 # make this better
89 self.__action_code_map = {
90 "terminate" : self.__terminate_code,
91 "terminate_illegal" : self.__terminate_illegal_code,
92 "push_token" : self.__push_token_code,
93 "push_line_terminator" : self.__push_line_terminator_code,
94 "skip" : self.__skip_code,
95 "code" : self.__code_code,
96 }
97
98 def __dfa_state_to_code(self, state):
99 start_node_number = self.__start_node_number
56 # FIXME: add different check types (if, switch, lookup table) 100 # FIXME: add different check types (if, switch, lookup table)
57 # FIXME: add action + break / continue 101 # FIXME: add action + break / continue
58 # FIXME: add default action 102 # FIXME: add default action
59 code = '' 103 code = ''
60 if start_node_number == state.node_number(): 104 if start_node_number == state.node_number():
61 code += ''' 105 code += '''
62 //code_start: 106 code_start:
63 ''' 107 '''
64 code += ''' 108 code += '''
65 code_%s: 109 code_%s:
66 //fprintf(stderr, "state %s\\n"); 110 //fprintf(stderr, "state %s\\n");
67 ''' % (state.node_number(), 111 ''' % (state.node_number(),
68 state.node_number()) 112 state.node_number())
69 113
70 entry_action = state.action().entry_action() if state.action() else None 114 entry_action = state.action().entry_action() if state.action() else None
71 match_action = state.action().match_action() if state.action() else None 115 match_action = state.action().match_action() if state.action() else None
72 print entry_action
73
74 if (entry_action and entry_action[0] != 'terminate' and
75 entry_action[0] != 'terminate_illegal' and entry_action[0] != 'code' and
76 entry_action[0] != 'push_token' and
77 entry_action[0] != 'push_line_terminator' and entry_action[0] != 'skip') :
78 raise Exception("unknown type %s" % entry_action[0])
79 116
80 if entry_action: 117 if entry_action:
81 if entry_action[0] == 'terminate': 118 code += self.__action_code_map[entry_action[0]](entry_action[1])
82 code += 'PUSH_TOKEN(Token::EOS); return 0;'
83 return code
84 elif entry_action[0] == 'terminate_illegal':
85 code += 'PUSH_TOKEN(Token::ILLEGAL); return 1;'
86 return code
87 elif entry_action[0] == 'skip':
88 code += 'SKIP(); goto code_start;'
89 return code
90 elif entry_action[0] == 'code':
91 code += '%s\n' % entry_action[1]
92 119
93 code += ''' 120 code += '''
94 //fprintf(stderr, "char at hand is %c (%d)\\n", yych, yych);\n''' 121 //fprintf(stderr, "char at hand is %c (%d)\\n", yych, yych);\n'''
95 122
96 for key, s in state.transitions().items(): 123 for key, s in state.transitions().items():
97 code += CodeGenerator.key_to_code(key) 124 code += CodeGenerator.key_to_code(key)
98 code += ''' { 125 code += ''' {
99 FORWARD(); 126 FORWARD();
100 goto code_%s; 127 goto code_%s;
101 } 128 }
102 ''' % s.node_number() 129 ''' % s.node_number()
103 130
104 if match_action: 131 if match_action:
105 if match_action[0] == 'push_token': 132 code += self.__action_code_map[match_action[0]](match_action[1])
106 content = 'PUSH_TOKEN(Token::%s);' % match_action[1] 133 code += 'goto code_%s;\n' % start_node_number
107 code += '%s\ngoto code_%s;\n' % (content, 134 else:
108 start_node_number) 135 code += " // FIXME: goto where"
109 code += " // FIXME: goto where"
110 return code 136 return code
111 137
112 @staticmethod 138 def __process(self):
113 def rule_processor_to_code(rule_processor, use_mdfa): 139 dfa = self.__dfa
114 if use_mdfa: 140 default_action = self.__default_action
115 dfa = rule_processor.default_automata().minimal_dfa() 141 start_node_number = self.__start_node_number
116 else:
117 dfa = rule_processor.default_automata().dfa()
118 start_node_number = dfa.start_state().node_number()
119 code = ''' 142 code = '''
120 #include "lexer/even-more-experimental-scanner.h" 143 #include "lexer/even-more-experimental-scanner.h"
121 144
122 namespace v8 { 145 namespace v8 {
123 namespace internal { 146 namespace internal {
124 uint32_t EvenMoreExperimentalScanner::DoLex() { 147 uint32_t EvenMoreExperimentalScanner::DoLex() {
125 YYCTYPE yych = *cursor_; 148 YYCTYPE yych = *cursor_;
126 goto code_%s; 149 goto code_%s;
127 ''' % start_node_number 150 ''' % start_node_number
128 def f(state, code): 151 def f(state, code):
129 code += CodeGenerator.dfa_state_to_code(state, start_node_number) 152 code += self.__dfa_state_to_code(state)
130 return code 153 return code
131 code = dfa.visit_all_states(f, code) 154 code = dfa.visit_all_states(f, code)
132 155
133 default_action_code = '' 156 default_action_code = ''
134 action = rule_processor.default_action.entry_action() if rule_processor.defa ult_action else None 157 action = default_action.entry_action() if default_action else None
135 if action: 158 if action:
136 if action[0] == 'push_token': 159 if action[0] == 'push_token':
137 default_action_code = ''' 160 default_action_code = '''
138 default_action: 161 default_action:
139 //fprintf(stderr, "default action\\n"); 162 //fprintf(stderr, "default action\\n");
140 PUSH_TOKEN(Token::%s); 163 PUSH_TOKEN(Token::%s);
141 FORWARD(); 164 FORWARD();
142 goto code_%s;''' % (rule_processor.default_action.data(), start_node_number) 165 goto code_%s;''' % (default_action, start_node_number)
143 else: 166 else:
144 raise Exception("Default action type %s not supported" % action[0]) 167 raise Exception("Default action type %s not supported" % action[0])
145 168
146 code += ''' 169 code += '''
147 CHECK(false); 170 CHECK(false);
148 %s 171 %s
149 return 0; 172 return 0;
150 } 173 }
151 174
152 } 175 }
153 } 176 }
154 ''' % default_action_code 177 ''' % default_action_code
155 return code 178 return code
179
180 @staticmethod
181 def rule_processor_to_code(rule_processor, use_mdfa):
182 if use_mdfa:
183 dfa = rule_processor.default_automata().minimal_dfa()
184 else:
185 dfa = rule_processor.default_automata().dfa()
186 return CodeGenerator(dfa, rule_processor.default_action).__process()
OLDNEW
« no previous file with comments | « no previous file | tools/lexer_generator/code_generator_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698