📄 parser.y
字号:
/*************************************************************************** parser.y (IDL yacc parser and tree generation) Copyright (C) 1998, 1999 Andrew T. Veliath This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: parser.y,v 1.152 1999/06/09 17:11:15 andrewtv Exp $***************************************************************************/%{#include <assert.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h>#include <errno.h>#include "rename.h"#include "util.h"#define REF_IDENTS#define do_binop(rv,op,a,b) do { \ if (IDL_binop_chktypes (op, a, b)) \ YYABORT; \ if (!(__IDL_flags & IDLF_NO_EVAL_CONST)) { \ rv = IDL_binop_eval (op, a, b); \ IDL_tree_free (a); \ IDL_tree_free (b); \ if (!rv) YYABORT; \ } else { \ rv = IDL_binop_new (op, a, b); \ } \} while (0)#define do_unaryop(rv,op,a) do { \ if (IDL_unaryop_chktypes (op, a)) \ YYABORT; \ if (!(__IDL_flags & IDLF_NO_EVAL_CONST)) { \ rv = IDL_unaryop_eval (op, a); \ IDL_tree_free (a); \ if (!rv) YYABORT; \ } else { \ rv = IDL_unaryop_new (op, a); \ } \} while (0)#define assign_declspec(tree,declspec) do { \ IDL_NODE_DECLSPEC (tree) = declspec; \ if (__IDL_inhibits > 0 || \ (__IDL_flags & IDLF_INHIBIT_INCLUDES && \ __IDL_flagsi & IDLFP_IN_INCLUDES)) { \ IDL_NODE_DECLSPEC (tree) |= \ IDLF_DECLSPEC_EXIST | \ IDLF_DECLSPEC_INHIBIT; \ } \} while (0)#define assign_props(tree,props) do { \ if (__IDL_flags & IDLF_PROPERTIES) \ IDL_NODE_PROPERTIES (tree) = (props); \ else \ __IDL_free_properties (props); \} while (0)extern int yylex (void);static IDL_declspec_t IDL_parse_declspec (const char *strspec);static int IDL_binop_chktypes (enum IDL_binop op, IDL_tree a, IDL_tree b);static int IDL_unaryop_chktypes (enum IDL_unaryop op, IDL_tree a);static IDL_tree IDL_binop_eval (enum IDL_binop op, IDL_tree a, IDL_tree b);static IDL_tree IDL_unaryop_eval (enum IDL_unaryop op, IDL_tree a);static IDL_tree list_start (IDL_tree a, gboolean filter_null);static IDL_tree list_chain (IDL_tree a, IDL_tree b, gboolean filter_null);static IDL_tree zlist_chain (IDL_tree a, IDL_tree b, gboolean filter_null);static int do_token_error (IDL_tree p, const char *message, gboolean prev);static void illegal_context_type_error (IDL_tree p, const char *what);static void illegal_type_error (IDL_tree p, const char *message);%}%union { IDL_tree tree; struct { IDL_tree tree; gpointer data; } treedata; GHashTable *hash_table; char *str; gboolean boolean; IDL_declspec_t declspec; IDL_longlong_t integer; double floatp; enum IDL_unaryop unaryop; enum IDL_param_attr paramattr;}/* Terminals */%token TOK_ANY%token TOK_ATTRIBUTE%token TOK_BOOLEAN%token TOK_CASE%token TOK_CHAR%token TOK_CONST%token TOK_CONTEXT%token TOK_DEFAULT%token TOK_DOUBLE%token TOK_ENUM%token TOK_EXCEPTION%token TOK_FALSE%token TOK_FIXED%token TOK_FLOAT%token TOK_IN %token TOK_INOUT%token TOK_INTERFACE%token TOK_LONG%token TOK_MODULE%token TOK_NATIVE%token TOK_OBJECT%token TOK_OCTET%token TOK_ONEWAY%token TOK_OP_SCOPE%token TOK_OP_SHL%token TOK_OP_SHR%token TOK_OUT%token TOK_RAISES%token TOK_READONLY %token TOK_SEQUENCE%token TOK_SHORT%token TOK_STRING%token TOK_STRUCT%token TOK_SWITCH%token TOK_TRUE%token TOK_TYPECODE%token TOK_TYPEDEF%token TOK_UNION%token TOK_UNSIGNED%token TOK_VARARGS%token TOK_VOID%token TOK_WCHAR%token TOK_WSTRING%token <floatp> TOK_FLOATP%token <integer> TOK_INTEGER%token <str> TOK_DECLSPEC TOK_PROP_KEY%token <str> TOK_PROP_VALUE TOK_NATIVE_TYPE%token <str> TOK_IDENT TOK_SQSTRING TOK_DQSTRING TOK_FIXEDP%token <tree> TOK_CODEFRAG/* Non-Terminals */%type <tree> add_expr%type <tree> and_expr%type <tree> any_type%type <tree> array_declarator%type <tree> attr_dcl%type <tree> attr_dcl_def%type <tree> base_type_spec%type <tree> boolean_lit%type <tree> boolean_type%type <tree> case_label%type <tree> case_label_list%type <tree> case_stmt%type <tree> case_stmt_list%type <tree> char_lit%type <tree> char_type%type <tree> codefrag%type <tree> complex_declarator%type <tree> const_dcl%type <tree> const_dcl_def%type <tree> const_exp%type <tree> const_type%type <tree> constr_type_spec%type <tree> context_expr%type <tree> cur_ns_new_or_prev_ident%type <tree> declarator%type <tree> declarator_list%type <tree> definition%type <tree> definition_list%type <tree> element_spec%type <tree> enum_type%type <tree> enumerator_list%type <tree> except_dcl%type <tree> except_dcl_def%type <tree> export%type <tree> export_list%type <tree> fixed_array_size%type <tree> fixed_array_size_list%type <tree> fixed_pt_const_type%type <tree> fixed_pt_lit%type <tree> fixed_pt_type%type <tree> floating_pt_lit%type <tree> floating_pt_type%type <tree> ident%type <tree> illegal_ident%type <tree> integer_lit%type <tree> integer_type%type <tree> interface%type <tree> interface_body%type <tree> interface_catch_ident%type <tree> is_context_expr%type <tree> is_raises_expr%type <tree> literal%type <tree> member%type <tree> member_list%type <tree> member_zlist%type <tree> module%type <tree> mult_expr%type <tree> new_ident%type <tree> new_or_prev_scope%type <tree> new_scope%type <tree> ns_global_ident%type <tree> ns_new_ident%type <tree> ns_prev_ident%type <tree> ns_scoped_name%type <tree> object_type%type <tree> octet_type%type <tree> op_dcl%type <tree> op_dcl_def%type <tree> op_param_type_spec%type <tree> op_param_type_spec_illegal%type <tree> op_type_spec%type <tree> or_expr%type <tree> param_dcl%type <tree> param_dcl_list%type <tree> param_type_spec%type <tree> pop_scope%type <tree> positive_int_const%type <tree> primary_expr%type <tree> raises_expr%type <tree> scoped_name%type <tree> scoped_name_list%type <tree> sequence_type%type <tree> shift_expr%type <tree> simple_declarator%type <tree> simple_declarator_list%type <tree> simple_type_spec%type <tree> specification%type <tree> string_lit%type <tree> string_lit_list%type <tree> string_type%type <tree> struct_type%type <tree> switch_body%type <tree> switch_type_spec%type <tree> template_type_spec%type <tree> type_dcl%type <tree> type_dcl_def%type <tree> type_declarator%type <tree> type_spec%type <tree> unary_expr%type <tree> union_type%type <tree> useless_semicolon%type <tree> wide_char_type%type <tree> wide_string_type%type <tree> xor_expr%type <tree> z_definition_list%type <tree> z_inheritance%type <tree> z_new_ident_catch%type <tree> z_new_scope_catch%type <tree> typecode_type%type <treedata> parameter_dcls%type <declspec> z_declspec module_declspec%type <hash_table> z_props prop_hash%type <boolean> is_readonly is_oneway%type <boolean> is_varargs is_cvarargs%type <integer> signed_int unsigned_int%type <paramattr> param_attribute%type <str> sqstring dqstring dqstring_cat%type <unaryop> unary_op%%specification: /* empty */ { yyerror ("Empty file"); YYABORT; }| definition_list { __IDL_root = $1; } ;z_definition_list: /* empty */ { $$ = NULL; }| definition_list ;definition_list: definition { $$ = list_start ($1, TRUE); }| definition_list definition { $$ = list_chain ($1, $2, TRUE); } ;check_semicolon: ';'| /* empty */ { if (do_token_error ($<tree>0, "Missing semicolon after", TRUE)) YYABORT;} ;useless_semicolon: ';' { yyerror ("Dangling semicolon has no effect"); $$ = NULL;} ;check_comma: ','| /* empty */ { if (do_token_error ($<tree>0, "Missing comma after", TRUE)) YYABORT;} ;illegal_ident: scoped_name { if (IDL_NODE_UP ($1)) do_token_error (IDL_NODE_UP ($1), "Illegal context for", FALSE); else yyerror ("Illegal context for identifier"); YYABORT;} ;definition: type_dcl check_semicolon| const_dcl check_semicolon| except_dcl check_semicolon| interface check_semicolon| module check_semicolon| codefrag| illegal_ident| useless_semicolon ;module_declspec: z_declspec TOK_MODULE ;module: module_declspec new_or_prev_scope { if (IDL_NODE_UP ($2) != NULL && IDL_NODE_TYPE (IDL_NODE_UP ($2)) != IDLN_MODULE) { yyerror ("Module definition conflicts"); do_token_error (IDL_NODE_UP ($2), "with", FALSE); YYABORT; }} '{' z_definition_list '}' pop_scope { IDL_tree module; if ($5 == NULL) { yyerrorv ("Empty module declaration `%s' is not legal IDL", IDL_IDENT ($2).str); module = NULL; } if (__IDL_flags & IDLF_COMBINE_REOPENED_MODULES) { if (IDL_NODE_UP ($2) == NULL) module = IDL_module_new ($2, $5); else { module = IDL_NODE_UP ($2); IDL_MODULE (module).definition_list = IDL_list_concat (IDL_MODULE (module).definition_list, $5); module = NULL; } } else module = IDL_module_new ($2, $5); $$ = module; if ($$) assign_declspec ($$, $1);} ;interface_catch_ident: new_or_prev_scope| TOK_OBJECT { yyerror ("Interfaces cannot be named `Object'"); YYABORT;}| TOK_TYPECODE { yyerror ("Interfaces cannot be named `TypeCode'"); YYABORT;} ;interface: z_declspec z_props TOK_INTERFACE interface_catch_ident { assert ($4 != NULL); assert (IDL_NODE_TYPE ($4) == IDLN_IDENT); assert (IDL_IDENT_TO_NS ($4) != NULL); assert (IDL_NODE_TYPE (IDL_IDENT_TO_NS ($4)) == IDLN_GENTREE); if (IDL_NODE_UP ($4) != NULL && IDL_NODE_TYPE (IDL_NODE_UP ($4)) != IDLN_INTERFACE && IDL_NODE_TYPE (IDL_NODE_UP ($4)) != IDLN_FORWARD_DCL) { yyerrorl ("Interface definition conflicts", __IDL_prev_token_line - __IDL_cur_token_line); do_token_error (IDL_NODE_UP ($4), "with", FALSE); YYABORT; } else if (IDL_NODE_UP ($4) != NULL && IDL_NODE_TYPE (IDL_NODE_UP ($4)) != IDLN_FORWARD_DCL) { yyerrorv ("Cannot redeclare interface `%s'", IDL_IDENT ($4).str); IDL_tree_error ($4, "Previous declaration of interface `%s'", IDL_IDENT ($4).str); YYABORT; } else if (IDL_NODE_UP ($4) != NULL && IDL_NODE_TYPE (IDL_NODE_UP ($4)) == IDLN_FORWARD_DCL) __IDL_assign_this_location ($4, __IDL_cur_filename, __IDL_cur_line);} pop_scope z_inheritance { IDL_GENTREE (IDL_IDENT_TO_NS ($4))._import = $7; IDL_ns_push_scope (__IDL_root_ns, IDL_IDENT_TO_NS ($4)); if (IDL_ns_check_for_ambiguous_inheritance ($4, $7)) __IDL_is_okay = FALSE;} '{' interface_body '}' pop_scope { $$ = IDL_interface_new ($4, $7, $10); assign_declspec ($$, $1); assign_props (IDL_INTERFACE ($$).ident, $2);}| z_declspec z_props TOK_INTERFACE interface_catch_ident pop_scope { if ($2) yywarningv (IDL_WARNING1, "Ignoring properties for forward declaration `%s'", IDL_IDENT ($4).str); $$ = IDL_forward_dcl_new ($4); assign_declspec ($$, $1);} ;z_inheritance: /* empty */ { $$ = NULL; }| ':' scoped_name_list { GHashTable *table = g_hash_table_new (g_direct_hash, g_direct_equal); gboolean die = FALSE; IDL_tree p = $2; assert (IDL_NODE_TYPE (p) == IDLN_LIST); for (; p != NULL && !die; p = IDL_LIST (p).next) { assert (IDL_LIST (p).data != NULL); assert (IDL_NODE_TYPE (IDL_LIST (p).data) == IDLN_IDENT); if (g_hash_table_lookup_extended (table, IDL_LIST (p).data, NULL, NULL)) { char *s = IDL_ns_ident_to_qstring (IDL_LIST (p).data, "::", 0); yyerrorv ("Cannot inherit from interface `%s' more than once", s); g_free (s); die = TRUE; break; } else g_hash_table_insert (table, IDL_LIST (p).data, NULL); if (IDL_NODE_TYPE (IDL_NODE_UP (IDL_LIST (p).data)) == IDLN_FORWARD_DCL) { char *s = IDL_ns_ident_to_qstring (IDL_LIST (p).data, "::", 0); yyerrorv ("Incomplete definition of interface `%s'", s); IDL_tree_error (IDL_LIST (p).data, "Previous forward declaration of `%s'", s); g_free (s); die = TRUE; } else if (IDL_NODE_TYPE (IDL_NODE_UP (IDL_LIST (p).data)) != IDLN_INTERFACE) { char *s = IDL_ns_ident_to_qstring (IDL_LIST (p).data, "::", 0); yyerrorv ("`%s' is not an interface", s); IDL_tree_error (IDL_LIST (p).data, "Previous declaration of `%s'", s); g_free (s); die = TRUE; } } g_hash_table_destroy (table); if (die) YYABORT; $$ = $2;} ;scoped_name_list: scoped_name { $$ = list_start ($1, TRUE); }| scoped_name_list check_comma scoped_name { $$ = list_chain ($1, $3, TRUE); } ;interface_body: export_list ;export_list: /* empty */ { $$ = NULL; }| export_list export { $$ = zlist_chain ($1, $2, TRUE); } ;export: type_dcl check_semicolon| except_dcl check_semicolon| op_dcl check_semicolon| attr_dcl check_semicolon| const_dcl check_semicolon| codefrag| useless_semicolon ;type_dcl: z_declspec type_dcl_def { $$ = $2; assign_declspec ($$, $1);} ;type_dcl_def: z_props TOK_TYPEDEF type_declarator {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -