| OLD | NEW |
| 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 Loading... |
| 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() |
| OLD | NEW |