OLD | NEW |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import re | 5 import re |
6 import sys | 6 import sys |
7 import os.path | 7 import os.path |
8 | 8 |
9 # Try to load the ply module, if not, then assume it is in the third_party | 9 # Try to load the ply module, if not, then assume it is in the third_party |
10 # directory. | 10 # directory. |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 floating_constant = \ | 154 floating_constant = \ |
155 '(((('+fractional_constant+')'+ \ | 155 '(((('+fractional_constant+')'+ \ |
156 exponent_part+'?)|([0-9]+'+exponent_part+'))[FfLl]?)' | 156 exponent_part+'?)|([0-9]+'+exponent_part+'))[FfLl]?)' |
157 binary_exponent_part = r'''([pP][+-]?[0-9]+)''' | 157 binary_exponent_part = r'''([pP][+-]?[0-9]+)''' |
158 hex_fractional_constant = \ | 158 hex_fractional_constant = \ |
159 '((('+hex_digits+r""")?\."""+hex_digits+')|('+hex_digits+r"""\.))""" | 159 '((('+hex_digits+r""")?\."""+hex_digits+')|('+hex_digits+r"""\.))""" |
160 hex_floating_constant = \ | 160 hex_floating_constant = \ |
161 '('+hex_prefix+'('+hex_digits+'|'+hex_fractional_constant+')'+ \ | 161 '('+hex_prefix+'('+hex_digits+'|'+hex_fractional_constant+')'+ \ |
162 binary_exponent_part+'[FfLl]?)' | 162 binary_exponent_part+'[FfLl]?)' |
163 | 163 |
| 164 # Ordinals |
| 165 ordinal = r'@[0-9]+' |
| 166 missing_ordinal_value = r'@' |
| 167 # Don't allow ordinal values in octal (even invalid octal, like 09) or |
| 168 # hexadecimal. |
| 169 octal_or_hex_ordinal_disallowed = r'@((0[0-9]+)|('+hex_prefix+hex_digits+'))' |
| 170 |
164 ## | 171 ## |
165 ## Rules for the normal state | 172 ## Rules for the normal state |
166 ## | 173 ## |
167 t_ignore = ' \t\r' | 174 t_ignore = ' \t\r' |
168 | 175 |
169 # Newlines | 176 # Newlines |
170 def t_NEWLINE(self, t): | 177 def t_NEWLINE(self, t): |
171 r'\n+' | 178 r'\n+' |
172 t.lexer.lineno += t.value.count("\n") | 179 t.lexer.lineno += t.value.count("\n") |
173 | 180 |
(...skipping 23 matching lines...) Expand all Loading... |
197 t_RBRACKET = r'\]' | 204 t_RBRACKET = r'\]' |
198 t_LBRACE = r'\{' | 205 t_LBRACE = r'\{' |
199 t_RBRACE = r'\}' | 206 t_RBRACE = r'\}' |
200 t_LANGLE = r'<' | 207 t_LANGLE = r'<' |
201 t_RANGLE = r'>' | 208 t_RANGLE = r'>' |
202 t_COMMA = r',' | 209 t_COMMA = r',' |
203 t_DOT = r'\.' | 210 t_DOT = r'\.' |
204 t_SEMI = r';' | 211 t_SEMI = r';' |
205 | 212 |
206 t_STRING_LITERAL = string_literal | 213 t_STRING_LITERAL = string_literal |
207 t_ORDINAL = r'@[0-9]*' | |
208 | 214 |
209 # The following floating and integer constants are defined as | 215 # The following floating and integer constants are defined as |
210 # functions to impose a strict order (otherwise, decimal | 216 # functions to impose a strict order (otherwise, decimal |
211 # is placed before the others because its regex is longer, | 217 # is placed before the others because its regex is longer, |
212 # and this is bad) | 218 # and this is bad) |
213 # | 219 # |
214 @TOKEN(floating_constant) | 220 @TOKEN(floating_constant) |
215 def t_FLOAT_CONST(self, t): | 221 def t_FLOAT_CONST(self, t): |
216 return t | 222 return t |
217 | 223 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 msg = "Invalid char constant %s" % t.value | 259 msg = "Invalid char constant %s" % t.value |
254 self._error(msg, t) | 260 self._error(msg, t) |
255 | 261 |
256 # unmatched string literals are caught by the preprocessor | 262 # unmatched string literals are caught by the preprocessor |
257 | 263 |
258 @TOKEN(bad_string_literal) | 264 @TOKEN(bad_string_literal) |
259 def t_BAD_STRING_LITERAL(self, t): | 265 def t_BAD_STRING_LITERAL(self, t): |
260 msg = "String contains invalid escape code" | 266 msg = "String contains invalid escape code" |
261 self._error(msg, t) | 267 self._error(msg, t) |
262 | 268 |
| 269 # Handle ordinal-related tokens in the right order: |
| 270 @TOKEN(octal_or_hex_ordinal_disallowed) |
| 271 def t_OCTAL_OR_HEX_ORDINAL_DISALLOWED(self, t): |
| 272 msg = "Octal and hexadecimal ordinal values not allowed" |
| 273 self._error(msg, t) |
| 274 |
| 275 @TOKEN(ordinal) |
| 276 def t_ORDINAL(self, t): |
| 277 return t |
| 278 |
| 279 @TOKEN(missing_ordinal_value) |
| 280 def t_BAD_ORDINAL(self, t): |
| 281 msg = "Missing ordinal value" |
| 282 self._error(msg, t) |
| 283 |
263 @TOKEN(identifier) | 284 @TOKEN(identifier) |
264 def t_NAME(self, t): | 285 def t_NAME(self, t): |
265 t.type = self.keyword_map.get(t.value, "NAME") | 286 t.type = self.keyword_map.get(t.value, "NAME") |
266 return t | 287 return t |
267 | 288 |
268 # Ignore C and C++ style comments | 289 # Ignore C and C++ style comments |
269 def t_COMMENT(self, t): | 290 def t_COMMENT(self, t): |
270 r'(/\*(.|\n)*?\*/)|(//.*(\n[ \t]*//.*)*)' | 291 r'(/\*(.|\n)*?\*/)|(//.*(\n[ \t]*//.*)*)' |
271 pass | 292 pass |
272 | 293 |
273 def t_error(self, t): | 294 def t_error(self, t): |
274 msg = 'Illegal character %s' % repr(t.value[0]) | 295 msg = 'Illegal character %s' % repr(t.value[0]) |
275 self._error(msg, t) | 296 self._error(msg, t) |
OLD | NEW |