Index: ppapi/generators/idl_parser.py |
diff --git a/ppapi/generators/idl_parser.py b/ppapi/generators/idl_parser.py |
index 45f10210a70a1b220599c67382dd46550900157a..f1045c3bd0f7d23f2f9fe95830a971bd7c8b5b34 100755 |
--- a/ppapi/generators/idl_parser.py |
+++ b/ppapi/generators/idl_parser.py |
@@ -223,11 +223,14 @@ class IDLParser(IDLLexer): |
# Build a list of top level items. |
def p_top_list(self, p): |
- """top_list : describe_block top_list |
+ """top_list : callback_decl top_list |
+ | describe_block top_list |
+ | dictionary_block top_list |
| enum_block top_list |
| inline top_list |
| interface_block top_list |
| label_block top_list |
+ | namespace top_list |
| struct_block top_list |
| typedef_decl top_list |
| """ |
@@ -267,6 +270,44 @@ class IDLParser(IDLLexer): |
# |
+# Namespace |
+# |
+# A namespace provides a named scope to an enclosed top_list. |
+# |
+ def p_namespace(self, p): |
+ """namespace : modifiers NAMESPACE namespace_name '{' top_list '}' ';'""" |
+ children = ListFromConcat(p[1], p[5]) |
+ p[0] = self.BuildNamed('Namespace', p, 3, children) |
+ |
+ # We allow namespace names of the form foo.bar.baz. |
+ def p_namespace_name(self, p): |
+ """namespace_name : SYMBOL |
+ | SYMBOL '.' namespace_name""" |
+ p[0] = "".join(p[1:]) |
+ |
+ |
+# |
+# Dictionary |
+# |
+# A dictionary contains is a named list of optional and required members. |
+# |
+ def p_dictionary_block(self, p): |
+ """dictionary_block : modifiers DICTIONARY SYMBOL '{' struct_list '}' ';'""" |
+ p[0] = self.BuildNamed('Dictionary', p, 3, ListFromConcat(p[5])) |
+ |
+# |
+# Callback |
+# |
+# A callback is essentially a single function declaration (outside of an |
+# Interface). |
+# |
+ def p_callback_decl(self, p): |
+ """callback_decl : modifiers CALLBACK SYMBOL '=' SYMBOL param_list ';'""" |
+ children = ListFromConcat(p[1], p[6]) |
+ p[0] = self.BuildNamed('Callback', p, 3, children) |
+ |
+ |
+# |
# Inline |
# |
# Inline blocks define option code to be emitted based on language tag, |
@@ -482,6 +523,19 @@ class IDLParser(IDLLexer): |
elif len(p) == 1: return |
if self.parse_debug: DumpReduction('arrays', p) |
+ |
+# An identifier is a legal value for a parameter or attribute name. Lots of |
+# existing IDL files use "callback" as a parameter/attribute name, so we allow |
+# a SYMBOL or the CALLBACK keyword. |
+ def p_identifier(self, p): |
+ """identifier : SYMBOL |
+ | CALLBACK""" |
+ p[0] = p[1] |
+ # Save the line number of the underlying token (otherwise it gets |
+ # discarded), since we use it in the productions with an identifier in |
+ # them. |
+ p.set_lineno(0, p.lineno(1)) |
+ |
# |
# Parameter List |
# |
@@ -499,12 +553,19 @@ class IDLParser(IDLLexer): |
if self.parse_debug: DumpReduction('param_list', p) |
def p_param_item(self, p): |
- """param_item : modifiers SYMBOL arrays SYMBOL""" |
- typeref = self.BuildAttribute('TYPEREF', p[2]) |
- children = ListFromConcat(p[1],typeref, p[3]) |
- p[0] = self.BuildNamed('Param', p, 4, children) |
+ """param_item : modifiers optional SYMBOL arrays identifier""" |
+ typeref = self.BuildAttribute('TYPEREF', p[3]) |
+ children = ListFromConcat(p[1],p[2], typeref, p[4]) |
+ p[0] = self.BuildNamed('Param', p, 5, children) |
if self.parse_debug: DumpReduction('param_item', p) |
+ def p_optional(self, p): |
+ """optional : OPTIONAL |
+ | """ |
+ if len(p) == 2: |
+ p[0] = self.BuildAttribute('OPTIONAL', True) |
+ |
+ |
def p_param_cont(self, p): |
"""param_cont : ',' param_item param_cont |
| """ |
@@ -520,7 +581,7 @@ class IDLParser(IDLLexer): |
# |
# Typedef |
# |
-# A typedef creates a new referencable type. The tyepdef can specify an array |
+# A typedef creates a new referencable type. The typedef can specify an array |
# definition as well as a function declaration. |
# |
def p_typedef_data(self, p): |
@@ -615,26 +676,31 @@ class IDLParser(IDLLexer): |
# A member attribute or function of a struct or interface. |
# |
def p_member_attribute(self, p): |
- """member_attribute : modifiers SYMBOL SYMBOL """ |
- typeref = self.BuildAttribute('TYPEREF', p[2]) |
- children = ListFromConcat(p[1], typeref) |
- p[0] = self.BuildNamed('Member', p, 3, children) |
- if self.parse_debug: DumpReduction('attribute', p) |
- |
- def p_member_attribute_array(self, p): |
- """member_attribute : modifiers SYMBOL arrays SYMBOL """ |
+ """member_attribute : modifiers SYMBOL arrays questionmark identifier""" |
typeref = self.BuildAttribute('TYPEREF', p[2]) |
- children = ListFromConcat(p[1], typeref, p[3]) |
- p[0] = self.BuildNamed('Member', p, 4, children) |
+ children = ListFromConcat(p[1], typeref, p[3], p[4]) |
+ p[0] = self.BuildNamed('Member', p, 5, children) |
if self.parse_debug: DumpReduction('attribute', p) |
def p_member_function(self, p): |
- """member_function : modifiers SYMBOL SYMBOL param_list""" |
- typeref = self.BuildAttribute('TYPEREF', p[2]) |
- children = ListFromConcat(p[1], typeref, p[4]) |
- p[0] = self.BuildNamed('Member', p, 3, children) |
+ """member_function : modifiers static SYMBOL SYMBOL param_list""" |
+ typeref = self.BuildAttribute('TYPEREF', p[3]) |
+ children = ListFromConcat(p[1], p[2], typeref, p[5]) |
+ p[0] = self.BuildNamed('Member', p, 4, children) |
if self.parse_debug: DumpReduction('function', p) |
+ def p_static(self, p): |
+ """static : STATIC |
+ | """ |
+ if len(p) == 2: |
+ p[0] = self.BuildAttribute('STATIC', True) |
+ |
+ def p_questionmark(self, p): |
+ """questionmark : '?' |
+ | """ |
+ if len(p) == 2: |
+ p[0] = self.BuildAttribute('OPTIONAL', True) |
+ |
# |
# Interface |
# |
@@ -770,14 +836,17 @@ class IDLParser(IDLLexer): |
name = p[index] |
# Remove comment markers |
+ lines = [] |
if name[:2] == '//': |
- # For C++ style, remove the preceding '//' |
+ # For C++ style, remove any leading whitespace and the '//' marker from |
+ # each line. |
form = 'cc' |
- name = name[2:].rstrip() |
+ for line in name.split('\n'): |
+ start = line.find('//') |
+ lines.append(line[start+2:]) |
else: |
# For C style, remove ending '*/'' |
form = 'c' |
- lines = [] |
for line in name[:-2].split('\n'): |
# Remove characters until start marker for this line '*' if found |
# otherwise it should be blank. |
@@ -787,7 +856,7 @@ class IDLParser(IDLLexer): |
else: |
line = '' |
lines.append(line) |
- name = '\n'.join(lines) |
+ name = '\n'.join(lines) |
childlist = [self.BuildAttribute('NAME', name), |
self.BuildAttribute('FORM', form)] |