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 |