diff options
author | Vincent Sanders <vince@kyllikki.org> | 2012-09-10 00:22:34 +0100 |
---|---|---|
committer | Vincent Sanders <vince@kyllikki.org> | 2012-09-10 00:22:34 +0100 |
commit | 74e143bf3a9cd1cf6748cf1462f8e0fb161d126e (patch) | |
tree | 8526a61b4f6735c7fa0fad17113ae3baee6d6e59 /src | |
parent | 640ed1da81d909bb3c2f01a481e7e8d3336f336c (diff) | |
download | nsgenbind-74e143bf3a9cd1cf6748cf1462f8e0fb161d126e.tar.gz nsgenbind-74e143bf3a9cd1cf6748cf1462f8e0fb161d126e.tar.bz2 |
clean up AST building for both parsers
Diffstat (limited to 'src')
-rw-r--r-- | src/genjsbind-ast.c | 183 | ||||
-rw-r--r-- | src/genjsbind-ast.h | 41 | ||||
-rw-r--r-- | src/genjsbind-lexer.l | 1 | ||||
-rw-r--r-- | src/genjsbind-parser.y | 97 | ||||
-rw-r--r-- | src/genjsbind.c | 9 | ||||
-rw-r--r-- | src/jsapi-libdom.c | 66 | ||||
-rw-r--r-- | src/jsapi-libdom.h | 15 | ||||
-rw-r--r-- | src/webidl-ast.c | 42 | ||||
-rw-r--r-- | src/webidl-ast.h | 32 | ||||
-rw-r--r-- | src/webidl-lexer.l | 1 | ||||
-rw-r--r-- | src/webidl-parser.y | 50 |
11 files changed, 388 insertions, 149 deletions
diff --git a/src/genjsbind-ast.c b/src/genjsbind-ast.c index a2e17df..e722c7c 100644 --- a/src/genjsbind-ast.c +++ b/src/genjsbind-ast.c @@ -16,78 +16,170 @@ #include <string.h> #include "genjsbind-ast.h" -#include "webidl-ast.h" #include "options.h" /* parser and lexer interface */ extern int genjsbind_debug; extern int genjsbind__flex_debug; extern void genjsbind_restart(FILE*); -extern int genjsbind_parse(void); +extern int genjsbind_parse(struct genbind_node **genbind_ast); +/* terminal nodes have a value only */ +struct genbind_node { + enum genbind_node_type type; + struct genbind_node *l; + union { + void *value; + struct genbind_node *node; + char *text; + } r; +}; -#define HDR_COMMENT_SEP "\n * " -#define HDR_COMMENT_SEP_LEN 4 -#define HDR_COMMENT_PREABLE "Generated by nsgenjsapi"HDR_COMMENT_SEP -/* current state */ -struct genbind_ast *genbind_ast; - -int genbind_header_comment(char *comment) +char *genbind_strapp(char *a, char *b) { char *fullstr; int fulllen; - fulllen = strlen(genbind_ast->hdr_comments) + - strlen(comment) + HDR_COMMENT_SEP_LEN + 1; + fulllen = strlen(a) + strlen(b) + 1; fullstr = malloc(fulllen); - snprintf(fullstr, fulllen, "%s"HDR_COMMENT_SEP"%s", genbind_ast->hdr_comments , comment); - free(genbind_ast->hdr_comments); - free(comment); - genbind_ast->hdr_comments = fullstr; - - return 0; + snprintf(fullstr, fulllen, "%s%s", a, b); + free(a); + free(b); + return fullstr; } -int genbind_preamble(char *ccode) +struct genbind_node *genbind_node_link(struct genbind_node *tgt, struct genbind_node *src) { - char *fullstr; - int fulllen; - fulllen = strlen(genbind_ast->preamble) + strlen(ccode) + 1; - fullstr = malloc(fulllen); - snprintf(fullstr, fulllen, "%s%s", genbind_ast->preamble , ccode); - free(genbind_ast->preamble); - free(ccode); - genbind_ast->preamble = fullstr; + tgt->l = src; + return tgt; +} - return 0; +struct genbind_node * +genbind_new_node(enum genbind_node_type type, struct genbind_node *l, void *r) +{ + struct genbind_node *nn; + nn = calloc(1, sizeof(struct genbind_node)); + nn->type = type; + nn->l = l; + nn->r.value = r; + return nn; } -int genbind_interface(char *interface) +int +genbind_node_for_each_type(struct genbind_node *node, + enum genbind_node_type type, + genbind_callback_t *cb, + void *ctx) { - genbind_ast->ifname = interface; return 0; } -static void init_state(void) +char *genbind_node_gettext(struct genbind_node *node) { - /* allocate state */ - genbind_ast = calloc(1, sizeof(struct genbind_ast)); + switch(node->type) { + case GENBIND_NODE_TYPE_WEBIDLFILE: + case GENBIND_NODE_TYPE_STRING: + case GENBIND_NODE_TYPE_PREAMBLE: + case GENBIND_NODE_TYPE_BINDING_IDENT: + case GENBIND_NODE_TYPE_TYPE_IDENT: + case GENBIND_NODE_TYPE_TYPE_NODE: + case GENBIND_NODE_TYPE_TYPE_INTERFACE: + return node->r.text; + + default: + return NULL; + } +} - /* initialise root IDL node */ - webidl_root = webidl_new_node(WEBIDL_NODE_TYPE_ROOT); +struct genbind_node *genbind_node_getnode(struct genbind_node *node) +{ + switch(node->type) { + case GENBIND_NODE_TYPE_HDRCOMMENT: + case GENBIND_NODE_TYPE_BINDING: + case GENBIND_NODE_TYPE_TYPE: + case GENBIND_NODE_TYPE_TYPE_EXTRA: + return node->r.node; + + default: + return NULL; + } +} - /* set default comment header text */ - genbind_ast->hdr_comments = strdup(HDR_COMMENT_PREABLE); +int genbind_ast_dump(struct genbind_node *node) +{ + char *txt; + while (node != NULL) { + switch(node->type) { + case GENBIND_NODE_TYPE_ROOT: + printf("root\n"); + break; + + case GENBIND_NODE_TYPE_WEBIDLFILE: + printf("webidlfile\n"); + break; + + case GENBIND_NODE_TYPE_HDRCOMMENT: + printf("hdrcomment\n"); + break; + + case GENBIND_NODE_TYPE_STRING: + printf("string\n"); + break; + + case GENBIND_NODE_TYPE_PREAMBLE: + printf("preamble\n"); + break; + + case GENBIND_NODE_TYPE_BINDING: + printf("binding\n"); + break; + + case GENBIND_NODE_TYPE_BINDING_IDENT: + printf("binding ident\n"); + break; + + case GENBIND_NODE_TYPE_TYPE: + printf("type\n"); + break; + + case GENBIND_NODE_TYPE_TYPE_IDENT: + printf("type ident\n"); + break; + + case GENBIND_NODE_TYPE_TYPE_NODE: + printf("type node\n"); + break; + + case GENBIND_NODE_TYPE_TYPE_EXTRA: + printf("type extra\n"); + break; + + case GENBIND_NODE_TYPE_TYPE_INTERFACE: + printf("\n"); + break; + + default: + printf("Unknown node type!\n"); + break; + } - genbind_ast->preamble = strdup(""); + txt = genbind_node_gettext(node); + if (txt == NULL) { + genbind_ast_dump(genbind_node_getnode(node)); + } else { + printf(" %s\n", txt); + } + node = node->l; + } + return 0; } -int genbind_parsefile(char *infilename) +int genbind_parsefile(char *infilename, struct genbind_node **ast) { FILE *infile; - /* open input file */ - if ((infilename[0] == '-') && + /* open input file */ + if ((infilename[0] == '-') && (infilename[1] == 0)) { if (options->verbose) { printf("Using stdin for input\n"); @@ -99,17 +191,14 @@ int genbind_parsefile(char *infilename) } infile = fopen(infilename, "r"); } - + if (!infile) { fprintf(stderr, "Error opening %s: %s\n", - infilename, + infilename, strerror(errno)); return 3; } - /* initialise internal state */ - init_state(); - if (options->debug) { genjsbind_debug = 1; genjsbind__flex_debug = 1; @@ -119,8 +208,6 @@ int genbind_parsefile(char *infilename) genjsbind_restart(infile); /* process binding */ - return genjsbind_parse(); + return genjsbind_parse(ast); } - - diff --git a/src/genjsbind-ast.h b/src/genjsbind-ast.h index 0f7c2d2..20ee028 100644 --- a/src/genjsbind-ast.h +++ b/src/genjsbind-ast.h @@ -9,17 +9,38 @@ #ifndef genjsbind_genjsbind_ast_h #define genjsbind_genjsbind_ast_h -int genbind_parsefile(char *infilename); -int genbind_header_comment(char *); -int genbind_interface(char *); -int genbind_preamble(char *ccode); - -struct genbind_ast { - char *hdr_comments; - char *preamble; - char *ifname; +enum genbind_node_type { + GENBIND_NODE_TYPE_ROOT = 0, + GENBIND_NODE_TYPE_WEBIDLFILE, + GENBIND_NODE_TYPE_HDRCOMMENT, + GENBIND_NODE_TYPE_STRING, + GENBIND_NODE_TYPE_PREAMBLE, + GENBIND_NODE_TYPE_BINDING, + GENBIND_NODE_TYPE_BINDING_IDENT, + GENBIND_NODE_TYPE_TYPE, + GENBIND_NODE_TYPE_TYPE_IDENT, + GENBIND_NODE_TYPE_TYPE_NODE, + GENBIND_NODE_TYPE_TYPE_EXTRA, + GENBIND_NODE_TYPE_TYPE_INTERFACE, }; -extern struct genbind_ast *genbind_ast; + +struct genbind_node; + +int genbind_parsefile(char *infilename, struct genbind_node **ast); + +char *genbind_strapp(char *a, char *b); + +struct genbind_node *genbind_new_node(enum genbind_node_type type, struct genbind_node *l, void *r); +struct genbind_node *genbind_node_link(struct genbind_node *tgt, struct genbind_node *src); + +typedef int (genbind_callback_t)(struct genbind_node *node, void *ctx); + +int genbind_node_for_each_type(struct genbind_node *node, enum genbind_node_type type, genbind_callback_t *cb, void *ctx); + +char *genbind_node_gettext(struct genbind_node *node); +struct genbind_node *genbind_node_getnode(struct genbind_node *node); + +int genbind_ast_dump(struct genbind_node *ast); #endif diff --git a/src/genjsbind-lexer.l b/src/genjsbind-lexer.l index 5044c04..89796ad 100644 --- a/src/genjsbind-lexer.l +++ b/src/genjsbind-lexer.l @@ -30,6 +30,7 @@ %option prefix="genjsbind_" %option nounput %option noinput +%option noyywrap /* other Unicode “space separator” */ USP (\xe1\x9a\x80)|(\xe1\xa0\x8e)|(\xe2\x80[\x80-\x8a])|(\xe2\x80\xaf)|(\xe2\x81\x9f)|(\xe3\x80\x80) diff --git a/src/genjsbind-parser.y b/src/genjsbind-parser.y index 0e68a47..17d1850 100644 --- a/src/genjsbind-parser.y +++ b/src/genjsbind-parser.y @@ -17,26 +17,23 @@ char *errtxt; -static void genjsbind_error(const char *str) + static void genjsbind_error(YYLTYPE *locp, struct genbind_node **genbind_ast, const char *str) { errtxt = strdup(str); } -int genjsbind_wrap() -{ - return 1; -} - %} %locations %define api.pure %error-verbose +%parse-param { struct genbind_node **genbind_ast } %union { char* text; + struct genbind_node *node; } %token TOK_IDLFILE @@ -50,19 +47,42 @@ int genjsbind_wrap() %token TOK_NODE %token <text> TOK_IDENTIFIER - %token <text> TOK_STRING_LITERAL %token <text> TOK_CCODE_LITERAL +%type <text> CBlock + +%type <node> Statement +%type <node> Statements +%type <node> IdlFile +%type <node> Preamble +%type <node> HdrComment +%type <node> Strings +%type <node> Binding +%type <node> BindingArgs +%type <node> BindingArg +%type <node> Type +%type <node> TypeArgs +%type <node> Extra +%type <node> Interface +%type <node> Node %% - /* [1] start with Statements */ +Input + : + Statements { *genbind_ast = $1 } + ; + + Statements : Statement | Statements Statement + { + $$ = genbind_node_link($2, $1); + } | error ';' { @@ -85,55 +105,60 @@ Statement /* [3] load a web IDL file */ IdlFile - : TOK_IDLFILE TOK_STRING_LITERAL ';' + : + TOK_IDLFILE TOK_STRING_LITERAL ';' { - if (webidl_parsefile($2) != 0) { - YYABORT; - } + $$ = genbind_new_node(GENBIND_NODE_TYPE_WEBIDLFILE, NULL, $2); } ; HdrComment - : TOK_HDR_COMMENT HdrStrings ';' + : + TOK_HDR_COMMENT Strings ';' { - + $$ = genbind_new_node(GENBIND_NODE_TYPE_HDRCOMMENT, NULL, $2); } ; -HdrStrings +Strings : TOK_STRING_LITERAL { - genbind_header_comment($1); + $$ = genbind_new_node(GENBIND_NODE_TYPE_STRING, NULL, $1); } | - HdrStrings TOK_STRING_LITERAL + Strings TOK_STRING_LITERAL { - genbind_header_comment($2); + $$ = genbind_new_node(GENBIND_NODE_TYPE_STRING, $1, $2); } ; Preamble : TOK_PREAMBLE CBlock ';' + { + $$ = genbind_new_node(GENBIND_NODE_TYPE_PREAMBLE, NULL, $2); + } ; CBlock : TOK_CCODE_LITERAL - { - genbind_preamble($1); - } | CBlock TOK_CCODE_LITERAL { - genbind_preamble($2); + $$ = genbind_strapp($1, $2); } ; Binding : TOK_BINDING TOK_IDENTIFIER '{' BindingArgs '}' ';' + { + $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING, + NULL, + genbind_new_node(GENBIND_NODE_TYPE_BINDING_IDENT, $4, $2)); + } ; BindingArgs @@ -141,6 +166,9 @@ BindingArgs BindingArg | BindingArgs BindingArg + { + $$ = genbind_node_link($2, $1); + } ; BindingArg @@ -155,23 +183,44 @@ BindingArg Type : TOK_TYPE TOK_IDENTIFIER '{' TypeArgs '}' ';' + { + $$ = genbind_new_node(GENBIND_NODE_TYPE_TYPE, + NULL, + genbind_new_node(GENBIND_NODE_TYPE_TYPE_IDENT, $4, $2)); + } ; TypeArgs : + /* empty */ + { + $$ = NULL; + } + | + Node + ; + +Node + : TOK_NODE TOK_IDENTIFIER ';' + { + $$ = genbind_new_node(GENBIND_NODE_TYPE_TYPE_NODE, NULL, $2); + } ; Extra : - TOK_EXTRA TOK_STRING_LITERAL ';' + TOK_EXTRA Strings ';' + { + $$ = genbind_new_node(GENBIND_NODE_TYPE_TYPE_EXTRA, NULL, $2); + } ; Interface : TOK_INTERFACE TOK_IDENTIFIER ';' { - genbind_interface($2); + $$ = genbind_new_node(GENBIND_NODE_TYPE_TYPE_INTERFACE, NULL, $2); } ; diff --git a/src/genjsbind.c b/src/genjsbind.c index 21bf8b1..559602b 100644 --- a/src/genjsbind.c +++ b/src/genjsbind.c @@ -73,6 +73,7 @@ static struct options* process_cmdline(int argc, char **argv) int main(int argc, char **argv) { int res; + struct genbind_node *genbind_root; options = process_cmdline(argc, argv); if (options == NULL) { @@ -86,13 +87,17 @@ int main(int argc, char **argv) return 2; } - res = genbind_parsefile(options->infilename); + res = genbind_parsefile(options->infilename, &genbind_root); if (res != 0) { fprintf(stderr, "Error: parse failed with code %d\n", res); return res; } - res = jsapi_libdom_output(options->outfilename); + if (options->verbose) { + genbind_ast_dump(genbind_root); + } + + res = jsapi_libdom_output(options->outfilename, genbind_root); if (res != 0) { fprintf(stderr, "Error: output failed with code %d\n", res); unlink(options->outfilename); diff --git a/src/jsapi-libdom.c b/src/jsapi-libdom.c index 02033e1..3d07161 100644 --- a/src/jsapi-libdom.c +++ b/src/jsapi-libdom.c @@ -11,11 +11,69 @@ #include <string.h> #include "genjsbind-ast.h" +#include "webidl-ast.h" #include "jsapi-libdom.h" -int jsapi_libdom_output(char *outfilename) +/* +#define HDR_COMMENT_SEP "\n * " +#define HDR_COMMENT_SEP_LEN 4 +#define HDR_COMMENT_PREABLE "Generated by nsgenjsapi"HDR_COMMENT_SEP + +int genbind_header_comment(char *comment) +{ + char *fullstr; + int fulllen; + fulllen = strlen(genbind_ast->hdr_comments) + + strlen(comment) + HDR_COMMENT_SEP_LEN + 1; + fullstr = malloc(fulllen); + snprintf(fullstr, fulllen, "%s"HDR_COMMENT_SEP"%s", genbind_ast->hdr_comments , comment); + free(genbind_ast->hdr_comments); + free(comment); + genbind_ast->hdr_comments = fullstr; + + return 0; +} + +{ + if (webidl_parsefile($2) != 0) { + YYABORT; +} +} +*/ + /* initialise root IDL node */ +/* webidl_root = + +*/ + +static int webidl_file_cb(struct genbind_node *node, void *ctx) +{ + struct webidl_node **webidl_ast = ctx; + char *filename; + + filename = genbind_node_gettext(node); + + return webidl_parsefile(filename, webidl_ast); + +} + +static int +read_webidl(struct genbind_node *genbind_ast, struct webidl_node **webidl_ast) +{ + return genbind_node_for_each_type(genbind_ast, + GENBIND_NODE_TYPE_WEBIDLFILE, + webidl_file_cb, + webidl_ast); + +} + +int jsapi_libdom_output(char *outfilename, struct genbind_node *genbind_ast) { FILE *outfile = NULL; + struct webidl_node *webidl_ast = NULL; + + read_webidl(genbind_ast, &webidl_ast); + + /* open output file */ if (outfilename == NULL) { outfile = stdout; @@ -30,12 +88,12 @@ int jsapi_libdom_output(char *outfilename) return 4; } - fprintf(outfile, "/* %s\n */\n\n", genbind_ast->hdr_comments); + /* fprintf(outfile, " %s\n \n\n", genbind_ast->hdr_comments); fprintf(outfile, "%s", genbind_ast->preamble); - fprintf(outfile, "/* interface %s */\n\n", genbind_ast->ifname); - + fprintf(outfile, " interface %s \n\n", genbind_ast->ifname); +*/ fclose(outfile); return 0; diff --git a/src/jsapi-libdom.h b/src/jsapi-libdom.h index 6ee8db7..fe28723 100644 --- a/src/jsapi-libdom.h +++ b/src/jsapi-libdom.h @@ -1 +1,14 @@ -int jsapi_libdom_output(char *outfile); +/* binding generator output + * + * This file is part of nsgenjsbind. + * Licensed under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org> + */ + +#ifndef genjsbind_jsapi_libdom_h +#define genjsbind_jsapi_libdom_h + +int jsapi_libdom_output(char *outfile, struct genbind_node *genbind_root); + +#endif diff --git a/src/webidl-ast.c b/src/webidl-ast.c index 1eddd68..e19fb80 100644 --- a/src/webidl-ast.c +++ b/src/webidl-ast.c @@ -18,19 +18,8 @@ extern int webidl_debug; extern int webidl__flex_debug; extern void webidl_restart(FILE*); -extern int webidl_parse(void); +extern int webidl_parse(struct webidl_node **webidl_ast); -struct webidl_node *webidl_root; - -struct webidl_node *webidl_new_node(enum webidl_node_type type) -{ - struct webidl_node *nnode; - nnode = calloc(1, sizeof(struct webidl_node)); - if (nnode != NULL) { - nnode->type = type; - } - return nnode; -} static FILE *idlopen(const char *filename) { @@ -55,10 +44,32 @@ static FILE *idlopen(const char *filename) return idlfile; } -int webidl_parsefile(char *filename) +struct webidl_node * +webidl_node_link(struct webidl_node *tgt, struct webidl_node *src) { - /* set flex to read from file */ + if (tgt != NULL) { + tgt->l = src; + return tgt; + } + return src; +} + +struct webidl_node *webidl_node_new(int type, struct webidl_node *l, void *r) +{ + struct webidl_node *nn; + nn = calloc(1, sizeof(struct webidl_node)); + nn->type = type; + nn->l = l; + nn->r.text = r; + return nn; +} + + +int webidl_parsefile(char *filename, struct webidl_node **webidl_ast) +{ + FILE *idlfile; + idlfile = idlopen(filename); if (!idlfile) { fprintf(stderr, "Error opening %s: %s\n", @@ -72,8 +83,9 @@ int webidl_parsefile(char *filename) webidl__flex_debug = 1; } + /* set flex to read from file */ webidl_restart(idlfile); /* parse the file */ - return webidl_parse(); + return webidl_parse(webidl_ast); } diff --git a/src/webidl-ast.h b/src/webidl-ast.h index 5dfd2a8..3c93305 100644 --- a/src/webidl-ast.h +++ b/src/webidl-ast.h @@ -9,35 +9,23 @@ #ifndef genjsbind_webidl_ast_h #define genjsbind_webidl_ast_h -enum webidl_node_type { - WEBIDL_NODE_TYPE_ROOT, - WEBIDL_NODE_TYPE_INTERFACE, -}; - -struct webidl_ifmember { - char *name; -}; - -struct webidl_if { - char *name; - struct webidl_ifmember* members; -}; - +#define WEBIDL_NODE_TYPE_ROOT 0 struct webidl_node { - enum webidl_node_type type; + int type; + struct webidl_node *l; union { - struct webidl_node *nodes; - struct webidl_if interface; - } data; + struct webidl_node *node; + char *text; + } r; }; -extern struct webidl_node *webidl_root; - /** parse web idl file */ -int webidl_parsefile(char *filename); +int webidl_parsefile(char *filename, struct webidl_node **webidl_ast); + +struct webidl_node *webidl_node_new(int type, struct webidl_node *l, void *r); -struct webidl_node *webidl_new_node(enum webidl_node_type type); +struct webidl_node *webidl_node_link(struct webidl_node *tgt, struct webidl_node *src); #endif diff --git a/src/webidl-lexer.l b/src/webidl-lexer.l index 5c8234c..bfa4fb5 100644 --- a/src/webidl-lexer.l +++ b/src/webidl-lexer.l @@ -38,6 +38,7 @@ %option warn %option prefix="webidl_" %option nounput +%option noyywrap /* regular definitions */ diff --git a/src/webidl-parser.y b/src/webidl-parser.y index db10ab7..b45a8bd 100644 --- a/src/webidl-parser.y +++ b/src/webidl-parser.y @@ -21,24 +21,20 @@ char *errtxt; -static void webidl_error(const char *str) +static void +webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str) { + locp = locp; + winbind_ast = winbind_ast; errtxt = strdup(str); } -int webidl_wrap() -{ - return 1; -} - %} %locations %define api.pure %error-verbose - - /* the w3c grammar results in 19 shift/reduce conficts */ -%expect 19 +%parse-param { struct webidl_node **webidl_ast } %union { @@ -46,6 +42,7 @@ int webidl_wrap() char* text; long value; struct ifmember_s **ifmember; + struct webidl_node *node; } @@ -112,27 +109,36 @@ int webidl_wrap() %type <text> Inheritance %type <ifmember> InterfaceMembers +%type <node> Definitions +%type <node> Definition + %% - /* [1] altered from original grammar to be left recusive, avoid reduce/reduce - * conficts and have an error term. - * - * By omitting the empty term from here reduce/reduce conficts are removed as - * both ExtendedAttributeList and Definition (by way of Exception) can end - * up with an empty term anyhow. - */ -Definitions: - ExtendedAttributeList Definition - | - Definitions ExtendedAttributeList Definition + /* default rule to add built AST to passed in one */ +Input: + Definitions + { *webidl_ast = webidl_node_link(*webidl_ast, $1); } | - error ';' + error { fprintf(stderr, "%d: %s\n", yylloc.first_line, errtxt); free(errtxt); YYABORT ; } ; + + /* [1] altered from original grammar to be left recusive, */ +Definitions: + /* empty */ + { + $$ = NULL; + } + | + Definitions ExtendedAttributeList Definition + { + $$ = webidl_node_link($1, $3); + } + ; /* [2] */ Definition: @@ -247,8 +253,6 @@ DefaultValue: /* [17] */ Exception: - /* empty */ - | TOK_EXCEPTION TOK_IDENTIFIER Inheritance '{' ExceptionMembers '}' ';' ; |