summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2015-08-17 17:41:18 +0200
committerVincent Sanders <vince@kyllikki.org>2015-08-17 17:41:18 +0200
commit40cd6a199d8a5f92f71c5638f4da021a779e7a5c (patch)
treee12c3c0325d361945ad83f007832f09c045c3192
parentee69169f841542c6d5d8a8c7d4b011e294d73bd8 (diff)
downloadnsgenbind-40cd6a199d8a5f92f71c5638f4da021a779e7a5c.tar.gz
nsgenbind-40cd6a199d8a5f92f71c5638f4da021a779e7a5c.tar.bz2
Add WebIDL parsing of dictionaries
This adds correct parsing of dictionaries into the AST. These entries in the AST are not yet used but do not affect generation of interfaces.
-rw-r--r--src/interface-map.c2
-rw-r--r--src/webidl-ast.c11
-rw-r--r--src/webidl-ast.h6
-rw-r--r--src/webidl-lexer.l2
-rw-r--r--src/webidl-parser.y300
5 files changed, 240 insertions, 81 deletions
diff --git a/src/interface-map.c b/src/interface-map.c
index a5a672a..822892f 100644
--- a/src/interface-map.c
+++ b/src/interface-map.c
@@ -596,7 +596,7 @@ int interface_map_new(struct genbind_node *genbind,
webidl_node_find_type(
webidl_node_getnode(node),
NULL,
- WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE));
+ WEBIDL_NODE_TYPE_INHERITANCE));
/* is the interface marked as not generating an object */
if (webidl_node_find_type_ident(
diff --git a/src/webidl-ast.c b/src/webidl-ast.c
index 87e3485..dc78e1f 100644
--- a/src/webidl-ast.c
+++ b/src/webidl-ast.c
@@ -96,6 +96,7 @@ webidl_node_add(struct webidl_node *node, struct webidl_node *list)
switch (node->type) {
case WEBIDL_NODE_TYPE_ROOT:
case WEBIDL_NODE_TYPE_INTERFACE:
+ case WEBIDL_NODE_TYPE_DICTIONARY:
case WEBIDL_NODE_TYPE_LIST:
case WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE:
case WEBIDL_NODE_TYPE_ATTRIBUTE:
@@ -265,7 +266,7 @@ char *webidl_node_gettext(struct webidl_node *node)
switch(node->type) {
case WEBIDL_NODE_TYPE_IDENT:
- case WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE:
+ case WEBIDL_NODE_TYPE_INHERITANCE:
case WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS:
case WEBIDL_NODE_TYPE_LITERAL_STRING:
return node->r.text;
@@ -311,6 +312,7 @@ struct webidl_node *webidl_node_getnode(struct webidl_node *node)
switch (node->type) {
case WEBIDL_NODE_TYPE_ROOT:
case WEBIDL_NODE_TYPE_INTERFACE:
+ case WEBIDL_NODE_TYPE_DICTIONARY:
case WEBIDL_NODE_TYPE_LIST:
case WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE:
case WEBIDL_NODE_TYPE_ATTRIBUTE:
@@ -338,7 +340,7 @@ static const char *webidl_node_type_to_str(enum webidl_node_type type)
case WEBIDL_NODE_TYPE_IDENT:
return "Ident";
- case WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE:
+ case WEBIDL_NODE_TYPE_INHERITANCE:
return "Inherit";
case WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS:
@@ -347,6 +349,9 @@ static const char *webidl_node_type_to_str(enum webidl_node_type type)
case WEBIDL_NODE_TYPE_INTERFACE:
return "Interface";
+ case WEBIDL_NODE_TYPE_DICTIONARY:
+ return "Dictionary";
+
case WEBIDL_NODE_TYPE_LIST:
return "List";
@@ -600,7 +605,7 @@ static int implements_copy_nodes(struct webidl_node *src_node,
while (src != NULL) {
if (src->type == WEBIDL_NODE_TYPE_LIST) {
- /** @todo technicaly this should copy WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE */
+ /** @todo technicaly this should copy WEBIDL_NODE_TYPE_INHERITANCE */
dst = webidl_node_new(src->type, dst, src->r.text);
}
src = src->l;
diff --git a/src/webidl-ast.h b/src/webidl-ast.h
index 109159f..0872965 100644
--- a/src/webidl-ast.h
+++ b/src/webidl-ast.h
@@ -19,14 +19,16 @@ enum webidl_node_type {
WEBIDL_NODE_TYPE_LIST,
/* non structural node types */
- WEBIDL_NODE_TYPE_INTERFACE,
- WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE,
+ WEBIDL_NODE_TYPE_INTERFACE, /**< node is an interface*/
WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS,
WEBIDL_NODE_TYPE_ATTRIBUTE,
WEBIDL_NODE_TYPE_OPERATION,
WEBIDL_NODE_TYPE_CONST,
+ WEBIDL_NODE_TYPE_DICTIONARY, /**< node is a dictionary */
+
+ WEBIDL_NODE_TYPE_INHERITANCE, /**< node has inheritance */
WEBIDL_NODE_TYPE_SPECIAL,
WEBIDL_NODE_TYPE_ARGUMENT,
WEBIDL_NODE_TYPE_OPTIONAL,
diff --git a/src/webidl-lexer.l b/src/webidl-lexer.l
index 8c68fdf..4788610 100644
--- a/src/webidl-lexer.l
+++ b/src/webidl-lexer.l
@@ -213,6 +213,8 @@ iterable return TOK_ITERABLE;
legacyiterable return TOK_LEGACYITERABLE;
+required return TOK_REQUIRED;
+
{identifier} {
/* A leading "_" is used to escape an identifier from
* looking like a reserved word terminal. */
diff --git a/src/webidl-parser.y b/src/webidl-parser.y
index 42fed63..406962f 100644
--- a/src/webidl-parser.y
+++ b/src/webidl-parser.y
@@ -66,7 +66,6 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str)
%token TOK_BOOLEAN
%token TOK_BYTE
%token TOK_CALLBACK
-%token TOK_LEGACYCALLER
%token TOK_CONST
%token TOK_CREATOR
%token TOK_DATE
@@ -87,6 +86,7 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str)
%token TOK_INHERIT
%token TOK_INTERFACE
%token TOK_ITERABLE
+%token TOK_LEGACYCALLER
%token TOK_LEGACYITERABLE
%token TOK_LONG
%token TOK_MODULE
@@ -102,6 +102,7 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str)
%token TOK_PROMISE
%token TOK_RAISES
%token TOK_READONLY
+%token TOK_REQUIRED
%token TOK_SETRAISES
%token TOK_SETTER
%token TOK_SEQUENCE
@@ -134,6 +135,8 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str)
%type <node> Dictionary
%type <node> PartialDictionary
+%type <node> DictionaryMembers
+%type <node> DictionaryMember
%type <node> Exception
%type <node> Enum
@@ -151,6 +154,8 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str)
%type <node> Attribute
%type <node> AttributeRest
+%type <text> AttributeName
+%type <text> AttributeNameKeyword
%type <node> AttributeOrOperation
%type <node> StringifierAttributeOrOperation
%type <node> Const
@@ -201,6 +206,7 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str)
%type <isit> ReadOnly
%type <isit> OptionalLong
%type <isit> Inherit
+ //%type <isit> Required
%type <node> ExtendedAttributeList
%type <node> ExtendedAttributes
@@ -210,6 +216,7 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str)
%type <text> Other
%type <text> OtherOrComma
+
%%
/* [1] default rule to add built AST to passed in one, altered from
@@ -274,34 +281,40 @@ CallbackRestOrInterface:
Interface:
TOK_INTERFACE TOK_IDENTIFIER Inheritance '{' InterfaceMembers '}' ';'
{
- /* extend interface with additional members */
- struct webidl_node *interface_node;
- struct webidl_node *members = NULL;
+ /* extend interface with additional members */
+ struct webidl_node *interface_node;
+ struct webidl_node *members = NULL;
- if ($3 != NULL) {
- members = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE, members, $3);
- }
+ if ($3 != NULL) {
+ members = webidl_node_new(WEBIDL_NODE_TYPE_INHERITANCE,
+ members,
+ $3);
+ }
- members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, members, $5);
+ members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, members, $5);
- interface_node = webidl_node_find_type_ident(*webidl_ast,
+ interface_node = webidl_node_find_type_ident(*webidl_ast,
WEBIDL_NODE_TYPE_INTERFACE,
- $2);
+ $2);
- if (interface_node == NULL) {
- /* no existing interface - create one with ident */
- members = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, members, $2);
+ if (interface_node == NULL) {
+ /* no existing interface - create one with ident */
+ members = webidl_node_new(WEBIDL_NODE_TYPE_IDENT,
+ members,
+ $2);
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE, NULL, members);
- } else {
- /* update the existing interface */
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE,
+ NULL,
+ members);
+ } else {
+ /* update the existing interface */
- /* link member node into interfaces_node */
- webidl_node_add(interface_node, members);
+ /* link member node into interfaces_node */
+ webidl_node_add(interface_node, members);
- $$ = NULL; /* updating so no need to add a new node */
- }
+ $$ = NULL; /* updating so no need to add a new node */
+ }
}
;
@@ -353,64 +366,65 @@ PartialInterface:
/* [9] slightly altered from original grammar to be left recursive */
InterfaceMembers:
- /* empty */
{
- $$ = NULL;
+ $$ = NULL; /* empty */
}
|
InterfaceMembers ExtendedAttributeList InterfaceMember
- /* This needs to deal with members with the same identifier which
- * indicate polymorphism. this is handled in the AST by adding the
- * argument lists for each polymorphism to the same
- * WEBIDL_NODE_TYPE_OPERATION
- *
- * @todo need to consider qualifer/stringifier compatibility
- */
- {
- struct webidl_node *member_node;
- struct webidl_node *ident_node;
- struct webidl_node *list_node;
-
- ident_node = webidl_node_find_type(webidl_node_getnode($3),
- NULL,
- WEBIDL_NODE_TYPE_IDENT);
-
- list_node = webidl_node_find_type(webidl_node_getnode($3),
- NULL,
- WEBIDL_NODE_TYPE_LIST);
-
- if (ident_node == NULL) {
- /* something with no ident - possibly constructors? */
- /* @todo understand this better */
-
- $$ = webidl_node_prepend($1, $3);
-
- } else if (list_node == NULL) {
- /* member with no argument list, usually an attribute, cannot
- * be polymorphic
+ {
+ /* This needs to deal with members with the same
+ * identifier which indicate polymorphism. this is
+ * handled in the AST by adding the argument lists for
+ * each polymorphism to the same
+ * WEBIDL_NODE_TYPE_OPERATION
+ *
+ * @todo need to consider qualifer/stringifier compatibility
*/
+ struct webidl_node *member_node;
+ struct webidl_node *ident_node;
+ struct webidl_node *list_node;
- /* add extended attributes to parameter list */
- webidl_node_add($3, $2);
+ ident_node = webidl_node_find_type(webidl_node_getnode($3),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT);
- $$ = webidl_node_prepend($1, $3);
+ list_node = webidl_node_find_type(webidl_node_getnode($3),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+
+ if (ident_node == NULL) {
+ /* something with no ident - possibly constructors? */
+ /* @todo understand this better */
+
+ $$ = webidl_node_prepend($1, $3);
+
+ } else if (list_node == NULL) {
+ /* member with no argument list, usually an
+ * attribute, cannot be polymorphic
+ */
+
+ /* add extended attributes to parameter list */
+ webidl_node_add($3, $2);
+
+ $$ = webidl_node_prepend($1, $3);
- } else {
- /* add extended attributes to parameter list */
- webidl_node_add(list_node, $2);
-
- /* has an arguemnt list so can be polymorphic */
- member_node = webidl_node_find_type_ident($1,
- webidl_node_gettype($3),
- webidl_node_gettext(ident_node));
- if (member_node == NULL) {
- /* not a member with that ident already present */
- $$ = webidl_node_prepend($1, $3);
} else {
- webidl_node_add(member_node, list_node);
- $$ = $1; /* updated existing node do not add new one */
+ /* add extended attributes to parameter list */
+ webidl_node_add(list_node, $2);
+
+ /* has an arguemnt list so can be polymorphic */
+ member_node = webidl_node_find_type_ident(
+ $1,
+ webidl_node_gettype($3),
+ webidl_node_gettext(ident_node));
+ if (member_node == NULL) {
+ /* not a member with that ident already present */
+ $$ = webidl_node_prepend($1, $3);
+ } else {
+ webidl_node_add(member_node, list_node);
+ $$ = $1; /* updated existing node do not add new one */
+ }
}
- }
}
;
@@ -433,28 +447,134 @@ InterfaceMember:
Dictionary:
TOK_DICTIONARY TOK_IDENTIFIER Inheritance '{' DictionaryMembers '}' ';'
{
- $$ = NULL;
+ /* extend dictionary with additional members */
+ struct webidl_node *dictionary_node;
+ struct webidl_node *members = NULL;
+
+ if ($3 != NULL) {
+ members = webidl_node_new(WEBIDL_NODE_TYPE_INHERITANCE,
+ members,
+ $3);
+ }
+
+ members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, members, $5);
+
+ dictionary_node = webidl_node_find_type_ident(
+ *webidl_ast,
+ WEBIDL_NODE_TYPE_DICTIONARY,
+ $2);
+
+ if (dictionary_node == NULL) {
+ /* no existing interface - create one with ident */
+ members = webidl_node_new(WEBIDL_NODE_TYPE_IDENT,
+ members,
+ $2);
+
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_DICTIONARY,
+ NULL,
+ members);
+ } else {
+ /* update the existing interface */
+
+ /* link member node into interfaces_node */
+ webidl_node_add(dictionary_node, members);
+
+ $$ = NULL; /* updating so no need to add a new node */
+ }
}
;
- /* [12] */
+ /* SE[12] */
DictionaryMembers:
- /* empty */
+ {
+ $$ = NULL; /* empty */
+ }
|
ExtendedAttributeList DictionaryMember DictionaryMembers
+ {
+ /** \todo handle ExtendedAttributeList */
+ $$ = webidl_node_append($3, $2);
+ }
;
- /* [13] */
+ /* SE[13]
+ * Second edition introduces Required except required type may not
+ * have default so why not express this in grammar here and remove
+ * rule 14?
+ */
DictionaryMember:
+ TOK_REQUIRED Type TOK_IDENTIFIER ';'
+ {
+ struct webidl_node *member;
+ /* add name */
+ member = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, NULL, $3);
+ /* add type node */
+ member = webidl_node_prepend(member, $2);
+
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_ARGUMENT, NULL, member);
+ }
+ |
Type TOK_IDENTIFIER Default ';'
+ {
+ struct webidl_node *member;
+ /* add name */
+ member = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, NULL, $2);
+ /* add default */
+ member = webidl_node_new(WEBIDL_NODE_TYPE_OPTIONAL, member, $3);
+ /* add type node */
+ member = webidl_node_prepend(member, $1);
+
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_ARGUMENT, NULL, member);
+ }
;
+/* SE[14] */
+//Required:
+// {
+// $$ = false; /* empty */
+// }
+// |
+// TOK_REQUIRED
+// {
+// $$ = true;
+// }
+// ;
+
/* [14] */
PartialDictionary:
TOK_DICTIONARY TOK_IDENTIFIER '{' DictionaryMembers '}' ';'
{
- $$ = NULL;
+ /* extend dictionary with additional members */
+ struct webidl_node *members;
+ struct webidl_node *dictionary_node;
+
+ dictionary_node = webidl_node_find_type_ident(
+ *webidl_ast,
+ WEBIDL_NODE_TYPE_DICTIONARY,
+ $2);
+
+ members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, NULL, $4);
+
+ if (dictionary_node == NULL) {
+ /* doesnt already exist so create it */
+
+ members = webidl_node_new(WEBIDL_NODE_TYPE_IDENT,
+ members,
+ $2);
+
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_DICTIONARY,
+ NULL,
+ members);
+ } else {
+ /* update the existing dictionary */
+
+ /* link member node into dictionary node */
+ webidl_node_add(dictionary_node, members);
+
+ $$ = NULL; /* updating so no need to add a new node */
+ }
}
+ ;
/* [15] */
Default:
@@ -778,12 +898,25 @@ StaticMemberRest:
/* SE[42] */
AttributeRest:
- TOK_ATTRIBUTE Type TOK_IDENTIFIER ';'
+ TOK_ATTRIBUTE Type AttributeName ';'
{
$$ = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, $2, $3);
}
;
+/* SE[43] */
+AttributeName:
+ AttributeNameKeyword
+ |
+ TOK_IDENTIFIER
+ ;
+
+/* SE[44] */
+AttributeNameKeyword:
+ TOK_REQUIRED
+ {
+ $$ = strdup("required");
+ }
/* [33]
* SE[45]
@@ -1333,7 +1466,9 @@ Other:
}
;
- /* [55] */
+ /* [55]
+ * SE[71] extended with new keywords
+ */
ArgumentNameKeyword:
TOK_ATTRIBUTE
{
@@ -1395,16 +1530,31 @@ ArgumentNameKeyword:
$$ = strdup("interface");
}
|
+ TOK_ITERABLE
+ {
+ $$ = strdup("iterable");
+ }
+ |
TOK_LEGACYCALLER
{
$$ = strdup("legacycaller");
}
|
+ TOK_LEGACYITERABLE
+ {
+ $$ = strdup("legacyiterable");
+ }
+ |
TOK_PARTIAL
{
$$ = strdup("partial");
}
|
+ TOK_REQUIRED
+ {
+ $$ = strdup("required");
+ }
+ |
TOK_SETTER
{
$$ = strdup("setter");