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

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

Issue 47543003: Mojo: Add basic IDL parser. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: A bit more object oriented. Created 7 years, 1 month 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
« no previous file with comments | « mojo/public/bindings/parser/__init__.py ('k') | mojo/public/bindings/parser/mojo_translate.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
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
4 # found in the LICENSE file.
5
6 """Generates a syntax tree from a Mojo IDL file."""
7
8
9 import sys
10 import os.path
11
12
13 # Try to load the ply module, if not, then assume it is in the third_party
14 # directory.
15 try:
16 # Disable lint check which fails to find the ply module.
17 # pylint: disable=F0401
18 from ply import lex
19 from ply import yacc
20 except ImportError:
21 module_path, module_name = os.path.split(__file__)
22 third_party = os.path.join(
23 module_path, os.pardir, os.pardir, os.pardir, os.pardir, 'third_party')
24 sys.path.append(third_party)
25 # pylint: disable=F0401
26 from ply import lex
27 from ply import yacc
28
29
30 def ListFromConcat(*items):
31 """Generate list by concatenating inputs"""
32 itemsout = []
33 for item in items:
34 if item is None:
35 continue
36 if type(item) is not type([]):
37 itemsout.append(item)
38 else:
39 itemsout.extend(item)
40
41 return itemsout
42
43
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 'ARRAY',
52 'ORDINAL',
53
54 'MODULE',
55 'STRUCT',
56 'INTERFACE',
57 'VOID',
58
59 'LCURLY',
60 'RCURLY',
61 'LPAREN',
62 'RPAREN',
63 'LBRACKET',
64 'RBRACKET',
65 'COMMA',
66 'SEMICOLON',
67 'EQUALS',
68 )
69
70 t_LCURLY = r'{'
71 t_RCURLY = r'}'
72 t_LPAREN = r'\('
73 t_RPAREN = r'\)'
74 t_LBRACKET = r'\['
75 t_RBRACKET = r'\]'
76 t_COMMA = r','
77 t_SEMICOLON = r';'
78 t_EQUALS = r'='
79 t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
80 t_ARRAY = r'[a-zA-Z_][a-zA-Z0-9_]*\[\]'
81 t_NUMBER = r'\d+'
82 t_ORDINAL = r'@[0-9]*'
83
84 def t_MODULE(self, t):
85 r'module'
86 return t
87
88 def t_STRUCT(self, t):
89 r'struct'
90 return t
91
92 def t_INTERFACE(self, t):
93 r'interface'
94 return t
95
96 def t_VOID(self, t):
97 r'void'
98 return t
99
100 # Ignore C and C++ style comments
101 def t_COMMENT(self, t):
102 r'(/\*(.|\n)*?\*/)|(//.*(\n[ \t]*//.*)*)'
103 pass
104
105 # Ignored characters
106 t_ignore = " \t"
107
108 def t_newline(self, t):
109 r'\n+'
110 t.lexer.lineno += t.value.count("\n")
111
112 def t_error(self, t):
113 print("Illegal character '%s'" % t.value[0])
114 t.lexer.skip(1)
115
116
117 class Parser(object):
118
119 def __init__(self, lexer):
120 self.tokens = lexer.tokens
121
122 def p_module(self, p):
123 """module : MODULE NAME LCURLY definitions RCURLY"""
124 p[0] = ('MODULE', p[2], p[4])
125
126 def p_definitions(self, p):
127 """definitions : definition definitions
128 |"""
129 if len(p) > 1:
130 p[0] = ListFromConcat(p[1], p[2])
131
132 def p_definition(self, p):
133 """definition : struct
134 | interface"""
135 p[0] = p[1]
136
137 def p_attribute_section(self, p):
138 """attribute_section : LBRACKET attributes RBRACKET
139 | """
140 if len(p) > 3:
141 p[0] = p[2]
142
143 def p_attributes(self, p):
144 """attributes : attribute
145 | attribute COMMA attributes
146 | """
147 if len(p) == 2:
148 p[0] = ListFromConcat(p[1])
149 elif len(p) > 3:
150 p[0] = ListFromConcat(p[1], p[3])
151
152 def p_attribute(self, p):
153 """attribute : NAME EQUALS NUMBER"""
154 p[0] = ('ATTRIBUTE', p[1], p[3])
155
156 def p_struct(self, p):
157 """struct : attribute_section STRUCT NAME LCURLY fields RCURLY SEMICOLON"""
158 p[0] = ('STRUCT', p[3], p[1], p[5])
159
160 def p_fields(self, p):
161 """fields : field fields
162 |"""
163 if len(p) > 1:
164 p[0] = ListFromConcat(p[1], p[2])
165
166 def p_field(self, p):
167 """field : typename NAME ordinal SEMICOLON"""
168 p[0] = ('FIELD', p[1], p[2], p[3])
169
170 def p_interface(self, p):
171 """interface : INTERFACE NAME LCURLY methods RCURLY SEMICOLON"""
172 p[0] = ('INTERFACE', p[2], p[4])
173
174 def p_methods(self, p):
175 """methods : method methods
176 | """
177 if len(p) > 1:
178 p[0] = ListFromConcat(p[1], p[2])
179
180 def p_method(self, p):
181 """method : VOID NAME LPAREN parameters RPAREN ordinal SEMICOLON"""
182 p[0] = ('METHOD', p[2], p[4], p[6])
183
184 def p_parameters(self, p):
185 """parameters : parameter
186 | parameter COMMA parameters
187 | """
188 if len(p) == 2:
189 p[0] = p[1]
190 elif len(p) > 3:
191 p[0] = ListFromConcat(p[1], p[3])
192
193 def p_parameter(self, p):
194 """parameter : typename NAME ordinal"""
195 p[0] = ('PARAM', p[1], p[2], p[3])
196
197 def p_typename(self, p):
198 """typename : NAME
199 | ARRAY"""
200 p[0] = p[1]
201
202 def p_ordinal(self, p):
203 """ordinal : ORDINAL
204 | """
205 if len(p) > 1:
206 p[0] = p[1]
207
208 def p_error(self, e):
209 print('error: %s'%e)
210
211
212 def Parse(filename):
213 lexer = Lexer()
214 parser = Parser(lexer)
215
216 lex.lex(object=lexer)
217 yacc.yacc(module=parser, debug=0, write_tables=0)
218
219 tree = yacc.parse(open(filename).read())
220 return tree
221
222
223 def Main():
224 if len(sys.argv) < 2:
225 print("usage: %s filename" % (sys.argv[0]))
226 sys.exit(1)
227 tree = Parse(filename=sys.argv[1])
228 print(tree)
229
230
231 if __name__ == '__main__':
232 Main()
OLDNEW
« no previous file with comments | « mojo/public/bindings/parser/__init__.py ('k') | mojo/public/bindings/parser/mojo_translate.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698