Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # | 2 # |
| 3 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 """ Lexer for PPAPI IDL """ | 7 """ Lexer for PPAPI IDL """ |
| 8 | 8 |
| 9 # | 9 # |
| 10 # IDL Lexer | 10 # IDL Lexer |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 39 Option('output', 'Generate output.') | 39 Option('output', 'Generate output.') |
| 40 | 40 |
| 41 # | 41 # |
| 42 # IDL Lexer | 42 # IDL Lexer |
| 43 # | 43 # |
| 44 class IDLLexer(object): | 44 class IDLLexer(object): |
| 45 # 'tokens' is a value required by lex which specifies the complete list | 45 # 'tokens' is a value required by lex which specifies the complete list |
| 46 # of valid token types. | 46 # of valid token types. |
| 47 tokens = [ | 47 tokens = [ |
| 48 # Symbol and keywords types | 48 # Symbol and keywords types |
| 49 'COMMENT', | 49 'COMMENT', |
|
sehr (please use chromium)
2011/06/29 16:43:06
should 'ATTRIBUTE' be here also?
noelallen1
2011/06/29 18:59:01
An extended attribute is a grammar component consi
| |
| 50 'DESCRIBE', | 50 'DESCRIBE', |
| 51 'ENUM', | 51 'ENUM', |
| 52 'LABEL', | |
| 52 'SYMBOL', | 53 'SYMBOL', |
| 54 'INLINE', | |
| 53 'INTERFACE', | 55 'INTERFACE', |
| 54 'STRUCT', | 56 'STRUCT', |
| 55 'TYPEDEF', | 57 'TYPEDEF', |
| 56 | 58 |
| 57 # Data types | 59 # Data types |
| 58 'FLOAT', | 60 'FLOAT', |
| 59 'OCT', | 61 'OCT', |
| 60 'INT', | 62 'INT', |
| 61 'HEX', | 63 'HEX', |
| 62 'STRING', | 64 'STRING', |
| 63 | 65 |
| 64 # Operators | 66 # Operators |
| 65 'LSHIFT' | 67 'LSHIFT' |
| 66 ] | 68 ] |
| 67 | 69 |
| 68 # 'keywords' is a map of string to token type. All SYMBOL tokens are | 70 # 'keywords' is a map of string to token type. All SYMBOL tokens are |
| 69 # matched against keywords, to determine if the token is actually a keyword. | 71 # matched against keywords, to determine if the token is actually a keyword. |
| 70 keywords = { | 72 keywords = { |
| 73 'attribute' : 'ATTRIBUTE', | |
| 71 'describe' : 'DESCRIBE', | 74 'describe' : 'DESCRIBE', |
| 72 'enum' : 'ENUM', | 75 'enum' : 'ENUM', |
| 76 'label' : 'LABEL', | |
| 73 'interface' : 'INTERFACE', | 77 'interface' : 'INTERFACE', |
| 74 'readonly' : 'READONLY', | 78 'readonly' : 'READONLY', |
| 75 'struct' : 'STRUCT', | 79 'struct' : 'STRUCT', |
| 76 'typedef' : 'TYPEDEF', | 80 'typedef' : 'TYPEDEF', |
| 77 } | 81 } |
| 78 | 82 |
| 79 # 'literals' is a value expected by lex which specifies a list of valid | 83 # 'literals' is a value expected by lex which specifies a list of valid |
| 80 # literal tokens, meaning the token type and token value are identical. | 84 # literal tokens, meaning the token type and token value are identical. |
| 81 literals = '"*.(){}[],;:=+-' | 85 literals = '"*.(){}[],;:=+-' |
| 82 | 86 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 108 r'"[^"]*"' | 112 r'"[^"]*"' |
| 109 t.value = t.value[1:-1] | 113 t.value = t.value[1:-1] |
| 110 self.AddLines(t.value.count('\n')) | 114 self.AddLines(t.value.count('\n')) |
| 111 return t | 115 return t |
| 112 | 116 |
| 113 # A C or C++ style comment: /* xxx */ or // | 117 # A C or C++ style comment: /* xxx */ or // |
| 114 def t_COMMENT(self, t): | 118 def t_COMMENT(self, t): |
| 115 r'(/\*(.|\n)*?\*/)|(//.*)' | 119 r'(/\*(.|\n)*?\*/)|(//.*)' |
| 116 self.AddLines(t.value.count('\n')) | 120 self.AddLines(t.value.count('\n')) |
| 117 | 121 |
| 118 # C++ comments should keep the newline | 122 # Remove comment markers |
| 119 if t.value[:2] == '//': t.value += '\n' | 123 if t.value[:2] == '//': |
| 124 # For C++ style, remove the preceeding '//' | |
|
sehr (please use chromium)
2011/06/29 16:43:06
s/preceeding/preceding/
noelallen1
2011/06/29 18:59:01
Done.
| |
| 125 t.value = t.value[2:].rstrip() | |
| 126 else: | |
| 127 # For C style, remove ending '*/'' | |
| 128 lines = [] | |
| 129 for line in t.value[:-2].split('\n'): | |
| 130 # Remove characters until start marker for this line '*' if found | |
| 131 # otherwise it should be blank. | |
| 132 offs = line.find('*') | |
| 133 if offs >= 0: | |
| 134 line = line[offs + 1:].rstrip() | |
| 135 else: | |
| 136 line = '' | |
| 137 lines.append(line) | |
| 138 t.value = '\n'.join(lines) | |
| 139 return t | |
| 140 | |
| 141 # Return a "preprocessor" inline block | |
| 142 def t_INLINE(self, t): | |
| 143 r'\#inline (.|\n)*\#endinl.*' | |
| 144 self.AddLines(t.value.count('\n')) | |
| 120 return t | 145 return t |
| 121 | 146 |
| 122 # A symbol or keyword. | 147 # A symbol or keyword. |
| 123 def t_KEYWORD_SYMBOL(self, t): | 148 def t_KEYWORD_SYMBOL(self, t): |
| 124 r'[A-Za-z][A-Za-z_0-9]*' | 149 r'[A-Za-z][A-Za-z_0-9]*' |
| 125 | 150 |
| 126 #All non-keywords are assumed to be symbols | 151 #All non-keywords are assumed to be symbols |
| 127 t.type = self.keywords.get(t.value, 'SYMBOL') | 152 t.type = self.keywords.get(t.value, 'SYMBOL') |
| 128 return t | 153 return t |
| 129 | 154 |
| 130 def t_ANY_error(self, t): | 155 def t_ANY_error(self, t): |
| 156 msg = "Unrecognized intput" | |
|
sehr (please use chromium)
2011/06/29 16:43:06
s/intput/input/
noelallen1
2011/06/29 18:59:01
Done.
| |
| 131 line = self.lexobj.lineno | 157 line = self.lexobj.lineno |
| 158 | |
| 159 # If that line has not been accounted for, then we must have hit | |
| 160 # EoF, so compute the beginning of the that caused the problem. | |
|
sehr (please use chromium)
2011/06/29 16:43:06
the what that?
noelallen1
2011/06/29 18:59:01
Done.
| |
| 161 if line >= len(self.index): | |
| 162 # Find the offset in the line of the first word causing the issue | |
| 163 word = t.value.split()[0] | |
| 164 offs = self.lines[line - 1].find(word) | |
| 165 # Add the computed line's starting possition | |
|
sehr (please use chromium)
2011/06/29 16:43:06
s/possition/position/
noelallen1
2011/06/29 18:59:01
Done.
| |
| 166 self.index.append(self.lexobj.lexpos - offs) | |
| 167 msg = "Unexpected EoF reached after" | |
| 168 | |
| 132 pos = self.lexobj.lexpos - self.index[line] | 169 pos = self.lexobj.lexpos - self.index[line] |
| 133 file = self.lexobj.filename | 170 file = self.lexobj.filename |
| 134 out = self.ErrorMessage(file, line, pos, "Unrecognized input") | 171 out = self.ErrorMessage(file, line, pos, msg) |
| 135 sys.stderr.write(out + '\n') | 172 sys.stderr.write(out + '\n') |
| 136 | 173 |
| 137 def AddLines(self, count): | 174 def AddLines(self, count): |
| 138 # Set the lexer position for the beginning of the next line. In the case | 175 # Set the lexer position for the beginning of the next line. In the case |
| 139 # of multiple lines, tokens can not exist on any of the lines except the | 176 # of multiple lines, tokens can not exist on any of the lines except the |
| 140 # last one, so the recorded value for previous lines are unused. We still | 177 # last one, so the recorded value for previous lines are unused. We still |
| 141 # fill the array however, to make sure the line count is correct. | 178 # fill the array however, to make sure the line count is correct. |
| 142 self.lexobj.lineno += count | 179 self.lexobj.lineno += count |
| 143 for i in range(count): | 180 for i in range(count): |
| 144 self.index.append(self.lexobj.lexpos) | 181 self.index.append(self.lexobj.lexpos) |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 | 244 |
| 208 # | 245 # |
| 209 # TestSame | 246 # TestSame |
| 210 # | 247 # |
| 211 # From a set of token values, generate a new source text by joining with a | 248 # From a set of token values, generate a new source text by joining with a |
| 212 # single space. The new source is then tokenized and compared against the | 249 # single space. The new source is then tokenized and compared against the |
| 213 # old set. | 250 # old set. |
| 214 # | 251 # |
| 215 def TestSame(values): | 252 def TestSame(values): |
| 216 src1 = ' '.join(values) | 253 src1 = ' '.join(values) |
| 217 src2 = ' '.join(TextToTokens(src1)) | 254 values2 = TextToTokens(src1) |
| 255 src2 = ' '.join(values2) | |
| 256 | |
| 257 for i in range(len(values)): | |
| 258 if values[i] != values2[i]: | |
| 259 print "%d >>%s<< >>%s<<" % (i, values[i], values2[i]) | |
| 218 | 260 |
| 219 if GetOption('output'): | 261 if GetOption('output'): |
| 220 sys.stdout.write('Generating original.txt and tokenized.txt\n') | 262 sys.stdout.write('Generating original.txt and tokenized.txt\n') |
| 221 open('original.txt', 'w').write(src1) | 263 open('original.txt', 'w').write(src1) |
| 222 open('tokenized.txt', 'w').write(src2) | 264 open('tokenized.txt', 'w').write(src2) |
| 223 | 265 |
| 224 if src1 == src2: | 266 if src1 == src2: |
| 225 sys.stdout.write('Same: Pass\n') | 267 sys.stdout.write('Same: Pass\n') |
| 226 return 0 | 268 return 0 |
| 227 | 269 |
| 270 print "****************\n%s\n%s***************\n" % (src1, src2) | |
| 228 sys.stdout.write('Same: Failed\n') | 271 sys.stdout.write('Same: Failed\n') |
| 229 return -1 | 272 return -1 |
| 230 | 273 |
| 231 | 274 |
| 232 # | 275 # |
| 233 # TestExpect | 276 # TestExpect |
| 234 # | 277 # |
| 235 # From a set of tokens pairs, verify the type field of the second matches | 278 # From a set of tokens pairs, verify the type field of the second matches |
| 236 # the value of the first, so that: | 279 # the value of the first, so that: |
| 237 # INT 123 FLOAT 1.1 | 280 # INT 123 FLOAT 1.1 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 276 return -1 | 319 return -1 |
| 277 return 0 | 320 return 0 |
| 278 | 321 |
| 279 except lex.LexError as le: | 322 except lex.LexError as le: |
| 280 sys.stderr.write('%s\n' % str(le)) | 323 sys.stderr.write('%s\n' % str(le)) |
| 281 return -1 | 324 return -1 |
| 282 | 325 |
| 283 if __name__ == '__main__': | 326 if __name__ == '__main__': |
| 284 sys.exit(Main(sys.argv[1:])) | 327 sys.exit(Main(sys.argv[1:])) |
| 285 | 328 |
| OLD | NEW |