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

Side by Side Diff: mojo/public/bindings/parse/mojo_parser.py

Issue 131833004: Unrevert 244233 "Add support for using expressions as enum values." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 months 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
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2013 The Chromium Authors. All rights reserved. 2 # Copyright 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Generates a syntax tree from a Mojo IDL file.""" 6 """Generates a syntax tree from a Mojo IDL file."""
7 7
8 8
9 import sys 9 import sys
10 import os.path 10 import os.path
11 11
12
13 # Try to load the ply module, if not, then assume it is in the third_party 12 # Try to load the ply module, if not, then assume it is in the third_party
14 # directory. 13 # directory.
15 try: 14 try:
16 # Disable lint check which fails to find the ply module. 15 # Disable lint check which fails to find the ply module.
17 # pylint: disable=F0401 16 # pylint: disable=F0401
18 from ply import lex 17 from ply import lex
19 from ply import yacc 18 from ply import yacc
20 except ImportError: 19 except ImportError:
21 module_path, module_name = os.path.split(__file__) 20 module_path, module_name = os.path.split(__file__)
22 third_party = os.path.join( 21 third_party = os.path.join(
23 module_path, os.pardir, os.pardir, os.pardir, os.pardir, 'third_party') 22 module_path, os.pardir, os.pardir, os.pardir, os.pardir, 'third_party')
24 sys.path.append(third_party) 23 sys.path.append(third_party)
25 # pylint: disable=F0401 24 # pylint: disable=F0401
26 from ply import lex 25 from ply import lex
27 from ply import yacc 26 from ply import yacc
28 27
28 from mojo_lexer import Lexer
29
29 30
30 def ListFromConcat(*items): 31 def ListFromConcat(*items):
31 """Generate list by concatenating inputs""" 32 """Generate list by concatenating inputs"""
32 itemsout = [] 33 itemsout = []
33 for item in items: 34 for item in items:
34 if item is None: 35 if item is None:
35 continue 36 continue
36 if type(item) is not type([]): 37 if type(item) is not type([]):
37 itemsout.append(item) 38 itemsout.append(item)
38 else: 39 else:
39 itemsout.extend(item) 40 itemsout.extend(item)
40 41
41 return itemsout 42 return itemsout
42 43
43 44
44 class Lexer(object):
45
46 # This field is required by lex to specify the complete list of valid tokens.
47 tokens = (
48 'NAME',
49 'NUMBER',
50
51 'ORDINAL',
52
53 'HANDLE',
54 'DATAPIPECONSUMER',
55 'DATAPIPEPRODUCER',
56 'MESSAGEPIPE',
57
58 'MODULE',
59 'STRUCT',
60 'INTERFACE',
61 'ENUM',
62 'VOID',
63
64 'LCURLY',
65 'RCURLY',
66 'LPAREN',
67 'RPAREN',
68 'LANGLE',
69 'RANGLE',
70 'LBRACKET',
71 'RBRACKET',
72 'COMMA',
73 'SEMICOLON',
74 'EQUALS',
75 )
76
77 t_LCURLY = r'{'
78 t_RCURLY = r'}'
79 t_LPAREN = r'\('
80 t_RPAREN = r'\)'
81 t_LANGLE = r'<'
82 t_RANGLE = r'>'
83 t_LBRACKET = r'\['
84 t_RBRACKET = r'\]'
85 t_COMMA = r','
86 t_SEMICOLON = r';'
87 t_EQUALS = r'='
88 t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
89 t_NUMBER = r'\d+'
90 t_ORDINAL = r'@[0-9]*'
91
92 def t_HANDLE(self, t):
93 r'handle'
94 return t
95
96 def t_DATAPIPECONSUMER(self, t):
97 r'data_pipe_consumer'
98 return t
99
100 def t_DATAPIPEPRODUCER(self, t):
101 r'data_pipe_producer'
102 return t
103
104 def t_MESSAGEPIPE(self, t):
105 r'message_pipe'
106 return t
107
108 def t_MODULE(self, t):
109 r'module'
110 return t
111
112 def t_STRUCT(self, t):
113 r'struct'
114 return t
115
116 def t_INTERFACE(self, t):
117 r'interface'
118 return t
119
120 def t_ENUM(self, t):
121 r'enum'
122 return t
123
124 def t_VOID(self, t):
125 r'void'
126 return t
127
128 # Ignore C and C++ style comments
129 def t_COMMENT(self, t):
130 r'(/\*(.|\n)*?\*/)|(//.*(\n[ \t]*//.*)*)'
131 pass
132
133 # Ignored characters
134 t_ignore = " \t"
135
136 def t_newline(self, t):
137 r'\n+'
138 t.lexer.lineno += t.value.count("\n")
139
140 def t_error(self, t):
141 print("Illegal character '%s'" % t.value[0])
142 t.lexer.skip(1)
143
144
145 class Parser(object): 45 class Parser(object):
146 46
147 def __init__(self, lexer): 47 def __init__(self, lexer):
148 self.tokens = lexer.tokens 48 self.tokens = lexer.tokens
149 49
150 def p_module(self, p): 50 def p_module(self, p):
151 """module : MODULE NAME LCURLY definitions RCURLY""" 51 """module : MODULE NAME LBRACE definitions RBRACE"""
152 p[0] = ('MODULE', p[2], p[4]) 52 p[0] = ('MODULE', p[2], p[4])
153 53
154 def p_definitions(self, p): 54 def p_definitions(self, p):
155 """definitions : definition definitions 55 """definitions : definition definitions
156 |""" 56 |"""
157 if len(p) > 1: 57 if len(p) > 1:
158 p[0] = ListFromConcat(p[1], p[2]) 58 p[0] = ListFromConcat(p[1], p[2])
159 59
160 def p_definition(self, p): 60 def p_definition(self, p):
161 """definition : struct 61 """definition : struct
(...skipping 10 matching lines...) Expand all
172 def p_attributes(self, p): 72 def p_attributes(self, p):
173 """attributes : attribute 73 """attributes : attribute
174 | attribute COMMA attributes 74 | attribute COMMA attributes
175 | """ 75 | """
176 if len(p) == 2: 76 if len(p) == 2:
177 p[0] = ListFromConcat(p[1]) 77 p[0] = ListFromConcat(p[1])
178 elif len(p) > 3: 78 elif len(p) > 3:
179 p[0] = ListFromConcat(p[1], p[3]) 79 p[0] = ListFromConcat(p[1], p[3])
180 80
181 def p_attribute(self, p): 81 def p_attribute(self, p):
182 """attribute : NAME EQUALS NUMBER 82 """attribute : NAME EQUALS expression
183 | NAME EQUALS NAME""" 83 | NAME EQUALS NAME"""
184 p[0] = ('ATTRIBUTE', p[1], p[3]) 84 p[0] = ('ATTRIBUTE', p[1], p[3])
185 85
186 def p_struct(self, p): 86 def p_struct(self, p):
187 """struct : attribute_section STRUCT NAME LCURLY struct_body RCURLY SEMICOLO N""" 87 """struct : attribute_section STRUCT NAME LBRACE struct_body RBRACE SEMI"""
188 p[0] = ('STRUCT', p[3], p[1], p[5]) 88 p[0] = ('STRUCT', p[3], p[1], p[5])
189 89
190 def p_struct_body(self, p): 90 def p_struct_body(self, p):
191 """struct_body : field struct_body 91 """struct_body : field struct_body
192 | enum struct_body 92 | enum struct_body
193 |""" 93 |"""
194 if len(p) > 1: 94 if len(p) > 1:
195 p[0] = ListFromConcat(p[1], p[2]) 95 p[0] = ListFromConcat(p[1], p[2])
196 96
197 def p_field(self, p): 97 def p_field(self, p):
198 """field : typename NAME ordinal SEMICOLON""" 98 """field : typename NAME ordinal SEMI"""
199 p[0] = ('FIELD', p[1], p[2], p[3]) 99 p[0] = ('FIELD', p[1], p[2], p[3])
200 100
201 def p_interface(self, p): 101 def p_interface(self, p):
202 """interface : attribute_section INTERFACE NAME LCURLY interface_body RCURLY SEMICOLON""" 102 """interface : attribute_section INTERFACE NAME LBRACE interface_body RBRACE SEMI"""
203 p[0] = ('INTERFACE', p[3], p[1], p[5]) 103 p[0] = ('INTERFACE', p[3], p[1], p[5])
204 104
205 def p_interface_body(self, p): 105 def p_interface_body(self, p):
206 """interface_body : method interface_body 106 """interface_body : method interface_body
207 | enum interface_body 107 | enum interface_body
208 | """ 108 | """
209 if len(p) > 1: 109 if len(p) > 1:
210 p[0] = ListFromConcat(p[1], p[2]) 110 p[0] = ListFromConcat(p[1], p[2])
211 111
212 def p_method(self, p): 112 def p_method(self, p):
213 """method : VOID NAME LPAREN parameters RPAREN ordinal SEMICOLON""" 113 """method : VOID NAME LPAREN parameters RPAREN ordinal SEMI"""
214 p[0] = ('METHOD', p[2], p[4], p[6]) 114 p[0] = ('METHOD', p[2], p[4], p[6])
215 115
216 def p_parameters(self, p): 116 def p_parameters(self, p):
217 """parameters : parameter 117 """parameters : parameter
218 | parameter COMMA parameters 118 | parameter COMMA parameters
219 | """ 119 | """
220 if len(p) == 1: 120 if len(p) == 1:
221 p[0] = [] 121 p[0] = []
222 elif len(p) == 2: 122 elif len(p) == 2:
223 p[0] = ListFromConcat(p[1]) 123 p[0] = ListFromConcat(p[1])
224 elif len(p) > 3: 124 elif len(p) > 3:
225 p[0] = ListFromConcat(p[1], p[3]) 125 p[0] = ListFromConcat(p[1], p[3])
226 126
227 def p_parameter(self, p): 127 def p_parameter(self, p):
228 """parameter : typename NAME ordinal""" 128 """parameter : typename NAME ordinal"""
229 p[0] = ('PARAM', p[1], p[2], p[3]) 129 p[0] = ('PARAM', p[1], p[2], p[3])
230 130
231 def p_typename(self, p): 131 def p_typename(self, p):
232 """typename : basictypename 132 """typename : basictypename
233 | array""" 133 | array"""
234 p[0] = p[1] 134 p[0] = p[1]
235 135
236 def p_basictypename(self, p): 136 def p_basictypename(self, p):
237 """basictypename : NAME 137 """basictypename : NAME
238 | HANDLE 138 | HANDLE
239 | specializedhandle""" 139 | specializedhandle"""
240 p[0] = p[1] 140 p[0] = p[1]
241 141
242 def p_specializedhandle(self, p): 142 def p_specializedhandle(self, p):
243 """specializedhandle : HANDLE LANGLE specializedhandlename RANGLE""" 143 """specializedhandle : HANDLE LT specializedhandlename GT"""
244 p[0] = "handle<" + p[3] + ">" 144 p[0] = "handle<" + p[3] + ">"
245 145
246 def p_specializedhandlename(self, p): 146 def p_specializedhandlename(self, p):
247 """specializedhandlename : DATAPIPECONSUMER 147 """specializedhandlename : DATA_PIPE_CONSUMER
248 | DATAPIPEPRODUCER 148 | DATA_PIPE_PRODUCER
249 | MESSAGEPIPE""" 149 | MESSAGE_PIPE"""
250 p[0] = p[1] 150 p[0] = p[1]
251 151
252 def p_array(self, p): 152 def p_array(self, p):
253 """array : basictypename LBRACKET RBRACKET""" 153 """array : basictypename LBRACKET RBRACKET"""
254 p[0] = p[1] + "[]" 154 p[0] = p[1] + "[]"
255 155
256 def p_ordinal(self, p): 156 def p_ordinal(self, p):
257 """ordinal : ORDINAL 157 """ordinal : ORDINAL
258 | """ 158 | """
259 if len(p) > 1: 159 if len(p) > 1:
260 p[0] = p[1] 160 p[0] = p[1]
261 161
262 def p_enum(self, p): 162 def p_enum(self, p):
263 """enum : ENUM NAME LCURLY enum_fields RCURLY SEMICOLON""" 163 """enum : ENUM NAME LBRACE enum_fields RBRACE SEMI"""
264 p[0] = ('ENUM', p[2], p[4]) 164 p[0] = ('ENUM', p[2], p[4])
265 165
266 def p_enum_fields(self, p): 166 def p_enum_fields(self, p):
267 """enum_fields : enum_field 167 """enum_fields : enum_field
268 | enum_field COMMA enum_fields 168 | enum_field COMMA enum_fields
269 |""" 169 |"""
270 if len(p) == 2: 170 if len(p) == 2:
271 p[0] = ListFromConcat(p[1]) 171 p[0] = ListFromConcat(p[1])
272 elif len(p) > 3: 172 elif len(p) > 3:
273 p[0] = ListFromConcat(p[1], p[3]) 173 p[0] = ListFromConcat(p[1], p[3])
274 174
275 def p_enum_field(self, p): 175 def p_enum_field(self, p):
276 """enum_field : NAME 176 """enum_field : NAME
277 | NAME EQUALS NUMBER""" 177 | NAME EQUALS expression"""
278 if len(p) == 2: 178 if len(p) == 2:
279 p[0] = ('ENUM_FIELD', p[1], None) 179 p[0] = ('ENUM_FIELD', p[1], None)
280 else: 180 else:
281 p[0] = ('ENUM_FIELD', p[1], p[3]) 181 p[0] = ('ENUM_FIELD', p[1], p[3])
282 182
183 ### Expressions ###
184
185 def p_expression(self, p):
186 """expression : conditional_expression"""
187 p[0] = p[1]
188
189 def p_conditional_expression(self, p):
190 """conditional_expression : binary_expression
191 | binary_expression CONDOP expression COLON condit ional_expression"""
192 # Just pass the arguments through. I don't think it's possible to preserve
193 # the spaces of the original, so just put a single space between them.
194 p[0] = ' '.join(p[1:])
195
196 # PLY lets us specify precedence of operators, but since we don't actually
197 # evaluate them, we don't need that here.
198 def p_binary_expression(self, p):
199 """binary_expression : unary_expression
200 | binary_expression binary_operator binary_expression"" "
201 p[0] = ' '.join(p[1:])
202
203 def p_binary_operator(self, p):
204 """binary_operator : TIMES
205 | DIVIDE
206 | MOD
207 | PLUS
208 | MINUS
209 | RSHIFT
210 | LSHIFT
211 | LT
212 | LE
213 | GE
214 | GT
215 | EQ
216 | NE
217 | AND
218 | OR
219 | XOR
220 | LAND
221 | LOR"""
222 p[0] = p[1]
223
224 def p_unary_expression(self, p):
225 """unary_expression : primary_expression
226 | unary_operator expression"""
227 p[0] = ''.join(p[1:])
228
229 def p_unary_operator(self, p):
230 """unary_operator : TIMES
231 | PLUS
232 | MINUS
233 | NOT
234 | LNOT"""
235 p[0] = p[1]
236
237 def p_primary_expression(self, p):
238 """primary_expression : constant
239 | NAME
240 | LPAREN expression RPAREN"""
241 p[0] = ''.join(p[1:])
242
243 def p_constant(self, p):
244 """constant : INT_CONST_DEC
245 | INT_CONST_OCT
246 | INT_CONST_HEX
247 | FLOAT_CONST
248 | HEX_FLOAT_CONST
249 | CHAR_CONST
250 | WCHAR_CONST
251 | STRING_LITERAL
252 | WSTRING_LITERAL"""
253 p[0] = ''.join(p[1:])
254
283 def p_error(self, e): 255 def p_error(self, e):
284 print('error: %s'%e) 256 print('error: %s'%e)
285 257
286 258
287 def Parse(filename): 259 def Parse(filename):
288 lexer = Lexer() 260 lexer = Lexer()
289 parser = Parser(lexer) 261 parser = Parser(lexer)
290 262
291 lex.lex(object=lexer) 263 lex.lex(object=lexer)
292 yacc.yacc(module=parser, debug=0, write_tables=0) 264 yacc.yacc(module=parser, debug=0, write_tables=0)
293 265
294 tree = yacc.parse(open(filename).read()) 266 tree = yacc.parse(open(filename).read())
295 return tree 267 return tree
296 268
297 269
298 def Main(): 270 def Main():
299 if len(sys.argv) < 2: 271 if len(sys.argv) < 2:
300 print("usage: %s filename" % (sys.argv[0])) 272 print("usage: %s filename" % (sys.argv[0]))
301 sys.exit(1) 273 sys.exit(1)
302 tree = Parse(filename=sys.argv[1]) 274 tree = Parse(filename=sys.argv[1])
303 print(tree) 275 print(tree)
304 276
305 277
306 if __name__ == '__main__': 278 if __name__ == '__main__':
307 Main() 279 Main()
OLDNEW
« no previous file with comments | « mojo/public/bindings/parse/mojo_lexer.py ('k') | mojo/public/bindings/sample/sample_service.mojom » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698