%{
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Portions of this software have been released under the following terms:
*
* (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY
* (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file for any
* purpose is hereby granted without fee, provided that the above
* copyright notices and this notice appears in all source code copies,
* and that none of the names of Open Software Foundation, Inc., Hewlett-
* Packard Company or Digital Equipment Corporation be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. Neither Open Software
* Foundation, Inc., Hewlett-Packard Company nor Digital
* Equipment Corporation makes any representations about the suitability
* of this software for any purpose.
*
* Copyright (c) 2007, Novell, Inc. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Novell Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
**
** NAME:
**
** IDL.Y
**
** FACILITY:
**
** Interface Definition Language (IDL) Compiler
**
** ABSTRACT:
**
** This module defines the main IDL grammar accepted
** by the IDL compiler.
**
** VERSION: DCE 1.0
**
*/
#include <sys/types.h>
#include <nidl.h>
#include <nametbl.h>
#include <errors.h>
#include <ast.h>
#include <astp.h>
#include <frontend.h>
#define YYDEBUG 1
extern boolean search_attributes_table ;
/*
** Local cells used for inter-production communication
*/
static ASTP_attr_k_t ASTP_bound_type; /* Array bound attribute */
/* An opaque pointer. */
#ifndef YY_TYPEDEF_YY_SCANNER_T
#define YY_TYPEDEF_YY_SCANNER_T
typedef void* yyscan_t;
#endif
typedef struct nidl_parser_state_t
{
yyscan_t nidl_yyscanner;
unsigned nidl_yynerrs;
parser_location_t nidl_location;
} nidl_parser_state_t;
static void nidl_yyerror (YYLTYPE *, nidl_parser_p, char const *);
%}
%locations
%defines
%error-verbose
%pure-parser
%name-prefix="nidl_yy"
/* Tell Bison that the Flexer takes a yyscan_t parameter. */
%lex-param { void * lexxer }
/* Tell Bison that we will pass the yyscan_t scanner into yyparse. */
%parse-param { nidl_parser_state_t * nidl }
/* Tell Bison how to get the lexxer argument from the parser state. */
%{
#define lexxer nidl->nidl_yyscanner
%}
/* Declaration of yylval, yyval */
%union
{
NAMETABLE_id_t y_id ; /* Identifier */
long y_ptrlevels; /* levels of * for pointers */
long y_ptrclass; /* class of pointer */
STRTAB_str_t y_string ; /* String */
STRTAB_str_t y_float ; /* Float constant */
AST_export_n_t* y_export ; /* an export node */
AST_import_n_t* y_import ; /* Import node */
AST_exception_n_t* y_exception ; /* Exception node */
AST_constant_n_t* y_constant; /* Constant node */
AST_parameter_n_t* y_parameter ; /* Parameter node */
AST_type_n_t* y_type ; /* Type node */
AST_type_p_n_t* y_type_ptr ; /* Type pointer node */
AST_field_n_t* y_field ; /* Field node */
AST_arm_n_t* y_arm ; /* Union variant arm */
AST_operation_n_t* y_operation ; /* Routine node */
AST_interface_n_t* y_interface ; /* Interface node */
AST_case_label_n_t* y_label ; /* Union tags */
ASTP_declarator_n_t* y_declarator ; /* Declarator info */
ASTP_array_index_n_t* y_index ; /* Array index info */
nidl_uuid_t y_uuid ; /* Universal UID */
char y_char; /* character constant */
ASTP_attributes_t y_attributes; /* attributes flags */
AST_cpp_quote_n_t* y_cpp_quote; /* Quoted C within interface treated as one 'kind' of export node + quote outside interfaces */
struct {
long int_val ; /* Integer constant */
AST_type_k_t int_size;
int int_signed;
} y_int_info; /* int size and signedness */
AST_exp_n_t * y_exp; /* constant expression info */
}
%{
#include <nidl_l.h>
%}
/********************************************************************/
/* */
/* Tokens used by the IDL parser. */
/* */
/********************************************************************/
/* Keywords */
%token ALIGN_KW
%token BYTE_KW
%token CHAR_KW
%token CONST_KW
%token DEFAULT_KW
%token ENUM_KW
%token EXCEPTIONS_KW
%token FLOAT_KW
%token HYPER_KW
%token INT_KW
%token INTERFACE_KW
%token IMPORT_KW
%token LIBRARY_KW
%token LONG_KW
%token PIPE_KW
%token REF_KW
%token SMALL_KW
%token STRUCT_KW
%token TYPEDEF_KW
%token UNION_KW
%token UNSIGNED_KW
%token SHORT_KW
%token VOID_KW
%token DOUBLE_KW
%token BOOLEAN_KW
%token CASE_KW
%token SWITCH_KW
%token HANDLE_T_KW
%token TRUE_KW
%token FALSE_KW
%token NULL_KW
%token BROADCAST_KW
%token COMM_STATUS_KW
%token CONTEXT_HANDLE_KW
%token FIRST_IS_KW
%token HANDLE_KW
%token IDEMPOTENT_KW
%token IGNORE_KW
%token CALL_AS_KW
%token IID_IS_KW
%token IMPLICIT_HANDLE_KW
%token IN_KW
%token LAST_IS_KW
%token LENGTH_IS_KW
%token LOCAL_KW
%token MAX_IS_KW
%token MAYBE_KW
%token MIN_IS_KW
%token MUTABLE_KW
%token OUT_KW
%token OBJECT_KW
%token POINTER_DEFAULT_KW
%token ENDPOINT_KW
%token PTR_KW
%token RANGE_KW
%token REFLECT_DELETIONS_KW
%token REMOTE_KW
%token SECURE_KW
%token SHAPE_KW
%token SIZE_IS_KW
%token STRING_KW
%token SWITCH_IS_KW
%token SWITCH_TYPE_KW
%token TRANSMIT_AS_KW
%token UNIQUE_KW
%token UUID_KW
%token VERSION_KW
%token V1_ARRAY_KW
%token V1_STRING_KW
%token V1_ENUM_KW
%token V1_STRUCT_KW
/* Added by Centeris */
%token CPP_QUOTE_KW
/* Non-keyword tokens */
%token UUID_REP
/* Punctuation */
%token COLON
%token COMMA
%token DOTDOT
%token EQUAL
%token LBRACE
%token LBRACKET
%token LPAREN
%token RBRACE
%token RBRACKET
%token RPAREN
%token SEMI
%token STAR
%token QUESTION
%token BAR
%token BARBAR
%token LANGLE
%token LANGLEANGLE
%token RANGLE
%token RANGLEANGLE
%token AMP
%token AMPAMP
%token LESSEQUAL
%token GREATEREQUAL
%token EQUALEQUAL
%token CARET
%token PLUS
%token MINUS
%token NOT
%token NOTEQUAL
%token SLASH
%token PERCENT
%token TILDE
%token POUND
%token UNKNOWN /* Something that doesn't fit in any other token class */
/* Tokens setting yylval */
%token <y_id> IDENTIFIER
%token <y_string> STRING
%token <y_int_info> INTEGER_NUMERIC
%token <y_char> CHAR
%token <y_float> FLOAT_NUMERIC
%start grammar_start
%%
/********************************************************************/
/* */
/* Syntax description and actions for IDL */
/* */
/********************************************************************/
grammar_start: interfaces cpp_quotes
{
global_cppquotes_post = (AST_cpp_quote_n_t*)AST_concat_element(
(ASTP_node_t*)global_cppquotes_post, (ASTP_node_t*)$<y_cpp_quote>2);
}
|
optional_imports_cppquotes
|
{
$<y_import>$ = (AST_import_n_t *)NULL;
}
/*{
#if 0
global_imports = (AST_import_n_t*)AST_concat_element(
(ASTP_node_t*)global_imports, (ASTP_node_t*)$<y_import>1);
#endif
global_cppquotes_post = (AST_cpp_quote_n_t*)AST_concat_element(
(ASTP_node_t*)global_cppquotes_post, (ASTP_node_t*)$<y_cpp_quote>2);
}*/
;
interfaces:
interfaces interface_plus
|
interface_plus
;
/*Centeris wfu*/
cpp_quotes:
cpp_quote cpp_quotes
{
$<y_cpp_quote>$ = (AST_cpp_quote_n_t *) AST_concat_element(
(ASTP_node_t *) $<y_cpp_quote>1,
(ASTP_node_t *) $<y_cpp_quote>2);
}
| /*Nothing*/
{ $<y_cpp_quote>$ = (AST_cpp_quote_n_t *)NULL;
}
;
interface_plus:
cpp_quotes interface
{
global_cppquotes = (AST_cpp_quote_n_t*)AST_concat_element(
(ASTP_node_t*)global_cppquotes, (ASTP_node_t*)$<y_cpp_quote>1);
}
;
interface:
interface_init interface_start interface_ancestor interface_tail
{
AST_finish_interface_node(nidl_location(nidl), the_interface);
}
;
interface_start:
interface_attributes INTERFACE_KW IDENTIFIER
{
AST_type_n_t * interface_type =
AST_type_node(nidl_location(nidl), AST_interface_k);
interface_type->type_structure.interface = the_interface;
interface_type->name = $<y_id>3;
the_interface->name = $<y_id>3;
ASTP_add_name_binding (nidl_location(nidl), the_interface->name, interface_type);
}
;
interface_ancestor:
/* Nothing */
{
the_interface->inherited_interface_name = NAMETABLE_NIL_ID;
}
| COLON IDENTIFIER
{
the_interface->inherited_interface_name = $<y_id>2;
}
;
interface_init:
/* Always create the interface node and auto-import the system idl */
{
STRTAB_str_t nidl_idl_str;
nidl_idl_str = STRTAB_add_string (AUTO_IMPORT_FILE);
AST_interface_n_t* old = the_interface;
the_interface = AST_interface_node(nidl_location(nidl));
the_interface->prev = old;
the_interface->exports = NULL;
the_interface->imports =
AST_import_node(nidl_location(nidl), nidl_idl_str);
the_interface->imports->interface = FE_parse_import (nidl_idl_str);
if (the_interface->imports->interface != NULL)
{
AST_CLR_OUT_OF_LINE(the_interface->imports->interface);
AST_SET_IN_LINE(the_interface->imports->interface);
}
}
;
interface_tail:
LBRACE interface_body RBRACE
{ $<y_interface>$ = $<y_interface>2; }
| error
{
$<y_interface>$ = NULL;
log_error(nidl_yylineno(nidl),NIDL_MISSONINTER, NULL);
}
| error RBRACE
{
$<y_interface>$ = NULL;
}
;
interface_body:
optional_imports exports extraneous_semi
{
/* May already be an import of nbase, so concat */
the_interface->imports = (AST_import_n_t *) AST_concat_element(
(ASTP_node_t *) the_interface->imports,
(ASTP_node_t *) $<y_import>1);
the_interface->exports = (AST_export_n_t*)AST_concat_element(
(ASTP_node_t*)the_interface->exports,
(ASTP_node_t*)$<y_export>2);
}
;
optional_imports:
imports
| /* Nothing */
{
$<y_import>$ = (AST_import_n_t *)NULL;
}
;
optional_imports_cppquotes:
imports cpp_quotes
{
#if 0
global_imports = (AST_import_n_t*)AST_concat_element(
(ASTP_node_t*)global_imports, (ASTP_node_t*)$<y_import>1);
#endif
global_cppquotes_post = (AST_cpp_quote_n_t*)AST_concat_element(
(ASTP_node_t*)global_cppquotes_post, (ASTP_node_t*)$<y_cpp_quote>2);
}
;
imports:
import
| imports import
{
$<y_import>$ = (AST_import_n_t *) AST_concat_element(
(ASTP_node_t *) $<y_import>1,
(ASTP_node_t *) $<y_import>2);
}
;
import:
IMPORT_KW error
{
$<y_import>$ = (AST_import_n_t *)NULL;
}
| IMPORT_KW error SEMI
{
$<y_import>$ = (AST_import_n_t *)NULL;
}
| IMPORT_KW import_files SEMI
{
$<y_import>$ = $<y_import>2;
}
;
import_files:
import_file
| import_files COMMA import_file
{
$<y_import>$ = (AST_import_n_t *) AST_concat_element(
(ASTP_node_t *) $<y_import>1,
(ASTP_node_t *) $<y_import>3);
}
;
import_file:
STRING
{
AST_interface_n_t *int_p;
int_p = FE_parse_import ($<y_string>1);
if (int_p != (AST_interface_n_t *)NULL)
{
$<y_import>$ = AST_import_node(nidl_location(nidl), $<y_string>1);
$<y_import>$->interface = int_p;
}
else
$<y_import>$ = (AST_import_n_t *)NULL;
}
;
exports:
export
| exports extraneous_semi export
{
$<y_export>$ = (AST_export_n_t *) AST_concat_element(
(ASTP_node_t *) $<y_export>1,
(ASTP_node_t *) $<y_export>3) ;
}
;
export:
type_dcl SEMI
{
$<y_export>$ = AST_types_to_exports (nidl_location(nidl),
$<y_type_ptr>1);
}
| const_dcl SEMI
{
$<y_export>$ = AST_export_node (
nidl_location(nidl),
(ASTP_node_t *) $<y_constant>1, AST_constant_k);
}
| operation_dcl SEMI
{
if (ASTP_parsing_main_idl)
$<y_export>$ = AST_export_node (
nidl_location(nidl),
(ASTP_node_t *) $<y_operation>1, AST_operation_k);
}
| cpp_quote
{
$<y_export>$ = AST_export_node (
nidl_location(nidl),
(ASTP_node_t *) $<y_cpp_quote>1, AST_cpp_quote_k);
}
| error SEMI
{
$<y_export>$ = (AST_export_n_t *)NULL;
}
;
cpp_quote:
CPP_QUOTE_KW LPAREN STRING RPAREN
{
$<y_cpp_quote>$ =
AST_cpp_quote_node(nidl_location(nidl), $<y_string>3);
}
;
const_dcl:
CONST_KW type_spec declarator EQUAL const_exp
{
$<y_constant>$ = AST_finish_constant_node (nidl_location(nidl),
$<y_constant>5, $<y_declarator>3, $<y_type>2);
}
;
const_exp: expression
{
$<y_constant>$ = AST_constant_from_exp(nidl_location(nidl),
$<y_exp>1);
if ($<y_constant>$ == NULL) {
log_error(nidl_yylineno(nidl), NIDL_EXPNOTCONST, NULL);
}
}
;
type_dcl:
TYPEDEF_KW type_declarator
{
$<y_type_ptr>$ = $<y_type_ptr>2;
}
;
type_declarator:
attributes type_spec declarators extraneous_comma
{
$<y_type_ptr>$ = AST_declarators_to_types(nidl_location(nidl),
the_interface, $<y_type>2, $<y_declarator>3, &$<y_attributes>1) ;
ASTP_free_simple_list((ASTP_node_t *)$<y_attributes>1.bounds);
}
;
type_spec:
simple_type_spec
| constructed_type_spec
;
simple_type_spec:
floating_point_type_spec
| integer_type_spec
| char_type_spec
| boolean_type_spec
| byte_type_spec
| void_type_spec
| named_type_spec
| handle_type_spec
;
constructed_type_spec:
struct_type_spec
| union_type_spec
| enum_type_spec
| pipe_type_spec
;
named_type_spec:
IDENTIFIER
{
$<y_type>$ = AST_lookup_named_type(nidl_location(nidl), $<y_id>1);
}
;
floating_point_type_spec:
FLOAT_KW
{
$<y_type>$ = AST_lookup_type_node(AST_short_float_k);
}
| DOUBLE_KW
{
$<y_type>$ = AST_lookup_type_node(AST_long_float_k);
}
;
extraneous_comma:
/* Nothing */
| COMMA
{ log_warning(nidl_yylineno(nidl), NIDL_EXTRAPUNCT, ",", NULL);}
;
extraneous_semi:
/* Nothing */
| SEMI
{ log_warning(nidl_yylineno(nidl), NIDL_EXTRAPUNCT, ";", NULL);}
;
optional_unsigned_kw:
UNSIGNED_KW { $<y_int_info>$.int_signed = false; }
| /* Nothing */ { $<y_int_info>$.int_signed = true; }
;
integer_size_spec:
SMALL_KW
{
$<y_int_info>$.int_size = AST_small_integer_k;
$<y_int_info>$.int_signed = true;
}
| SHORT_KW
{
$<y_int_info>$.int_size = AST_short_integer_k;
$<y_int_info>$.int_signed = true;
}
| LONG_KW
{
$<y_int_info>$.int_size = AST_long_integer_k;
$<y_int_info>$.int_signed = true;
}
| HYPER_KW
{
$<y_int_info>$.int_size = AST_hyper_integer_k;
$<y_int_info>$.int_signed = true;
}
;
integer_modifiers:
integer_size_spec
{ $<y_int_info>$ = $<y_int_info>1; }
| UNSIGNED_KW integer_size_spec
{
$<y_int_info>$.int_size = $<y_int_info>2.int_size;
$<y_int_info>$.int_signed = false;
}
| integer_size_spec UNSIGNED_KW
{
$<y_int_info>$.int_size = $<y_int_info>1.int_size;
$<y_int_info>$.int_signed = false;
}
;
integer_type_spec:
integer_modifiers
{ $<y_type>$ = AST_lookup_integer_type_node($<y_int_info>1.int_size,$<y_int_info>1.int_signed); }
| integer_modifiers INT_KW
{ $<y_type>$ = AST_lookup_integer_type_node($<y_int_info>1.int_size,$<y_int_info>1.int_signed); }
| optional_unsigned_kw INT_KW
{
log_warning(nidl_yylineno(nidl),NIDL_INTSIZEREQ, NULL);
$<y_type>$ = AST_lookup_integer_type_node(AST_long_integer_k,$<y_int_info>1.int_signed);
}
;
char_type_spec:
optional_unsigned_kw CHAR_KW
{ $<y_type>$ = AST_lookup_type_node(AST_character_k); }
;
boolean_type_spec:
BOOLEAN_KW
{ $<y_type>$ = AST_lookup_type_node(AST_boolean_k); }
;
byte_type_spec:
BYTE_KW
{ $<y_type>$ = AST_lookup_type_node(AST_byte_k); }
;
void_type_spec:
VOID_KW
{ $<y_type>$ = AST_lookup_type_node(AST_void_k); }
;
handle_type_spec:
HANDLE_T_KW
{ $<y_type>$ = AST_lookup_type_node(AST_handle_k); }
;
push_name_space:
LBRACE
{
NAMETABLE_push_level ();
}
;
pop_name_space:
RBRACE
{
ASTP_patch_field_reference (nidl_location(nidl));
NAMETABLE_pop_level ();
}
;
union_type_spec:
UNION_KW ne_union_body
{
$<y_type>$ = AST_disc_union_node(
nidl_location(nidl),
NAMETABLE_NIL_ID, /* tag name */
NAMETABLE_NIL_ID, /* union name */
NAMETABLE_NIL_ID, /* discriminant name */
NULL, /* discriminant type */
$<y_arm>2 ); /* the arm list */
}
|
UNION_KW SWITCH_KW LPAREN simple_type_spec IDENTIFIER RPAREN union_body
{
$<y_type>$ = AST_disc_union_node(
nidl_location(nidl),
NAMETABLE_NIL_ID, /* tag name */
ASTP_tagged_union_id, /* union name */
$<y_id>5, /* discriminant name */
$<y_type>4, /* discriminant type */
$<y_arm>7 ); /* the arm list */
}
| UNION_KW IDENTIFIER ne_union_body
{
$<y_type>$ = AST_disc_union_node(
nidl_location(nidl),
$<y_id>2, /* tag name */
NAMETABLE_NIL_ID, /* union name */
NAMETABLE_NIL_ID, /* discriminant name */
NULL, /* discriminant type */
$<y_arm>3 ); /* the arm list */
}
| UNION_KW SWITCH_KW LPAREN simple_type_spec IDENTIFIER RPAREN IDENTIFIER union_body
{
$<y_type>$ = AST_disc_union_node(
nidl_location(nidl),
NAMETABLE_NIL_ID, /* tag name */
$<y_id>7, /* union name */
$<y_id>5, /* discriminant name */
$<y_type>4, /* discriminant type */
$<y_arm>8 ); /* the arm list */
}
| UNION_KW IDENTIFIER SWITCH_KW LPAREN simple_type_spec IDENTIFIER RPAREN union_body
{
$<y_type>$ = AST_disc_union_node(
nidl_location(nidl),
$<y_id>2, /* tag name */
ASTP_tagged_union_id, /* union name */
$<y_id>6, /* discriminant name */
$<y_type>5, /* discriminant type */
$<y_arm>8 ); /* the arm list */
}
| UNION_KW IDENTIFIER SWITCH_KW LPAREN simple_type_spec IDENTIFIER RPAREN IDENTIFIER union_body
{
$<y_type>$ = AST_disc_union_node(
nidl_location(nidl),
$<y_id>2, /* tag name */
$<y_id>8, /* union name */
$<y_id>6, /* discriminant name */
$<y_type>5, /* discriminant type */
$<y_arm>9 ); /* the arm list */
}
| UNION_KW IDENTIFIER
{
$<y_type>$ = AST_type_from_tag (nidl_location(nidl),
AST_disc_union_k, $<y_id>2);
}
;
ne_union_body:
push_name_space ne_union_cases pop_name_space
{
$<y_arm>$ = $<y_arm>2;
}
;
union_body:
push_name_space union_cases pop_name_space
{
$<y_arm>$ = $<y_arm>2;
}
;
ne_union_cases:
ne_union_case
| ne_union_cases extraneous_semi ne_union_case
{
$<y_arm>$ = (AST_arm_n_t *) AST_concat_element(
(ASTP_node_t *) $<y_arm>1,
(ASTP_node_t *) $<y_arm>3);
}
;
union_cases:
union_case
| union_cases extraneous_semi union_case
{
$<y_arm>$ = (AST_arm_n_t *) AST_concat_element(
(ASTP_node_t *) $<y_arm>1,
(ASTP_node_t *) $<y_arm>3);
}
;
ne_union_case:
ne_union_member
{
$<y_arm>$ = $<y_arm>1;
}
;
union_case:
union_case_list union_member
{
$<y_arm>$ = AST_label_arm($<y_arm>2, $<y_label>1) ;
}
;
ne_union_case_list:
ne_union_case_label
| ne_union_case_list COMMA ne_union_case_label
{
$<y_label>$ = (AST_case_label_n_t *) AST_concat_element(
(ASTP_node_t *) $<y_label>1,
(ASTP_node_t *) $<y_label>3);
}
;
union_case_list:
union_case_label
| union_case_list union_case_label
{
$<y_label>$ = (AST_case_label_n_t *) AST_concat_element(
(ASTP_node_t *) $<y_label>1,
(ASTP_node_t *) $<y_label>2);
}
;
ne_union_case_label:
const_exp
{
$<y_label>$ = AST_case_label_node(
nidl_location(nidl), $<y_constant>1);
}
;
union_case_label:
CASE_KW const_exp COLON
{
$<y_label>$ = AST_case_label_node(
nidl_location(nidl), $<y_constant>2);
}
| DEFAULT_KW COLON
{
$<y_label>$ = AST_default_case_label_node(
nidl_location(nidl));
}
;
ne_union_member:
attribute_opener rest_of_attribute_list SEMI
{
$<y_arm>$ = AST_declarator_to_arm(nidl_location(nidl),
NULL, NULL, &$<y_attributes>2);
ASTP_free_simple_list((ASTP_node_t *)$<y_attributes>2.bounds);
}
| attribute_opener rest_of_attribute_list type_spec declarator SEMI
{
$<y_arm>$ = AST_declarator_to_arm(nidl_location(nidl),
$<y_type>3, $<y_declarator>4, &$<y_attributes>2);
ASTP_free_simple_list((ASTP_node_t *)$<y_attributes>2.bounds);
}
;
union_member:
/* nothing */ SEMI
{
$<y_arm>$ = AST_arm_node(nidl_location(nidl),
NAMETABLE_NIL_ID,NULL,NULL);
}
| attributes type_spec declarator SEMI
{
if (ASTP_TEST_ATTR(&$<y_attributes>1, ASTP_CASE))
{
ASTP_attr_flag_t attr1 = ASTP_CASE;
log_error(nidl_yylineno(nidl), NIDL_EUMEMATTR,
KEYWORDS_lookup_text(AST_attribute_to_token(&attr1)),
NULL);
}
if (ASTP_TEST_ATTR(&$<y_attributes>1, ASTP_DEFAULT))
{
ASTP_attr_flag_t attr1 = ASTP_DEFAULT;
log_error(nidl_yylineno(nidl), NIDL_EUMEMATTR,
KEYWORDS_lookup_text(AST_attribute_to_token(&attr1)),
NULL);
}
$<y_arm>$ = AST_declarator_to_arm(nidl_location(nidl),
$<y_type>2, $<y_declarator>3, &$<y_attributes>1);
ASTP_free_simple_list((ASTP_node_t *)$<y_attributes>1.bounds);
}
;
struct_type_spec:
STRUCT_KW push_name_space member_list pop_name_space
{
$<y_type>$ = AST_structure_node(nidl_location(nidl),
$<y_field>3, NAMETABLE_NIL_ID) ;
}
| STRUCT_KW IDENTIFIER push_name_space member_list pop_name_space
{
$<y_type>$ = AST_structure_node(nidl_location(nidl),
$<y_field>4, $<y_id>2) ;
}
| STRUCT_KW IDENTIFIER
{
$<y_type>$ = AST_type_from_tag (nidl_location(nidl),
AST_structure_k, $<y_id>2);
}
;
member_list:
member
| member_list extraneous_semi member
{
$<y_field>$ = (AST_field_n_t *)AST_concat_element(
(ASTP_node_t *) $<y_field>1,
(ASTP_node_t *) $<y_field>3) ;
}
;
member:
attributes type_spec old_attribute_syntax declarators SEMI
{
$<y_field>$ = AST_declarators_to_fields(nidl_location(nidl),
$<y_declarator>4,
$<y_type>2,
&$<y_attributes>1);
ASTP_free_simple_list((ASTP_node_t *)$<y_attributes>1.bounds);
}
;
enum_type_spec:
ENUM_KW optional_tag enum_body
{
$<y_type>$ = AST_enumerator_node(nidl_location(nidl),
$<y_constant>3, AST_short_integer_k);
}
;
optional_tag:
IDENTIFIER
{
}
| /* Nothing */
;
enum_body:
LBRACE enum_ids extraneous_comma RBRACE
{
$<y_constant>$ = $<y_constant>2 ;
}
;
enum_ids:
enum_id
| enum_ids COMMA enum_id
{
$<y_constant>$ = (AST_constant_n_t *) AST_concat_element(
(ASTP_node_t *) $<y_constant>1,
(ASTP_node_t *) $<y_constant>3) ;
}
;
enum_id:
IDENTIFIER optional_value
{
$<y_constant>$ = AST_enum_constant(nidl_location(nidl),
$<y_id>1, $<y_exp>2) ;
}
;
pipe_type_spec:
PIPE_KW type_spec
{
$<y_type>$ = AST_pipe_node (nidl_location(nidl), $<y_type>2);
}
;
optional_value:
/* Nothing */
{
$<y_exp>$ = AST_exp_integer_constant(nidl_location(nidl),
0, true);
}
| EQUAL expression
{
ASTP_validate_integer(nidl_location(nidl), $<y_exp>2);
$<y_exp>$ = $<y_exp>2;
}
;
declarators:
declarator
{
$<y_declarator>$ = $<y_declarator>1;
}
| declarators COMMA declarator
{
$<y_declarator>$ = (ASTP_declarator_n_t *) AST_concat_element(
(ASTP_node_t *) $<y_declarator>1,
(ASTP_node_t *) $<y_declarator>3) ;
}
;
declarator:
declarator1
{ $<y_declarator>$ = $<y_declarator>1; }
;
declarator1:
direct_declarator
{ $<y_declarator>$ = $<y_declarator>1; }
| pointer direct_declarator
{
$<y_declarator>$ = $<y_declarator>2;
AST_declarator_operation($<y_declarator>$, AST_pointer_k,
(ASTP_node_t *)NULL, $<y_ptrlevels>1 );
};
pointer :
STAR
{ $<y_ptrlevels>$ = 1;}
| STAR pointer
{ $<y_ptrlevels>$ = $<y_ptrlevels>2 + 1; };
direct_declarator:
IDENTIFIER
{ $<y_declarator>$ = AST_declarator_node ( $<y_id>1 ); }
| direct_declarator array_bounds
{
$<y_declarator>$ = $<y_declarator>$;
AST_declarator_operation($<y_declarator>$, AST_array_k,
(ASTP_node_t *) $<y_index>2, 0 );
}
| LPAREN declarator RPAREN
{
$<y_declarator>$ = $<y_declarator>2;
}
| direct_declarator parameter_dcls
{
$<y_declarator>$ = $<y_declarator>$;
AST_declarator_operation($<y_declarator>$, AST_function_k,
(ASTP_node_t *) $<y_parameter>2, 0 );
}
;
/*
* The following productions use an AST routine with the signature:
*
* ASTP_array_index_node( AST_constant_n_t * lower_bound,
* ASTP_bound_t lower_bound_type,
* AST_constant_n_t * upper_bound,
* ASTP_bound_t upper_bound_type);
*
* The type ASTP_bound_t is defined as:
*
* typedef enum {ASTP_constant_bound,
* ASTP_default_bound,
* ASTP_open_bound} ASTP_bound_t;
*
* The bound value passed is only used if the associated bound type is
* ASTP_constant_bound.
*/
array_bounds:
LBRACKET RBRACKET
{
$<y_index>$ = ASTP_array_index_node (nidl_location(nidl),
NULL, ASTP_default_bound,
NULL, ASTP_open_bound);
}
| LBRACKET STAR RBRACKET
{
$<y_index>$ = ASTP_array_index_node (nidl_location(nidl),
NULL, ASTP_default_bound,
NULL, ASTP_open_bound);
}
| LBRACKET const_exp RBRACKET
{
$<y_index>$ = ASTP_array_index_node (nidl_location(nidl),
NULL, ASTP_default_bound,
$<y_constant>2, ASTP_constant_bound);
}
| LBRACKET STAR DOTDOT STAR RBRACKET
{
$<y_index>$ = ASTP_array_index_node (nidl_location(nidl),
NULL, ASTP_open_bound,
NULL, ASTP_open_bound);
}
| LBRACKET STAR DOTDOT const_exp RBRACKET
{
$<y_index>$ = ASTP_array_index_node (nidl_location(nidl),
NULL, ASTP_open_bound,
$<y_constant>4,
ASTP_constant_bound);
}
| LBRACKET const_exp DOTDOT STAR RBRACKET
{
$<y_index>$ = ASTP_array_index_node (nidl_location(nidl),
$<y_constant>2,
ASTP_constant_bound,
NULL, ASTP_open_bound);
}
| LBRACKET const_exp DOTDOT const_exp RBRACKET
{
$<y_index>$ = ASTP_array_index_node (nidl_location(nidl),
$<y_constant>2, ASTP_constant_bound,
$<y_constant>4, ASTP_constant_bound);
}
;
operation_dcl:
attributes type_spec declarators extraneous_comma
{
if (ASTP_parsing_main_idl)
$<y_operation>$ = AST_operation_node (
nidl_location(nidl),
$<y_type>2, /*The type node*/
$<y_declarator>3, /* Declarator list */
&$<y_attributes>1); /* attributes */
ASTP_free_simple_list((ASTP_node_t *)$<y_attributes>1.bounds);
}
| error declarators
{
log_error(nidl_yylineno(nidl),NIDL_MISSONOP, NULL);
$<y_operation>$ = NULL;
}
;
parameter_dcls:
param_names param_list extraneous_comma end_param_names
{
$<y_parameter>$ = $<y_parameter>2;
}
;
param_names:
LPAREN
{
NAMETABLE_push_level ();
}
;
end_param_names:
RPAREN
{
ASTP_patch_field_reference (nidl_location(nidl));
NAMETABLE_pop_level ();
}
;
param_list:
param_dcl
| param_list COMMA param_dcl
{
if (ASTP_parsing_main_idl)
$<y_parameter>$ = (AST_parameter_n_t *) AST_concat_element(
(ASTP_node_t *) $<y_parameter>1,
(ASTP_node_t *) $<y_parameter>3);
}
| /* nothing */
{
$<y_parameter>$ = (AST_parameter_n_t *)NULL;
}
;
param_dcl:
attributes type_spec old_attribute_syntax declarator_or_null
{
/*
* We have to use special code here to allow (void) as a parameter
* specification. If there are no declarators, then we need to
* make sure that the type is void and that there are no attributes .
*/
if ($<y_declarator>4 == NULL)
{
/*
* If the type is not void or some attribute is specified,
* there is a syntax error. Force a yacc error, so that
* we can safely recover from the lack of a declarator.
*/
if (($<y_type>2->kind != AST_void_k) ||
($<y_attributes>1.bounds != NULL) ||
($<y_attributes>1.attr_flags != 0))
{
yywhere(nidl_location(nidl)); /* Issue a syntax error for this line */
YYERROR; /* Allow natural error recovery */
}
$<y_parameter>$ = (AST_parameter_n_t *)NULL;
}
else
{
if (ASTP_parsing_main_idl)
$<y_parameter>$ = AST_declarator_to_param(
nidl_location(nidl),
&$<y_attributes>1,
$<y_type>2,
$<y_declarator>4);
}
ASTP_free_simple_list((ASTP_node_t *)$<y_attributes>1.bounds);
}
| error old_attribute_syntax declarator_or_null
{
log_error(nidl_yylineno(nidl), NIDL_MISSONPARAM, NULL);
$<y_parameter>$ = (AST_parameter_n_t *)NULL;
}
;
declarator_or_null:
declarator
{ $<y_declarator>$ = $<y_declarator>1; }
| /* nothing */
{ $<y_declarator>$ = NULL; }
;
/*
* Attribute definitions
*
* Attributes may appear on types, fields, parameters, operations and
* interfaces. Thes productions must be used around attributes in order
* for LEX to recognize attribute names as keywords instead of identifiers.
* The bounds productions are used in attribute options (such
* as size_is) because variable names the may look like attribute names
* should be allowed.
*/
attribute_opener:
LBRACKET
{
search_attributes_table = true;
}
;
attribute_closer:
RBRACKET
{
search_attributes_table = false;
}
;
bounds_opener:
LPAREN
{
search_attributes_table = false;
}
;
bounds_closer:
RPAREN
{
search_attributes_table = true;
}
;
/*
* Production to accept attributes in the old location, and issue a clear error that
* the translator should be used.
*/
old_attribute_syntax:
attributes
{
/* Give an error on notranslated sources */
if (($<y_attributes>1.bounds != NULL) ||
($<y_attributes>1.attr_flags != 0))
{
log_error(nidl_yylineno(nidl),NIDL_ATTRTRANS, NULL);
ASTP_free_simple_list((ASTP_node_t *)$<y_attributes>1.bounds);
}
}
;
/*
* Interface Attributes
*
* Interface attributes are special--there is no cross between interface
* attributes and other attributes (for instance on fields or types.
*/
interface_attributes:
attribute_opener interface_attr_list extraneous_comma attribute_closer
| attribute_opener error attribute_closer
{
log_error(nidl_yylineno(nidl),NIDL_ERRINATTR, NULL);
}
| /* Nothing */
;
interface_attr_list:
interface_attr
| interface_attr_list COMMA interface_attr
| /* nothing */
;
interface_attr:
UUID_KW error
{
log_error(nidl_yylineno(nidl),NIDL_SYNTAXUUID, NULL);
}
| UUID_KW UUID_REP
{
{
if (ASTP_IF_AF_SET(the_interface,ASTP_IF_UUID))
log_error(nidl_yylineno(nidl), NIDL_ATTRUSEMULT, NULL);
ASTP_SET_IF_AF(the_interface,ASTP_IF_UUID);
the_interface->uuid = $<y_uuid>2;
}
}
| ENDPOINT_KW LPAREN port_list extraneous_comma RPAREN
{
if (ASTP_IF_AF_SET(the_interface,ASTP_IF_PORT))
log_error(nidl_yylineno(nidl), NIDL_ATTRUSEMULT, NULL);
ASTP_SET_IF_AF(the_interface,ASTP_IF_PORT);
}
| EXCEPTIONS_KW LPAREN excep_list extraneous_comma RPAREN
{
if (ASTP_IF_AF_SET(the_interface, ASTP_IF_EXCEPTIONS))
log_error(nidl_yylineno(nidl), NIDL_ATTRUSEMULT, NULL);
ASTP_SET_IF_AF(the_interface, ASTP_IF_EXCEPTIONS);
}
| VERSION_KW LPAREN version_number RPAREN
{
{
if (ASTP_IF_AF_SET(the_interface,ASTP_IF_VERSION))
log_error(nidl_yylineno(nidl), NIDL_ATTRUSEMULT, NULL);
ASTP_SET_IF_AF(the_interface,ASTP_IF_VERSION);
}
}
| LOCAL_KW
{
{
if (AST_LOCAL_SET(the_interface))
log_warning(nidl_yylineno(nidl), NIDL_MULATTRDEF, NULL);
AST_SET_LOCAL(the_interface);
}
}
| POINTER_DEFAULT_KW LPAREN pointer_class RPAREN
{
if (the_interface->pointer_default != 0)
log_error(nidl_yylineno(nidl), NIDL_ATTRUSEMULT, NULL);
the_interface->pointer_default = $<y_ptrclass>3;
}
/* extensions to osf */
| OBJECT_KW
{
if (AST_OBJECT_SET(the_interface))
log_warning(nidl_yylineno(nidl), NIDL_MULATTRDEF, NULL);
AST_SET_OBJECT(the_interface);
}
| acf_interface_attr
{
/* complain about compat here */
}
;
acf_interface_attr:
IMPLICIT_HANDLE_KW LPAREN HANDLE_T_KW IDENTIFIER RPAREN
{
if (the_interface->implicit_handle_name != NAMETABLE_NIL_ID)
log_error(nidl_yylineno(nidl), NIDL_ATTRUSEMULT, NULL);
ASTP_set_implicit_handle(the_interface, NAMETABLE_NIL_ID, $<y_id>4);
}
|
IMPLICIT_HANDLE_KW LPAREN IDENTIFIER IDENTIFIER RPAREN
{
if (the_interface->implicit_handle_name != NAMETABLE_NIL_ID)
log_error(nidl_yylineno(nidl), NIDL_ATTRUSEMULT, NULL);
ASTP_set_implicit_handle(the_interface, $<y_id>3, $<y_id>4);
}
;
pointer_class:
REF_KW { $<y_ptrclass>$ = ASTP_REF; }
| PTR_KW { $<y_ptrclass>$ = ASTP_PTR; }
| UNIQUE_KW { $<y_ptrclass>$ = ASTP_UNIQUE; }
;
version_number:
INTEGER_NUMERIC
{
the_interface->version = $<y_int_info>1.int_val;
if (the_interface->version > /*(unsigned int)*/ASTP_C_USHORT_MAX)
log_error(nidl_yylineno(nidl), NIDL_MAJORTOOLARGE,
ASTP_C_USHORT_MAX, NULL);
}
| FLOAT_NUMERIC
{
char const *float_text;
unsigned int major_version,minor_version;
STRTAB_str_to_string($<y_string>1, &float_text);
sscanf(float_text,"%d.%d",&major_version,&minor_version);
if (major_version > (unsigned int)ASTP_C_USHORT_MAX)
log_error(nidl_yylineno(nidl), NIDL_MAJORTOOLARGE,
ASTP_C_USHORT_MAX, NULL);
if (minor_version > (unsigned int)ASTP_C_USHORT_MAX)
log_error(nidl_yylineno(nidl), NIDL_MINORTOOLARGE,
ASTP_C_USHORT_MAX, NULL);
the_interface->version = (minor_version * 65536) + major_version;
}
;
port_list:
port_spec
| port_list COMMA port_spec
;
excep_list:
excep_spec
{
the_interface->exceptions = $<y_exception>1;
}
| excep_list COMMA excep_spec
{
$<y_exception>$ = (AST_exception_n_t *) AST_concat_element(
(ASTP_node_t *) the_interface->exceptions,
(ASTP_node_t *) $<y_exception>3 );
}
;
port_spec:
STRING
{
ASTP_parse_port(the_interface,$<y_string>1);
}
;
excep_spec:
IDENTIFIER
{
if (ASTP_parsing_main_idl)
{
$<y_exception>$ =
AST_exception_node(nidl_location(nidl), $<y_id>1);
}
else
{
$<y_exception>$ = NULL;
}
}
;
/*
* Attributes that can appear on fields or parameters. These are the array
* bounds attributes, i.e., last_is and friends. They are handled differently
* from any other attributes.
*/
fp_attribute:
array_bound_type bounds_opener array_bound_id_list bounds_closer
{
$<y_attributes>$.bounds = $<y_attributes>3.bounds;
$<y_attributes>$.attr_flags = 0;
}
| neu_switch_type bounds_opener neu_switch_id bounds_closer
{
$<y_attributes>$.bounds = $<y_attributes>3.bounds;
$<y_attributes>$.attr_flags = 0;
}
;
array_bound_type:
FIRST_IS_KW
{
ASTP_bound_type = first_is_k;
}
| LAST_IS_KW
{
ASTP_bound_type = last_is_k;
}
| LENGTH_IS_KW
{
ASTP_bound_type = length_is_k;
}
| MAX_IS_KW
{
ASTP_bound_type = max_is_k;
}
| MIN_IS_KW
{
ASTP_bound_type = min_is_k;
}
| SIZE_IS_KW
{
ASTP_bound_type = size_is_k;
}
;
array_bound_id_list:
array_bound_id
| array_bound_id_list COMMA array_bound_id
{
$<y_attributes>$.bounds = (ASTP_type_attr_n_t *) AST_concat_element (
(ASTP_node_t*) $<y_attributes>1.bounds,
(ASTP_node_t*) $<y_attributes>3.bounds);
}
;
/* expression conflicts with identifier here */
array_bound_id:
expression
{
$<y_attributes>$.bounds =
AST_array_bound_from_expr(nidl_location(nidl),
$<y_exp>1, ASTP_bound_type);
}
| /* nothing */
{
$<y_attributes>$.bounds = AST_array_bound_info (nidl_location(nidl),
NAMETABLE_NIL_ID, ASTP_bound_type, FALSE);
}
;
neu_switch_type:
SWITCH_IS_KW
{
ASTP_bound_type = switch_is_k;
}
;
neu_switch_id:
IDENTIFIER
{
$<y_attributes>$.bounds = AST_array_bound_info(nidl_location(nidl),
$<y_id>1, ASTP_bound_type, FALSE);
}
| STAR IDENTIFIER
{
$<y_attributes>$.bounds = AST_array_bound_info(nidl_location(nidl),
$<y_id>2, ASTP_bound_type, TRUE);
}
;
/*
* Generalized Attribute processing
*/
attributes:
attribute_opener rest_of_attribute_list
{ $<y_attributes>$ = $<y_attributes>2; }
|
/* nothing */
{
$<y_attributes>$.bounds = NULL;
$<y_attributes>$.attr_flags = 0;
}
;
rest_of_attribute_list:
attribute_list extraneous_comma attribute_closer
| error attribute_closer
{
/*
* Can't tell if we had any valid attributes in the list, so return
* none.
*/
$<y_attributes>$.bounds = NULL;
$<y_attributes>$.attr_flags = 0;
log_error(nidl_yylineno(nidl), NIDL_ERRINATTR, NULL);
}
| error SEMI
{
/*
* No closer to the attribute, so give a different message.
*/
$<y_attributes>$.bounds = NULL;
$<y_attributes>$.attr_flags = 0;
log_error(nidl_yylineno(nidl), NIDL_MISSONATTR, NULL);
search_attributes_table = false;
}
;
attribute_list:
attribute
{ $<y_attributes>$ = $<y_attributes>1; }
|
attribute_list COMMA attribute
{
/*
* If the same bit has been specified more than once, then issue
* a message.
*/
if (($<y_attributes>1.attr_flags & $<y_attributes>3.attr_flags) != 0)
log_warning(nidl_yylineno(nidl), NIDL_MULATTRDEF, NULL);
$<y_attributes>$.attr_flags = $<y_attributes>1.attr_flags |
$<y_attributes>3.attr_flags;
$<y_attributes>$.bounds = (ASTP_type_attr_n_t *) AST_concat_element (
(ASTP_node_t*) $<y_attributes>1.bounds,
(ASTP_node_t*) $<y_attributes>3.bounds);
}
;
attribute:
/* bound attributes */
fp_attribute { $<y_attributes>$ = $<y_attributes>1; }
/* Operation Attributes */
| BROADCAST_KW { $<y_attributes>$.attr_flags = ASTP_BROADCAST;
$<y_attributes>$.bounds = NULL; }
| MAYBE_KW { $<y_attributes>$.attr_flags = ASTP_MAYBE;
$<y_attributes>$.bounds = NULL; }
| IDEMPOTENT_KW { $<y_attributes>$.attr_flags = ASTP_IDEMPOTENT;
$<y_attributes>$.bounds = NULL; }
| REFLECT_DELETIONS_KW { $<y_attributes>$.attr_flags = ASTP_REFLECT_DELETIONS;
$<y_attributes>$.bounds = NULL; }
| LOCAL_KW { $<y_attributes>$.attr_flags = ASTP_LOCAL;
$<y_attributes>$.bounds = NULL; }
| CALL_AS_KW LPAREN IDENTIFIER RPAREN { }
/* Parameter-only Attributes */
| PTR_KW { $<y_attributes>$.attr_flags = ASTP_PTR;
$<y_attributes>$.bounds = NULL; }
| IN_KW { $<y_attributes>$.attr_flags = ASTP_IN;
$<y_attributes>$.bounds = NULL; }
| IN_KW LPAREN SHAPE_KW RPAREN
{ $<y_attributes>$.attr_flags =
ASTP_IN | ASTP_IN_SHAPE;
$<y_attributes>$.bounds = NULL; }
| OUT_KW { $<y_attributes>$.attr_flags = ASTP_OUT;
$<y_attributes>$.bounds = NULL; }
| OUT_KW LPAREN SHAPE_KW RPAREN
{ $<y_attributes>$.attr_flags =
ASTP_OUT | ASTP_OUT_SHAPE;
$<y_attributes>$.bounds = NULL; }
| IID_IS_KW LPAREN IDENTIFIER RPAREN
{ $<y_attributes>$.iid_is_name = $<y_id>3;
$<y_attributes>$.bounds = NULL;
$<y_attributes>$.attr_flags = 0;
}
| IID_IS_KW LPAREN STAR IDENTIFIER RPAREN /* MIDL extension */
{ $<y_attributes>$.iid_is_name = $<y_id>4;
$<y_attributes>$.bounds = NULL;
$<y_attributes>$.attr_flags = 0;
}
/* Type, Field, Parameter Attributes */
| V1_ARRAY_KW { $<y_attributes>$.attr_flags = ASTP_SMALL;
$<y_attributes>$.bounds = NULL; }
| STRING_KW { $<y_attributes>$.attr_flags = ASTP_STRING;
$<y_attributes>$.bounds = NULL; }
| V1_STRING_KW { $<y_attributes>$.attr_flags = ASTP_STRING0;
$<y_attributes>$.bounds = NULL; }
| UNIQUE_KW { $<y_attributes>$.attr_flags = ASTP_UNIQUE;
$<y_attributes>$.bounds = NULL; }
| REF_KW { $<y_attributes>$.attr_flags = ASTP_REF;
$<y_attributes>$.bounds = NULL; }
| IGNORE_KW { $<y_attributes>$.attr_flags = ASTP_IGNORE;
$<y_attributes>$.bounds = NULL; }
| CONTEXT_HANDLE_KW { $<y_attributes>$.attr_flags = ASTP_CONTEXT;
$<y_attributes>$.bounds = NULL; }
| RANGE_KW LPAREN expression COMMA expression RPAREN /* MIDL extension */
{ $<y_attributes>$.attr_flags = ASTP_RANGE;
$<y_attributes>$.bounds =
AST_range_from_expr(nidl_location(nidl),
$<y_exp>3, $<y_exp>5);
}
/* Type-only Attribute(s) */
| V1_STRUCT_KW { $<y_attributes>$.attr_flags = ASTP_UNALIGN;
$<y_attributes>$.bounds = NULL; }
| V1_ENUM_KW { $<y_attributes>$.attr_flags = ASTP_V1_ENUM;
$<y_attributes>$.bounds = NULL; }
| ALIGN_KW LPAREN SMALL_KW RPAREN
{ $<y_attributes>$.attr_flags = ASTP_ALIGN_SMALL;
$<y_attributes>$.bounds = NULL; }
| ALIGN_KW LPAREN SHORT_KW RPAREN
{ $<y_attributes>$.attr_flags = ASTP_ALIGN_SHORT;
$<y_attributes>$.bounds = NULL; }
| ALIGN_KW LPAREN LONG_KW RPAREN
{ $<y_attributes>$.attr_flags = ASTP_ALIGN_LONG;
$<y_attributes>$.bounds = NULL; }
| ALIGN_KW LPAREN HYPER_KW RPAREN
{ $<y_attributes>$.attr_flags = ASTP_ALIGN_HYPER;
$<y_attributes>$.bounds = NULL; }
| HANDLE_KW { $<y_attributes>$.attr_flags = ASTP_HANDLE;
$<y_attributes>$.bounds = NULL; }
| TRANSMIT_AS_KW LPAREN simple_type_spec RPAREN
{ $<y_attributes>$.attr_flags = ASTP_TRANSMIT_AS;
$<y_attributes>$.bounds = NULL;
ASTP_transmit_as_type = $<y_type>3;
}
| SWITCH_TYPE_KW LPAREN simple_type_spec RPAREN
{ $<y_attributes>$.attr_flags = ASTP_SWITCH_TYPE;
$<y_attributes>$.bounds = NULL;
ASTP_switch_type = $<y_type>3;
}
/* Arm-only Attribute(s) */
| CASE_KW LPAREN ne_union_case_list RPAREN
{ $<y_attributes>$.attr_flags = ASTP_CASE;
$<y_attributes>$.bounds = NULL;
ASTP_case = $<y_label>3;
}
| DEFAULT_KW { $<y_attributes>$.attr_flags = ASTP_DEFAULT;
$<y_attributes>$.bounds = NULL;
}
| IDENTIFIER /* Not an attribute, so give an error */
{
char const *identifier; /* place to receive the identifier text */
NAMETABLE_id_to_string ($<y_id>1, &identifier);
log_error (nidl_yylineno(nidl), NIDL_UNKNOWNATTR, identifier, NULL);
$<y_attributes>$.attr_flags = 0;
$<y_attributes>$.bounds = NULL;
}
;
/********************************************************************/
/* */
/* Compiletime Integer expression evaluation */
/* */
/********************************************************************/
expression: conditional_expression
{$<y_exp>$ = $<y_exp>1;}
;
conditional_expression:
logical_OR_expression
{$<y_exp>$ = $<y_exp>1;}
| logical_OR_expression QUESTION expression COLON conditional_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_TERNARY_OP, $<y_exp>1, $<y_exp>3, $<y_exp>5);
}
;
logical_OR_expression:
logical_AND_expression
{$<y_exp>$ = $<y_exp>1;}
| logical_OR_expression BARBAR logical_AND_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_LOG_OR, $<y_exp>1, $<y_exp>3, NULL);
}
;
logical_AND_expression:
inclusive_OR_expression
{$<y_exp>$ = $<y_exp>1;}
| logical_AND_expression AMPAMP inclusive_OR_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_LOG_AND, $<y_exp>1, $<y_exp>3, NULL);
}
;
inclusive_OR_expression:
exclusive_OR_expression
{$<y_exp>$ = $<y_exp>1;}
| inclusive_OR_expression BAR exclusive_OR_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_OR, $<y_exp>1, $<y_exp>3, NULL);
}
;
exclusive_OR_expression:
AND_expression
{$<y_exp>$ = $<y_exp>1;}
| exclusive_OR_expression CARET AND_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_XOR, $<y_exp>1, $<y_exp>3, NULL);
}
;
AND_expression:
equality_expression
{$<y_exp>$ = $<y_exp>1;}
| AND_expression AMP equality_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_AND, $<y_exp>1, $<y_exp>3, NULL);
}
;
equality_expression:
relational_expression
{$<y_exp>$ = $<y_exp>1;}
| equality_expression EQUALEQUAL relational_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_EQUAL, $<y_exp>1, $<y_exp>3, NULL);
}
| equality_expression NOTEQUAL relational_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_NE, $<y_exp>1, $<y_exp>3, NULL);
}
;
relational_expression:
shift_expression
{$<y_exp>$ = $<y_exp>1;}
| relational_expression LANGLE shift_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_LT, $<y_exp>1, $<y_exp>3, NULL);
}
| relational_expression RANGLE shift_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_GT, $<y_exp>1, $<y_exp>3, NULL);
}
| relational_expression LESSEQUAL shift_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_LE, $<y_exp>1, $<y_exp>3, NULL);
}
| relational_expression GREATEREQUAL shift_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_GE, $<y_exp>1, $<y_exp>3, NULL);
}
;
shift_expression:
additive_expression
{$<y_exp>$ = $<y_exp>1;}
| shift_expression LANGLEANGLE additive_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_LSHIFT, $<y_exp>1, $<y_exp>3, NULL);
}
| shift_expression RANGLEANGLE additive_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_RSHIFT, $<y_exp>1, $<y_exp>3, NULL);
}
;
additive_expression:
multiplicative_expression
{$<y_exp>$ = $<y_exp>1;}
| additive_expression PLUS multiplicative_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_PLUS, $<y_exp>1, $<y_exp>3, NULL);
}
| additive_expression MINUS multiplicative_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_MINUS, $<y_exp>1, $<y_exp>3, NULL);
}
;
multiplicative_expression:
cast_expression
{$<y_exp>$ = $<y_exp>1;}
| multiplicative_expression STAR cast_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_STAR, $<y_exp>1, $<y_exp>3, NULL);
/*
if (($<y_exp>$.exp.constant.val.integer < $<y_exp>1.exp.constant.val.integer) &&
($<y_exp>$.exp.constant.val.integer < $<y_exp>3.exp.constant.val.integer))
log_error (nidl_yylineno(nidl), NIDL_INTOVERFLOW,
KEYWORDS_lookup_text(LONG_KW), NULL);
*/
}
| multiplicative_expression SLASH cast_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_SLASH, $<y_exp>1, $<y_exp>3, NULL);
}
| multiplicative_expression PERCENT cast_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_BINARY_PERCENT, $<y_exp>1, $<y_exp>3, NULL);
/* log_error (nidl_yylineno(nidl), NIDL_INTDIVBY0, NULL); */
}
;
cast_expression: unary_expression
{$<y_exp>$ = $<y_exp>1;}
;
unary_expression:
primary_expression
{$<y_exp>$ = $<y_exp>1;}
| PLUS primary_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_UNARY_PLUS, $<y_exp>2, NULL, NULL);
}
| MINUS primary_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_UNARY_MINUS, $<y_exp>2, NULL, NULL);
}
| TILDE primary_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_UNARY_TILDE, $<y_exp>2, NULL, NULL);
}
| NOT primary_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_UNARY_NOT, $<y_exp>2, NULL, NULL);
}
| STAR primary_expression
{
$<y_exp>$ = AST_expression(nidl_location(nidl),
AST_EXP_UNARY_STAR, $<y_exp>2, NULL, NULL);
}
;
primary_expression:
LPAREN expression RPAREN
{ $<y_exp>$ = $<y_exp>2; }
| INTEGER_NUMERIC
{
$<y_exp>$ = AST_exp_integer_constant(
nidl_location(nidl),
$<y_int_info>1.int_val,
$<y_int_info>1.int_signed);
}
| CHAR
{
$<y_exp>$ = AST_exp_char_constant(nidl_location(nidl), $<y_char>1);
}
| IDENTIFIER
{
$<y_exp>$ = AST_exp_identifier(nidl_location(nidl), $<y_id>1);
}
| STRING
{
$<y_exp>$ = AST_exp_string_constant(
nidl_location(nidl), $<y_string>1);
}
| NULL_KW
{
$<y_exp>$ = AST_exp_null_constant(nidl_location(nidl));
}
| TRUE_KW
{
$<y_exp>$ = AST_exp_boolean_constant(nidl_location(nidl), true);
}
| FALSE_KW
{
$<y_exp>$ = AST_exp_boolean_constant(nidl_location(nidl), false);
}
| FLOAT_NUMERIC
{
$<y_exp>$ = AST_exp_integer_constant(nidl_location(nidl), 0,0);
log_error(nidl_yylineno(nidl), NIDL_FLOATCONSTNOSUP, NULL);
}
;
%%
nidl_parser_p nidl_parser_alloc
(
boolean *cmd_opt_arr, /* [in] Array of command option flags */
void **cmd_val_arr, /* [in] Array of command option values */
char *nidl_file /* [in] ACF file name */
)
{
nidl_parser_state_t * nidl;
nidl = NEW(nidl_parser_state_t);
/* Set global (STRTAB_str_t error_file_name_id) for error processing. */
set_name_for_errors(nidl_file);
nidl->nidl_location.fileid = STRTAB_add_string(nidl_file);
// XXX save file name ID in parser state
return nidl;
}
void nidl_parser_destroy
(
nidl_parser_p nidl
)
{
FREE(nidl);
yyin_p = NULL;
yylineno_p = NULL;
}
void nidl_parser_input
(
nidl_parser_p nidl,
FILE * in
)
{
assert(nidl->nidl_yyscanner == NULL);
nidl_yylex_init(&nidl->nidl_yyscanner);
nidl_yyset_in(in, nidl->nidl_yyscanner);
yyin_p = in;
yylineno_p = &nidl->nidl_location.lineno;
}
const parser_location_t * nidl_location
(
nidl_parser_p nidl
)
{
/* Update the current location before handing it back ... */
nidl->nidl_location.lineno = nidl_yylineno(nidl);
nidl->nidl_location.location = *nidl_yyget_lloc(nidl->nidl_yyscanner);
nidl->nidl_location.text = nidl_yyget_text(nidl->nidl_yyscanner);
return &nidl->nidl_location;
}
unsigned nidl_yylineno
(
nidl_parser_p nidl
)
{
return nidl_yyget_lineno(nidl->nidl_yyscanner);
}
unsigned nidl_errcount
(
nidl_parser_p nidl
)
{
return nidl->nidl_yynerrs;
}
static void nidl_yyerror
(
YYLTYPE * yylloc ATTRIBUTE_UNUSED,
nidl_parser_p nidl,
char const * message
)
{
const struct parser_location_t * loc;
loc = nidl_location(nidl);
idl_yyerror(loc, message);
}
/* preserve coding style vim: set tw=78 sw=3 ts=3 et : */