/* * Copyright (c) 2002, The Tendra Project * 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 unmodified, 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. * * * Crown Copyright (c) 1997, 1998 * * This TenDRA(r) Computer Program is subject to Copyright * owned by the United Kingdom Secretary of State for Defence * acting through the Defence Evaluation and Research Agency * (DERA). It is made available to Recipients with a * royalty-free licence for its use, reproduction, transfer * to other parties and amendment for any purpose not excluding * product development provided that any such use et cetera * shall be deemed to be acceptance of the following conditions:- * * (1) Its Recipients shall ensure that this Notice is * reproduced upon any copies or amended versions of it; * * (2) Any amended version of it shall be clearly marked to * show both the nature of and the organisation responsible * for the relevant amendment or amendments; * * (3) Its onward transfer from a recipient to another * party shall be deemed to be that party's acceptance of * these conditions; * * (4) DERA gives no warranty or assurance as to its * quality or suitability for any purpose and DERA accepts * no liability whatsoever in relation to any use to which * it may be put. * * $TenDRA: tendra/src/producers/common/parse/psyntax.act,v 1.8 2005/10/14 09:52:18 stefanf Exp $ */ %prefixes% /* * TERMINAL PREFIX * * This prefix is used to identify lexical token numbers in syntax.h * (see also symbols.h). */ terminal = lex_; type = XT; function = XR; input = XI; output = XO; label = XL; %maps% /* * PARSER ENTRY POINTS * * There are a number of entry points into the parser. The main ones * are translation-unit which is used to parse an entire translation * unit and hash-if-expression which is used to parse expressions in * #if preprocessing directives. */ pragma-tendra -> parse_tendra; pragma-preproc -> parse_preproc; /* * BASIC TYPES * * The type BOOL is used to hold the predicate values, true and false. * The type COUNT is used to hold the various counters maintained (see * predict.c). The type LEX is used to hold a lexical token number * (i.e. one of the values defined in syntax.h). The other types used * in the parser map in a simple fashion to the main program types. * Note that it is necessary to use aliases for compound types because * of the restrictions imposed by sid. */ ACCESS -> DECL_SPEC; BOOL -> int; BTYPE -> BASE_TYPE; CV -> CV_SPEC; EXP -> EXP; IDENTIFIER -> IDENTIFIER; LEX -> int; LINKAGE -> DECL_SPEC; LIST-ID -> SID_LIST_ID; NAMESPACE -> NAMESPACE; NUMBER -> int; STATE -> unsigned; TOKEN -> TOKEN; TYPE -> TYPE; VALUE -> unsigned; /* * FILE HEADERS * * These headers are prepended to the parser definition and declaration * output files. Because of the simple file splitting algorithm applied * to the output this should contain only declarations and not definitions. */ %header% @{ /* * Crown Copyright (c) 1997, 1998 * * This TenDRA(r) Computer Program is subject to Copyright * owned by the United Kingdom Secretary of State for Defence * acting through the Defence Evaluation and Research Agency * (DERA). It is made available to Recipients with a * royalty-free licence for its use, reproduction, transfer * to other parties and amendment for any purpose not excluding * product development provided that any such use et cetera * shall be deemed to be acceptance of the following conditions:- * * (1) Its Recipients shall ensure that this Notice is * reproduced upon any copies or amended versions of it; * * (2) Any amended version of it shall be clearly marked to * show both the nature of and the organisation responsible * for the relevant amendment or amendments; * * (3) Its onward transfer from a recipient to another * party shall be deemed to be that party's acceptance of * these conditions; * * (4) DERA gives no warranty or assurance as to its * quality or suitability for any purpose and DERA accepts * no liability whatsoever in relation to any use to which * it may be put. */ #include "config.h" #include "producer.h" #include "c_types.h" #include "exp_ops.h" #include "hashid_ops.h" #include "id_ops.h" #include "tok_ops.h" #include "type_ops.h" #include "error.h" #include "catalog.h" #include "option.h" #include "access.h" #include "allocate.h" #include "assign.h" #include "basetype.h" #include "cast.h" #include "chktype.h" #include "class.h" #include "constant.h" #include "construct.h" #include "convert.h" #include "declare.h" #include "derive.h" #include "exception.h" #include "expression.h" #include "function.h" #include "hash.h" #include "identifier.h" #include "initialise.h" #include "inttype.h" #include "label.h" #include "lex.h" #include "literal.h" #include "member.h" #include "namespace.h" #include "parse.h" #include "pragma.h" #include "predict.h" #include "preproc.h" #include "printf.h" #include "redeclare.h" #include "rewrite.h" #include "statement.h" #include "symbols.h" #include "template.h" #include "tokdef.h" #include "token.h" #include "typeid.h" #include "variable.h" /* * COMPOUND TYPE ALIASES * * These are the aliases for the compound types used in the parser. */ typedef LIST (IDENTIFIER) SID_LIST_ID; /* * DECLARE FUNCTIONS * * The function declarations are included at this point so that the * type definitions are in scope. */ #include "psyntax.h" extern void parse_tok_type(TYPE *); extern void parse_mem_type(TYPE *); extern void parse_operator(IDENTIFIER *); /* * COMPILATION MODE * * The output of sid is automatically generated. Hence it is not * necessarily appropriate to apply the same level of checking to this * as to the rest of the program. These pragmas describe the relaxations * allowed for the sid output. */ #if FS_TENDRA #pragma TenDRA begin #pragma TenDRA variable analysis off #ifndef OLD_PRODUCER #pragma TenDRA unreachable code allow #endif #endif @}, @{ /* * Crown Copyright (c) 1997, 1998 * * This TenDRA(r) Computer Program is subject to Copyright * owned by the United Kingdom Secretary of State for Defence * acting through the Defence Evaluation and Research Agency * (DERA). It is made available to Recipients with a * royalty-free licence for its use, reproduction, transfer * to other parties and amendment for any purpose not excluding * product development provided that any such use et cetera * shall be deemed to be acceptance of the following conditions:- * * (1) Its Recipients shall ensure that this Notice is * reproduced upon any copies or amended versions of it; * * (2) Any amended version of it shall be clearly marked to * show both the nature of and the organisation responsible * for the relevant amendment or amendments; * * (3) Its onward transfer from a recipient to another * party shall be deemed to be that party's acceptance of * these conditions; * * (4) DERA gives no warranty or assurance as to its * quality or suitability for any purpose and DERA accepts * no liability whatsoever in relation to any use to which * it may be put. */ #ifndef PSYNTAX_INCLUDED #define PSYNTAX_INCLUDED @}; %terminals% /* * IDENTIFIER TERMINALS * * Identifiers and related terminals (type names, namespace names and * destructor names) are identified by means of an identifier stored in * crt_token by expand_token. */ identifier: () -> (id) = @{ @id = crt_token->pp_data.id.use; @}; type-name: () -> (id) = @{ @id = crt_token->pp_data.id.use; @}; namespace-name: () -> (id) = @{ @id = crt_token->pp_data.id.use; @}; statement-name: () -> (id) = @{ @id = crt_token->pp_data.id.use; @}; destructor-name: () -> (id) = @{ @id = crt_token->pp_data.id.use; @}; template-id: () -> (id) = @{ IDENTIFIER id = crt_token->pp_data.tok.id; PPTOKEN *args = crt_token->pp_data.tok.args; @id = parse_id_template (id, args, 0); crt_templ_qualifier = 1; RESCAN_LEXER; @}; template-type: () -> (id) = @{ IDENTIFIER id = crt_token->pp_data.tok.id; PPTOKEN *args = crt_token->pp_data.tok.args; @id = parse_type_template (id, args, 0); crt_templ_qualifier = 1; RESCAN_LEXER; @}; /* * NAMESPACE SPECIFIER TERMINALS * * Namespace specifiers (i.e. sequences of namespace or class names * separated using '::') are identified by expand_token. The full nested * names are those which begin with the global namespace. */ nested-name: () -> (ns) = @{ @ns = crt_token->pp_data.ns; @}; full-name: () -> (ns) = @{ @ns = crt_token->pp_data.ns; @}; /* * POINTER TO MEMBER TERMINALS * * Pointer to member specifiers (such as 'C::*') are identified by * expand_token. The identifier corresponding to the given class is * stored in crt_token. */ nested-name-star: () -> (id) = @{ @id = crt_token->pp_data.id.use; @}; full-name-star: () -> (id) = @{ @id = crt_token->pp_data.id.use; @}; /* * INTEGER AND FLOATING-POINT LITERAL TERMINALS * * Integer and floating-point literal tokens have already been transformed * into their corresponding expressions by expand_token, which stores this * information in crt_token. */ integer-exp: () -> (e) = @{ @e = crt_token->pp_data.exp; @}; floating-exp: () -> (e) = @{ @e = crt_token->pp_data.exp; @}; /* * STRING AND CHARACTER LITERAL TERMINALS * * String and character literal tokens have already been transformed * into their corresponding expressions by expand_token, which stores this * information in crt_token. */ char-exp: () -> (e) = @{ @e = crt_token->pp_data.exp; @}; wchar-exp: () -> (e) = @{ @e = crt_token->pp_data.exp; @}; string-exp: () -> (e) = @{ @e = crt_token->pp_data.exp; @}; wstring-exp: () -> (e) = @{ @e = crt_token->pp_data.exp; @}; /* * CONDITIONAL COMPILATION TERMINALS * * Any target dependent conditional compilation expressions are stored * in crt_token by the preprocessing routines. */ hash-if: () -> (e) = @{ @e = crt_token->pp_data.exp; @}; hash-elif: () -> (e) = @{ @e = crt_token->pp_data.exp; @}; /* * COMPLEX EXPRESSION AND TYPE TERMINALS * * These terminals are used to handle complex expressions and types * such as token applications. */ complex-exp: () -> (e) = @{ IDENTIFIER id = crt_token->pp_data.tok.id; PPTOKEN *args = crt_token->pp_data.tok.args; @e = parse_exp_token (id, args); RESCAN_LEXER; @}; complex-stmt: () -> (e) = @{ IDENTIFIER id = crt_token->pp_data.tok.id; PPTOKEN *args = crt_token->pp_data.tok.args; @e = parse_exp_token (id, args); RESCAN_LEXER; @}; complex-type: () -> (t) = @{ IDENTIFIER id = crt_token->pp_data.tok.id; PPTOKEN *args = crt_token->pp_data.tok.args; @t = parse_type_token (id, args); have_type_declaration = TYPE_DECL_NONE; have_type_specifier = 1; RESCAN_LEXER; @}; %actions% /* * LINKS TO MAIN SYNTAX * * These actions give links into the main syntax. Note that none of the * used rules in the main syntax has an associated exception handler, * allowing syntax errors to be handled in the pragma syntax. */ : () -> (t) = @{ @t = type_error; parse_tok_type (&@t); object_type (@t, null_tag); @}; : () -> (t) = @{ @t = type_error; parse_tok_type (&@t); object_type (@t, id_function_tag); @}; : () -> (t) = @{ @t = type_error; parse_mem_type (&@t); object_type (@t, null_tag); @}; : () -> (id) = @{ @id = DEREF_id (hashid_id (KEYWORD (lex_zzzz))); parse_operator (&@id); @}; : () -> (b) = @{ @b = predict_operator (); @}; /* * LEXICAL TOKENS * * These actions give the basic values for the type LEX. They are used * primarily in overloaded operator function names, but they are also used * to distinguish closely related groups of expressions, such as relational * expressions. Note that the primary form of the token has been given * whenever there is a choice, otherwise the actions are very dull. */ : () -> (t) = @{ @t = lex_asm; @}; : () -> (t) = @{ @t = lex_discard; @}; : () -> (t) = @{ @t = lex_exhaustive; @}; : () -> (t) = @{ @t = lex_fall; @}; : () -> (t) = @{ @t = lex_inline; @}; : () -> (t) = @{ @t = lex_ignore_token; @}; : () -> (t) = @{ @t = lex_postpone; @}; : () -> (t) = @{ @t = lex_hash_Hpragma; @}; : () -> (t) = @{ @t = lex_reachable; @}; : () -> (t) = @{ @t = lex_representation; @}; : () -> (t) = @{ @t = lex_set; @}; : () -> (t) = @{ @t = lex_unpostpone; @}; : () -> (t) = @{ @t = lex_unreachable; @}; : () -> (t) = @{ @t = lex_unused; @}; : () -> (t) = @{ @t = lex_weak; @}; : () -> (t) = @{ @t = crt_lex_token; if (@t >= FIRST_SYMBOL && @t <= LAST_SYMBOL) crt_lex_token = lex_plus; @}; /* * SPECIAL IDENTIFIERS * * id_none gives the null identifier and id_anon generates a unique * anonymous identifier. */ : () -> (id) = @{ @id = NULL_id; crt_id_qualifier = qual_none; qual_namespace = NULL_nspace; @}; : () -> (id) = @{ HASHID nm = lookup_anon (); @id = DEREF_id (hashid_id (nm)); crt_id_qualifier = qual_none; qual_namespace = NULL_nspace; @}; : () -> (e) = @{ @e = NULL_exp; @}; /* * CONST-VOLATILE QUALIFIERS * * These actions describe how to construct and combine the const and * volatile type qualifiers. */ : () -> (cv) = @{ @cv = cv_none; @}; : () -> (cv) = @{ @cv = cv_const; @}; /* * BASIC TYPES * * These actions describe the basic type specifiers, char, short, int, * and so on. This is a simple map onto the calculus type BTYPE. */ : () -> (bt) = @{ @bt = btype_signed; @}; : () -> (bt) = @{ @bt = btype_unsigned; @}; : () -> (bt) = @{ @bt = btype_wchar_t; @}; : () -> (bt) = @{ @bt = btype_size_t; @}; : () -> (bt) = @{ @bt = btype_ptrdiff_t; @}; : () -> (bt) = @{ @bt = btype_none; @}; /* * ACCESS SPECIFIERS * * These actions describe the access specifiers, private, protected and * public. */ : () -> (a) = @{ @a = dspec_private; @}; : () -> (a) = @{ @a = dspec_protected; @}; : () -> (a) = @{ @a = dspec_public; @}; /* * LINKAGE SPECIFIERS * * These actions describe the linkage specifiers. These are implemented * by a simple global variable, crt_linkage. The action linkage_string * translates a string literal expression into a linkage specifier. */ : (s) -> (a) = @{ @a = find_linkage (@s); @}; /* * OBJECT DECLARATIONS * * These actions describe how to construct an object declaration. */ : () -> () = @{ crt_templ_qualifier = 0; @}; /* * LISTS OF IDENTIFIERS * * These actions give the basic constructs for building up lists of * identifiers. They map directly to the calculus list operations. */ : () -> (p) = @{ @p = NULL_list (IDENTIFIER); @}; : (id, q) -> (p) = @{ CONS_id (@id, @q, @p); @}; /* * TOKEN ACTIONS * * The following rules are concerned with the construction and definition * of TDF tokens. */ : () -> (t) = @{ MAKE_tok_nat (NULL_nat, @t); @}; : () -> (t) = @{ MAKE_tok_snat (NULL_nat, @t); @}; : () -> (t) = @{ MAKE_tok_stmt (NULL_exp, @t); @}; : () -> (t) = @{ @t = make_type_token (btype_none); @}; : () -> (t) = @{ @t = make_type_token (btype_int); @}; : () -> (t) = @{ @t = make_type_token (btype_signed | btype_int); @}; : () -> (t) = @{ @t = make_type_token (btype_unsigned | btype_int); @}; : () -> (t) = @{ @t = make_type_token (btype_float); @}; : () -> (t) = @{ @t = make_type_token (btype_arith); @}; : () -> (t) = @{ @t = make_type_token (btype_lang); @}; : () -> (t) = @{ @t = make_type_token (btype_scalar); @}; : () -> (t) = @{ @t = make_type_token (btype_struct); @}; : () -> (t) = @{ @t = make_type_token (btype_union); @}; : (a, c, b) -> (t) = @{ @t = make_exp_token (@b, @a, @c); @}; : (p, a, b) -> (t) = @{ @t = make_member_token (@a, @b, @p); @}; : (a) -> (t) = @{ @t = make_func_token (@a); @}; : (t, b, tid) -> (id) = @{ @id = make_tok_param (@t, @b, @tid); @}; : (tid, r) -> (id) = @{ @id = prog_tok_param (@tid, NULL_type, tok_exp_tag, @r); @}; : (tid, r) -> (id) = @{ @id = prog_tok_param (@tid, NULL_type, tok_stmt_tag, @r); @}; : (t, r) -> (id) = @{ IDENTIFIER tid = DEREF_id (type_name (@t)); @id = prog_tok_param (tid, @t, tok_type_tag, @r); @}; : (t, tid, r) -> (id) = @{ @id = prog_tok_param (@tid, @t, tok_member_tag, @r); @}; : (tid, r) -> (id) = @{ @id = prog_tok_param (@tid, NULL_type, tok_proc_tag, @r); @}; : () -> (t) = @{ @t = begin_proc_token (); @}; : (a, p) -> (t) = @{ @t = cont_proc_token (@a, @p, @p); @}; : (a, p, q) -> (t) = @{ @t = cont_proc_token (@a, @p, @q); @}; : (a, b) -> (t) = @{ @t = end_proc_token (@a, @b); @}; : (t, c, a, b) -> () = @{ IGNORE make_token_decl (@t, @c, @a, @b); @}; : (a) -> (id) = @{ @id = check_id (crt_namespace, @a, 0); @}; : (a) -> (id) = @{ @id = find_tag_token (@a); @}; : (a, b) -> (id) = @{ @id = find_mem_token (@a, @b); @}; : (a) -> (id) = @{ @id = find_ext_token (@a); @}; : (id, i) -> () = @{ token_interface (@id, @i); @}; : (t, id) -> () = @{ if (define_mem_macro (@id, @t)) no_declarations++; @}; : () -> () = @{ in_token_decl = 1; @}; : () -> () = @{ in_token_decl = 0; @}; : (id) -> () = @{ allow_conversion (@id); @}; : (id) -> () = @{ allow_initialiser (@id); @}; : (id, a) -> () = @{ preserve_id (@id, @a); @}; : (id) -> () = @{ preserve_id (@id, lex_preserve); @}; : () -> () = @{ preserve_all = 1; @}; : (id) -> () = @{ preserve_id (@id, lex_suspend); @}; : () -> (i) = @{ @i = lex_define; @}; : () -> (i) = @{ @i = lex_no_Hdef; @}; : () -> (i) = @{ @i = lex_ignore; @}; : () -> (i) = @{ @i = crt_interface; @}; : () -> (i) = @{ @i = lex_undef; @}; /* * INTEGER LITERAL PRAGMA DIRECTIVES * * The following rules are concerned with processing those '#pragma' * directives concerned with defining integer literal types. */ : () -> (b) = @{ @b = BASE_OCTAL; @}; : () -> (b) = @{ @b = BASE_DECIMAL; @}; : () -> (b) = @{ @b = BASE_HEXADECIMAL; @}; : () -> (s) = @{ @s = SUFFIX_NONE; @}; : () -> (s) = @{ @s = SUFFIX_U; @}; : () -> (s) = @{ @s = SUFFIX_L; @}; : () -> (s) = @{ @s = SUFFIX_UL; @}; : () -> (s) = @{ @s = SUFFIX_LL; @}; : () -> (s) = @{ @s = SUFFIX_ULL; @}; : () -> () = @{ pragma_number = 1; @}; : (b, s) -> () = @{ begin_literal (@b, @s); @}; : () -> () = @{ add_range_literal (NULL_exp, 0); @}; : (e) -> () = @{ add_range_literal (@e, 2); @}; : () -> () = @{ add_range_literal (NULL_exp, 1); @}; : (t) -> () = @{ add_type_literal (@t); @}; : (id, a) -> () = @{ add_token_literal (@id, @a); @}; : (a) -> () = @{ add_token_literal (NULL_id, @a); @}; /* * CHECKING SCOPE PRAGMA DIRECTIVES * * The following rules are concerned with processing those '#pragma' * directives concerned with defining error checking scopes. */ : (id) -> () = @{ begin_option (@id); @}; : () -> () = @{ end_option (1); @}; : (dir, id) -> () = @{ directory_option (@dir, @id); @}; : (id, e) -> () = @{ use_option (@id, @e); @}; : (id) -> () = @{ begin_decl_block (@id); @}; : () -> () = @{ IGNORE end_decl_block (NULL_id, 1); @}; /* * ERROR PRAGMA DIRECTIVES * * The following rules are concerned with processing those '#pragma' * directives concerned with error messages. */ : (e) -> (n) = @{ STRING s = DEREF_str (exp_string_lit_str (@e)); @n = find_error_no (s, 0); if (@n == -1) { report (preproc_loc, ERR_pragma_error_bad (s)); } @}; : (e) -> (n) = @{ STRING s = DEREF_str (exp_string_lit_str (@e)); @n = find_option_no (s, 0); if (@n == -1) { report (preproc_loc, ERR_pragma_option_bad (s)); } @}; : (e) -> (n) = @{ STRING s = DEREF_str (exp_string_lit_str (@e)); @n = find_value_no (s, 0); if (@n == -1) { report (preproc_loc, ERR_pragma_option_bad (s)); } @}; : () -> (e) = @{ @e = (unsigned) OPTION_ON; @}; : () -> (e) = @{ @e = (unsigned) OPTION_OFF; @}; : () -> (e) = @{ @e = (unsigned) OPTION_WARN; @}; : (n, e) -> () = @{ set_error_sev (@n, @e); @}; : (n) -> () = @{ if (@n >= 0) { no_error_args = 1; report (crt_loc, make_error (@n)); no_error_args = 0; } @}; /* * TYPE PRAGMA DIRECTIVES * * The following rules are concerned with processing those '#pragma' * directives concerned with types. */ : (s, t) -> () = @{ accept_argument (@s, @t); @}; : (t) -> () = @{ accept_ellipsis (@t); @}; : (t) -> () = @{ set_char_lit (@t); @}; : (bt) -> () = @{ set_char_sign (@bt); @}; : (cv) -> () = @{ set_string_qual (@cv); @}; : (b) -> () = @{ set_long_long_type (@b); @}; : (s, t, e) -> () = @{ set_compatible_type (@s, @t, @e); @}; : (id) -> () = @{ compute_promote_type (@id); @}; : (s, t) -> () = @{ set_promote_type (@s, @t, ntype_ellipsis); @}; : (bt, t) -> () = @{ set_builtin_type (@bt, @t); @}; : (id, t) -> () = @{ typedef_special (@id, @t); @}; : (id) -> () = @{ set_std_namespace (@id); @}; : () -> (t) = @{ @t = type_bottom; @}; : () -> (t) = @{ @t = type_printf; @}; : () -> (t) = @{ @t = type_scanf; @}; : () -> (t) = @{ @t = type_wprintf; @}; : () -> (t) = @{ @t = type_wscanf; @}; : () -> (t) = @{ @t = type_ptrdiff_t; @}; : () -> (t) = @{ @t = type_size_t; @}; : () -> (t) = @{ @t = type_wchar_t; @}; /* * KEYWORD PRAGMA DIRECTIVES * * The following rules are concerned with processing those '#pragma' * directives concerned with keywords. */ : (id) -> (t) = @{ @t = find_keyword (@id); @}; : (id, t) -> () = @{ define_keyword (@id, @t); @}; : (id) -> () = @{ undef_keyword (@id); @}; /* * CHARACTER PRAGMA DIRECTIVES * * The following rules are concerned with processing those '#pragma' * directives concerned with characters. */ : (a, b) -> () = @{ set_character (@a, @b); @}; : (a, b) -> () = @{ set_escape (@a, @b); @}; /* * CAST PRAGMA DIRECTIVES * * The following rules are concerned with processing those '#pragma' * directives concerned with explicit casts. */ : () -> (c) = @{ @c = CAST_STATIC; @}; : () -> (c) = @{ @c = CAST_REINTERP; @}; : () -> (c) = @{ @c = CAST_CONST; @}; : () -> (c) = @{ @c = CAST_EXPLICIT; @}; : (a, b) -> (c) = @{ @c = (@a | @b); @}; /* * OPTION PRAGMA DIRECTIVES * * The following rules are concerned with processing those '#pragma' * directives concerned with setting options. */ : (n, e) -> () = @{ set_option (@n, @e); @}; : (n, v) -> () = @{ set_value (@n, NULL_exp, (unsigned long) @v); @}; : (n, e) -> () = @{ set_value (@n, @e, (unsigned long) 0); @}; : (a) -> () = @{ set_link_opt (@a); @}; : () -> (n) = @{ @n = OPT_error; @}; : () -> (n) = @{ @n = OPT_none; @}; : () -> (n) = @{ @n = OPT_warning; @}; : () -> (n) = @{ @n = OPT_bitf_overflow; @}; : () -> (n) = @{ @n = OPT_bitf_type; @}; : () -> (n) = @{ @n = OPT_bool_assign; @}; : () -> (n) = @{ @n = OPT_case_fall; @}; : () -> (n) = @{ @n = OPT_cast_explicit; @}; : () -> (n) = @{ @n = OPT_comma_extra; @}; : () -> (n) = @{ @n = OPT_complete_struct; @}; : () -> (n) = @{ @n = OPT_concat_string; @}; : () -> (n) = @{ @n = OPT_cond_lvalue; @}; : () -> (n) = @{ @n = OPT_const_cond; @}; : () -> (n) = @{ @n = OPT_const_internal; @}; : () -> (n) = @{ @n = OPT_const_string; @}; : () -> (n) = @{ @n = OPT_conv; @}; : () -> (n) = @{ @n = OPT_conv_int_enum; @}; : () -> (n) = @{ @n = OPT_conv_int_int; @}; : () -> (n) = @{ @n = OPT_conv_int_int_expl; @}; : () -> (n) = @{ @n = OPT_conv_int_int_impl; @}; : () -> (n) = @{ @n = OPT_conv_int_ptr; @}; : () -> (n) = @{ @n = OPT_conv_int_ptr_expl; @}; : () -> (n) = @{ @n = OPT_conv_int_ptr_impl; @}; : () -> (n) = @{ @n = OPT_conv_ptr_func; @}; : () -> (n) = @{ @n = OPT_conv_ptr_ptr; @}; : () -> (n) = @{ @n = OPT_conv_ptr_ptr_expl; @}; : () -> (n) = @{ @n = OPT_conv_ptr_ptr_impl; @}; : () -> (n) = @{ @n = OPT_conv_ptr_ptr_void; @}; : () -> (n) = @{ @n = OPT_conv_ptr_void_ptr; @}; : () -> (n) = @{ @n = OPT_decl_cond; @}; : () -> (n) = @{ @n = OPT_decl_hide; @}; : () -> (n) = @{ @n = OPT_decl_none; @}; : () -> (n) = @{ @n = OPT_decl_struct_anon; @}; : () -> (n) = @{ @n = OPT_decl_unify; @}; : () -> (n) = @{ @n = OPT_decl_volatile; @}; : () -> (n) = @{ @n = OPT_discard; @}; : () -> (n) = @{ @n = OPT_discard_func; @}; : () -> (n) = @{ @n = OPT_discard_static; @}; : () -> (n) = @{ @n = OPT_discard_value; @}; : () -> (n) = @{ @n = OPT_dollar_ident; @}; : () -> (n) = @{ @n = OPT_dspec_none; @}; : () -> (n) = @{ @n = OPT_dspec_none_func; @}; : () -> (n) = @{ @n = OPT_ellipsis_extra; @}; : () -> (n) = @{ @n = OPT_ellipsis_ident; @}; : () -> (n) = @{ @n = OPT_empty_body; @}; : () -> (n) = @{ @n = OPT_enum_decl; @}; : () -> (n) = @{ @n = OPT_enum_switch; @}; : () -> (n) = @{ @n = OPT_eof_nline; @}; : () -> (n) = @{ @n = OPT_escape_overflow; @}; : () -> (n) = @{ @n = OPT_escape_unknown; @}; : () -> (n) = @{ @n = OPT_for_scope; @}; : () -> (n) = @{ @n = OPT_func_block; @}; : () -> (n) = @{ @n = OPT_func_impl; @}; : () -> (n) = @{ @n = OPT_func_incompat; @}; : () -> (n) = @{ @n = OPT_func_linkage; @}; : () -> (n) = @{ @n = OPT_func_proto; @}; : () -> (n) = @{ @n = OPT_func_ret_void; @}; : () -> (n) = @{ @n = OPT_func_token_undef; @}; : () -> (n) = @{ @n = OPT_func_weak; @}; : () -> (n) = @{ @n = OPT_hash_ident; @}; : () -> (n) = @{ @n = OPT_infer_int; @}; : () -> (n) = @{ @n = OPT_infer_int_cv; @}; : () -> (n) = @{ @n = OPT_include_full; @}; : () -> (n) = @{ @n = OPT_init_aggregate; @}; : () -> (n) = @{ @n = OPT_init_dynamic; @}; : () -> (n) = @{ @n = OPT_init_struct; @}; : () -> (n) = @{ @n = OPT_inline_internal; @}; : () -> (n) = @{ @n = OPT_interf_incompat; @}; : () -> (n) = @{ @n = OPT_int_operator; @}; : () -> (n) = @{ @n = OPT_int_overflow; @}; : () -> (n) = @{ @n = OPT_link_incompat; @}; : () -> (n) = @{ @n = OPT_link_internal; @}; : () -> (n) = @{ @n = OPT_link_resolve; @}; : () -> (n) = @{ @n = OPT_longlong; @}; : () -> (n) = @{ @n = OPT_macro_arg_dir; @}; : () -> (n) = @{ @n = OPT_macro_redef; @}; : () -> (n) = @{ @n = OPT_macro_weak; @}; : () -> (n) = @{ @n = OPT_member_incompat; @}; : () -> (n) = @{ @n = OPT_name_limit; @}; : () -> (n) = @{ @n = OPT_nest_comment; @}; : () -> (n) = @{ @n = OPT_overload_ambig; @}; : () -> (n) = @{ @n = OPT_overload_dep; @}; : () -> (n) = @{ @n = OPT_overload_res; @}; : () -> (n) = @{ @n = OPT_overload_strict; @}; : () -> (n) = @{ @n = OPT_param_impl; @}; : () -> (n) = @{ @n = OPT_paren; @}; : () -> (n) = @{ @n = OPT_ppdir_id; @}; : () -> (n) = @{ @n = OPT_ppdir_indent; @}; : () -> (n) = @{ @n = OPT_ppdir_indent_dir; @}; : () -> (n) = @{ @n = OPT_ppdir_text; @}; : () -> (n) = @{ @n = OPT_ppdir_unknown; @}; : () -> (n) = @{ @n = OPT_pragma_unknown; @}; : () -> (n) = @{ @n = OPT_ptr_operator; @}; : () -> (n) = @{ @n = OPT_reached; @}; : () -> (n) = @{ @n = OPT_semicolon_extra; @}; : () -> (n) = @{ @n = OPT_templ_export; @}; : () -> (n) = @{ @n = OPT_this_lvalue; @}; : () -> (n) = @{ @n = OPT_throw_bad; @}; : () -> (n) = @{ @n = OPT_token_const; @}; : () -> (n) = @{ @n = OPT_token_redef; @}; : () -> (n) = @{ @n = OPT_token_undef; @}; : () -> (n) = @{ @n = OPT_type_obj_incompl; @}; : () -> (n) = @{ @n = OPT_type_qual_incompat; @}; : () -> (n) = @{ @n = OPT_type_redef; @}; : () -> (n) = @{ @n = OPT_type_tag_ignore; @}; : () -> (n) = @{ @n = OPT_unmatched; @}; : () -> (n) = @{ @n = OPT_variable; @}; : () -> (n) = @{ @n = OPT_wall; @}; : () -> (n) = @{ @n = OPT_weak; @}; : () -> (n) = @{ @n = OPT_VAL_cast_explicit; @}; : () -> (n) = @{ @n = OPT_VAL_include_depth; @}; : () -> (n) = @{ @n = OPT_VAL_maximum_error; @}; : () -> (n) = @{ @n = OPT_VAL_name_limit; @}; : () -> (n, m) = @{ @n = OPT_ppdir_assert; @m = OPT_ppdir_assert_ignore; @}; : () -> (n, m) = @{ @n = OPT_ppdir_file; @m = OPT_ppdir_file_ignore; @}; : () -> (n, m) = @{ @n = OPT_ppdir_ident; @m = OPT_ppdir_ident_ignore; @}; : () -> (n, m) = @{ @n = OPT_ppdir_import; @m = OPT_ppdir_import_ignore; @}; : () -> (n, m) = @{ @n = OPT_ppdir_unassert; @m = OPT_ppdir_unassert_ignore; @}; : () -> (n, m) = @{ @n = OPT_ppdir_warning; @m = OPT_ppdir_warning_ignore; @}; : () -> (n, m) = @{ @n = OPT_ppdir_weak; @m = OPT_ppdir_weak_ignore; @}; /* * ERROR REPORTING * * These actions describe the error reporting functions for syntax errors * and for weeding out extra constructs which have been allowed in the * grammar to permit for better error reporting. */ : () -> () = @{ /* Syntax errors */ ERROR err = ERR_lex_parse (crt_token); report (crt_loc, err); have_syntax_error = 1; @}; : () -> () = @{ /* Extra comma at the end of a list */ report (crt_loc, ERR_lex_extra_comma ()); @}; /* * PREDICATE LITERALS * * These actions give the basic values, true and false, for the type * BOOL. */ : () -> (b) = @{ @b = 0; @}; : () -> (b) = @{ @b = 1; @}; /* * PARSER HACKS AND PATCHES * * In a couple of places it is necessary to fool the parser by changing * the next token (or even inserting an extra token) depending on the * current state. */ : () -> () = @{ int t = crt_lex_token; if (t >= FIRST_KEYWORD && t <= LAST_KEYWORD) { crt_lex_token = lex_identifier; } @}; : () -> () = @{ int t = crt_lex_token; if (t == lex_identifier || t == lex_type_Hname || t == lex_namespace_Hname || t == lex_statement_Hname) { t = find_hashid (crt_token->pp_data.id.hash); crt_lex_token = t; } @}; : () -> () = @{ rescan_pragma (lex_unknown); RESCAN_LEXER; @}; : () -> () = @{ rescan_pragma (lex_allow); RESCAN_LEXER; @}; : () -> () = @{ rescan_pragma (lex_as); RESCAN_LEXER; @}; : () -> () = @{ int t = crt_lex_token; if (t >= FIRST_KEYWORD && t <= LAST_KEYWORD) { if (t != lex_tag_Hcap && !predict_operator ()) { crt_lex_token = lex_identifier; } } @}; /* * FILE TRAILERS * * These trailers are appended to the parser definition and declaration * output files. */ %trailer% @{ @}, @{ /* * DUMMY LEXICAL TOKEN VALUES * * These values are used as lexical token values in certain circumstances * but do not represent actual tokens. Note that they are all negative. */ #define lex_ignore_token -1 #define lex_end_condition -2 #define lex_included -3 #define lex_placemarker -4 #endif @};