/*
* 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.sid,v 1.9 2005/10/16 07:47:46 stefanf Exp $
*/
/*
* PRAGMA SYNTAX
*
* This module gives the syntax for the '#pragma' directives recognised
* by the producer.
*/
/*
* TYPE DECLARATIONS
*
* The types BOOL, COUNT and LEX are natural types arising from the
* parser. The remaining types directly correspond to types within the
* main program, or composite types formed from them.
*/
%types%
ACCESS;
BOOL;
BTYPE;
CV;
EXP;
IDENTIFIER;
LEX;
LINKAGE;
LIST-ID;
NAMESPACE;
NUMBER;
STATE;
TOKEN;
TYPE;
VALUE;
/*
* LIST OF TERMINALS
*
* This list of terminals corresponds to that given in symbols.h and
* syntax.h.
*/
%terminals%
!unknown;
/* Identifiers */
identifier: () -> (:IDENTIFIER);
type-name: () -> (:IDENTIFIER);
namespace-name: () -> (:IDENTIFIER);
statement-name: () -> (:IDENTIFIER);
!destructor-name: () -> (:IDENTIFIER);
!template-id: () -> (:IDENTIFIER);
!template-type: () -> (:IDENTIFIER);
/* Nested name specifiers */
!nested-name: () -> (:NAMESPACE);
!full-name: () -> (:NAMESPACE);
!nested-name-star: () -> (:IDENTIFIER);
!full-name-star: () -> (:IDENTIFIER);
/* Literals */
!char-lit; !wchar-lit; !string-lit; !wstring-lit; !integer-lit;
/* Literal expressions */
char-exp: () -> (:EXP);
wchar-exp: () -> (:EXP);
string-exp: () -> (:EXP);
wstring-exp: () -> (:EXP);
integer-exp: () -> (:EXP);
!floating-exp: () -> (:EXP);
/* Token applications */
!complex-exp: () -> (:EXP);
!complex-stmt: () -> (:EXP);
!complex-type: () -> (:TYPE);
/* Target-dependent preprocessing directives */
!hash-if: () -> (:EXP);
!hash-elif: () -> (:EXP);
!hash-else;
!hash-endif;
!hash-pragma;
/* End of file markers */
!newline; !eof;
/* Symbols */
!and-1; !and-eq-1; !arrow; !assign; !backslash; close-brace-1;
close-round; !close-square-1; colon; comma; !compl-1; div; !div-eq;
dot; ellipsis; eq; !greater; !greater-eq; hash-1; !hash-hash-1;
!less; !less-eq; !logical-and-1; !logical-or-1; !lshift; !lshift-eq;
minus; !minus-eq; !minus-minus; !not-1; !not-eq-1; open-brace-1;
open-round; !open-square-1; or-1; !or-eq-1; plus; !plus-eq;
!plus-plus; question; !rem; !rem-eq; !rshift; !rshift-eq;
semicolon; star; !star-eq; !xor-1; !xor-eq-1; !arrow-star;
colon-colon; !dot-star; !abs; !max; !min;
/* Digraphs */
!close-brace-2; !close-square-2; !hash-2; !hash-hash-2;
!open-brace-2; !open-square-2;
/* C keywords */
auto; !break; case; !char; const; !continue; !default; !do;
!double; !else; enum; !extern; !float; for; !goto; !if; int;
long; !register; return; !short; signed; !sizeof; static; struct;
switch; !typedef; union; unsigned; void; volatile; !while;
/* C99 keywords */
!restrict;
/* C++ keywords */
asm; bool; catch; !class; const-cast; !delete; !dynamic-cast;
explicit; export; !false; !friend; inline; !mutable; namespace;
!new; operator; private; protected; public; reinterpret-cast;
static-cast; template; this; throw; !true; !try; !typeid;
!typename; !using; !virtual; wchar-t;
/* ISO keywords */
!and-2; !and-eq-2; !compl-2; !logical-and-2; !logical-or-2;
!not-2; !not-eq-2; !or-2; !or-eq-2; !xor-2; !xor-eq-2;
/* TenDRA keywords */
accept; after; !alignof; all; allow; ambiguous; analysis;
argument; arith-cap; !array; as; assert; assignment; begin;
bitfield; block; bottom; cast; character; class-cap; code;
comment; compatible; complete; compute; conditional; conversion;
decimal; decl; define; !define-cap; !defined; definition; depth;
directive; directory; disallow; discard; dollar; either; !elif;
ellipsis-exp; end; !endif; environment; equality; error; escape;
exhaustive; exp-cap; !explain; !extend; external; extra; fall;
file; float-cap; forward; func-cap; !func-id; function; hexadecimal; hiding;
ident; identif; !ifdef; !ifndef; ignore; !implement; implicit;
import; !include; includes; include-next; incompatible; incomplete;
indented; initialization; integer; interface; internal; into;
int-cap; keyword; limit; !line; linkage; lit; longlong; lvalue;
macro; !main; member; member-cap; name; nat-cap; nested; nline;
no; no-def; object; octal; of; off; on; option; overflow;
overload; pointer; postpone; pragma; !pragma-2; precedence; preserve; printf;
proc-cap; promote; promoted; prototype; ptrdiff-t; qualifier;
quote; reachable; !reference; reject; representation; reset;
resolution; rvalue; scalar-cap; scanf; set; size-t; !size-t-2;
!sort; std; stmt-cap; string; struct-cap; suspend; tag; tag-cap;
!tendra; text; !this-name; token; type; type-cap; !typeof;
un-known; unassert; undef; unify; union-cap; unmatched; unpostpone;
unreachable; !unused; use; value; variable; variety-cap; !va-args;
volatile-t; !vtable; warning; weak; writeable; !zzzz;
/* Miscellaneous symbols */
!array-op; !builtin-file; !builtin-line; !close-template; !cond-op;
!delete-full; !delete-array; !delete-array-full; !func-op; !hash-op;
!hash-hash-op; !inset-start; !inset-end; !macro-arg; !new-full;
!new-array; !new-array-full; !open-init; !open-template; !zzzzzz;
/*
* ALTERNATIVE REPRESENTATIONS
*
* The ISO keywords and digraphs will have been replaced by their primary
* representations by this stage. These rules are effectively identities
* for these alternatives. Don't try removing them - SID gets very
* confused.
*/
%productions%
close-brace = { close-brace-1; };
open-brace = { open-brace-1; };
hash = { hash-1; };
or = { or-1; };
ellipsis-aux = { ellipsis; || ellipsis-exp; };
/*
* IDENTIFIERS
*
* The identifier terminal is exclusive - it does not include those
* identifiers which are actually type and namespace names. This rule
* gives all identifiers and sets the appropriate identifier type.
*/
any-identifier: () -> (id: IDENTIFIER) = {
id = identifier;
|| id = type-name;
|| id = namespace-name;
|| id = statement-name;
};
/*
* LITERAL EXPRESSIONS
*
* These rules describe the literal expressions. These are the integer
* and floating point literals, the character and string literals, plus
* the boolean literals true and false. Concatenation of adjacent string
* literals has already been performed.
*/
integer-literal: () -> (e: EXP) = {
e = integer-exp;
};
character-literal: () -> (e: EXP) = {
e = char-exp;
|| e = wchar-exp;
};
string-literal: () -> (e: EXP) = {
e = string-exp;
|| e = wstring-exp;
};
/*
* PROCEDURE TOKEN SYNTAX
*
* These rules describe the parameter syntax for procedure tokens.
*/
: () -> (:TYPE);
: () -> (:TYPE);
: () -> (:TYPE);
: () -> (:LIST-ID);
: (:IDENTIFIER, :LIST-ID) -> (:LIST-ID);
: (:TOKEN, :BOOL, :IDENTIFIER) -> (:IDENTIFIER);
: (:IDENTIFIER, :LIST-ID) -> (:IDENTIFIER);
: (:IDENTIFIER, :LIST-ID) -> (:IDENTIFIER);
: (:TYPE, :LIST-ID) -> (:IDENTIFIER);
: (:TYPE, :IDENTIFIER, :LIST-ID) -> (:IDENTIFIER);
: (:IDENTIFIER, :LIST-ID) -> (:IDENTIFIER);
: () -> (:IDENTIFIER);
: () -> (:BOOL);
: () -> (:BOOL);
: () -> ();
token-introduction: () -> (:TOKEN);
tag-opt: () -> (t: BOOL) = {
tag-cap; t = ;
|| t = ;
};
bound-tok-param: () -> (id: IDENTIFIER) = {
tok = token-introduction;
t = tag-opt; tid = any-identifier;
id = (tok, t, tid);
};
bound-tok-pars: () -> (p: LIST-ID) = {
id = bound-tok-param;
{
comma; q = bound-tok-pars;
|| comma; ; q = ;
|| q = ;
};
p = (id, q);
};
prog-tok-param: (r: LIST-ID) -> (id: IDENTIFIER) = {
exp-cap; tid = any-identifier;
id = (tid, r);
||
stmt-cap; tid = any-identifier;
id = (tid, r);
||
type-cap; t = ;
id = (t, r);
||
member-cap;
t = ; colon; tid = any-identifier;
id = (t, tid, r);
||
proc-cap; tid = any-identifier;
id = (tid, r);
};
prog-tok-pars: (r: LIST-ID) -> (p: LIST-ID) = {
a = prog-tok-param (r);
{
comma; q = prog-tok-pars (r);
|| comma; ; q = ;
|| q = ;
};
p = (a, q);
};
simple-tok-param: () -> (id: IDENTIFIER) = {
tok = token-introduction;
t = tag-opt;
{
tid = any-identifier;
|| tid = ;
};
id = (tok, t, tid);
};
simple-tok-pars: () -> (p: LIST-ID) = {
id = simple-tok-param;
{
comma; q = simple-tok-pars;
|| comma; ; q = ;
|| q = ;
};
p = (id, q);
};
/*
* TOKEN SYNTAX
*
* These rules describe the '#pragma token' syntax.
*/
: () -> ();
: () -> ();
: () -> ();
: () -> (:TOKEN);
: () -> (:TOKEN);
: () -> (:TOKEN);
: () -> (:TOKEN);
: () -> (:TOKEN);
: () -> (:TOKEN);
: () -> (:TOKEN);
: () -> (:TOKEN);
: () -> (:TOKEN);
: () -> (:TOKEN);
: () -> (:TOKEN);
: () -> (:TOKEN);
: () -> (:TOKEN);
: (:BOOL, :BOOL, :TYPE) -> (:TOKEN);
: (:ACCESS, :TYPE, :TYPE) -> (:TOKEN);
: (:TYPE) -> (:TOKEN);
: () -> (:TOKEN);
: (:TOKEN, :LIST-ID) -> (:TOKEN);
: (:TOKEN, :LIST-ID, :LIST-ID) -> (:TOKEN);
: (:TOKEN, :TOKEN) -> (:TOKEN);
: (:TOKEN, :BOOL, :IDENTIFIER, :IDENTIFIER) -> ();
: () -> (:BOOL);
: () -> (:IDENTIFIER);
: () -> (:ACCESS);
: () -> (:ACCESS);
: () -> (:ACCESS);
exp-storage: () -> (b: BOOL, c: BOOL) = {
lvalue; b = ; c = ;
|| rvalue; b = ; c = ;
|| const; b = ; c = ;
|| b = ; c = ;
};
access-specifier-opt: () -> (a: ACCESS) = {
private; a = ;
|| protected; a = ;
|| public; a = ;
|| a = ;
};
token-introduction: () -> (tok: TOKEN) = {
nat-cap;
tok = ;
||
int-cap;
tok = ;
||
stmt-cap;
tok = ;
||
type-cap;
tok = ;
||
variety-cap;
tok = ;
||
variety-cap; signed;
tok = ;
||
variety-cap; unsigned;
tok = ;
||
float-cap;
tok = ;
||
arith-cap;
tok = ;
||
class-cap;
tok = ;
||
scalar-cap;
tok = ;
||
struct-cap;
tok = ;
||
union-cap;
tok = ;
||
exp-cap; (b, c) = exp-storage; colon;
t = ; colon;
tok = (b, c, t);
||
member-cap; a = access-specifier-opt;
t = ; colon; s = ; colon;
tok = (a, t, s);
||
func-cap; t = ; colon;
tok = (t);
||
proc-cap; open-brace;
a = ;
{
p0 = bound-tok-pars;
|| p0 = ;
};
p = p0;
or;
{
q0 = prog-tok-pars (p);
|| q0 = ;
};
q = q0;
close-brace;
b = (a, p, q);
r = token-introduction;
tok = (b, r);
||
proc-cap; open-round;
a = ;
{
p = simple-tok-pars;
|| p = ;
};
close-round;
b = (a, p);
r = token-introduction;
tok = (b, r);
};
token-rule: () -> () = {
token; tok = token-introduction;
;
{
t = tag-opt; ; a = any-identifier;
||
? = ;
a = ; t = ;
};
hash; ;
{
b = any-identifier;
|| minus; b = ;
|| b = a;
};
(tok, t, a, b);
};
/*
* TOKEN INTERFACE LISTS
*
* These rules are concerned with the '#pragma interface' statements.
*/
: (:IDENTIFIER) -> (:IDENTIFIER);
: (:IDENTIFIER) -> (:IDENTIFIER);
: (:IDENTIFIER, :IDENTIFIER) -> (:IDENTIFIER);
: (:IDENTIFIER) -> (:IDENTIFIER);
: (:IDENTIFIER, :LEX) -> ();
: () -> (:LEX);
: () -> (:LEX);
: () -> (:LEX);
: () -> (:LEX);
: () -> (:LEX);
token-id: () -> (id: IDENTIFIER) = {
nm = any-identifier;
id = (nm);
||
tag-cap; ; nm = any-identifier;
id = (nm);
||
? = ;
nm = ;
id = (nm);
||
nm = token-id; dot; ; mem = any-identifier;
id = (nm, mem);
||
hash; ; nm = any-identifier;
id = (nm);
};
token-id-list: (i: LEX) -> () = {
id = token-id;
(id, i);
;
{
token-id-list (i);
|| $;
};
};
interface-command: () -> (i: LEX) = {
define; i = ;
|| no-def; i = ;
|| reject; i = ;
|| interface; i = ;
|| undef; token; i = ;
};
interface-rule: () -> () = {
i = interface-command;
;
{
token-id-list (i);
|| $;
};
};
/*
* TOKEN DEFINITION PRAGMAS
*
* These rules are concerned with those '#pragma' statements which are
* concerned with token definitions.
*/
: () -> ();
: () -> ();
: (:TYPE, :IDENTIFIER) -> ();
tokdef-rule: () -> () = {
;
member; definition;
t = ; colon; id = any-identifier;
;
(t, id);
};
/*
* IDENTIFIER PRAGMAS
*
* These rules are concerned with those '#pragma' statements which are
* concerned with special identifiers.
*/
: () -> ();
: () -> ();
: () -> ();
: (:IDENTIFIER) -> ();
: (:IDENTIFIER) -> ();
: (:IDENTIFIER, :LEX) -> ();
: (:IDENTIFIER) -> ();
: () -> ();
: (:IDENTIFIER) -> ();
: () -> (:LEX);
: () -> (:LEX);
conversion-list: () -> () = {
id = any-identifier;
(id);
conversion-list;
||
$;
};
postpone-list: (a: LEX) -> () = {
id = any-identifier;
(id, a);
postpone-list (a);
||
$;
};
preserve-list: () -> () = {
id = any-identifier;
(id);
preserve-list;
||
$;
};
suspend-list: () -> () = {
id = any-identifier;
(id);
suspend-list;
||
$;
};
identifier-rule: () -> () = {
accept; conversion; ; conversion-list;
||
conversion; ; conversion-list; allow;
||
initialization; ; id = any-identifier; allow;
(id);
||
postpone; ;
a = ; postpone-list (a);
||
preserve; ; preserve-list;
||
preserve; star;
;
||
suspend; static; ; suspend-list;
||
unpostpone; ;
a = ; postpone-list (a);
};
/*
* ERROR STATES
*
* These give the various error states which may be associated with an
* option.
*/
: () -> (:STATE);
: () -> (:STATE);
: () -> (:STATE);
: () -> (:NUMBER);
: () -> (:NUMBER);
: () -> (:NUMBER);
error-state: () -> (e: STATE) = {
on; e = ;
|| off; e = ;
|| warning; e = ;
};
allow-state: () -> (e: STATE) = {
allow; e = ;
|| disallow; e = ;
|| warning; e = ;
};
option-state: () -> (e: STATE) = {
on; e = ;
|| off; e = ;
|| allow; e = ;
|| disallow; e = ;
|| warning; e = ;
};
warning-opt: () -> (e: STATE) = {
warning; e = ;
|| e = ;
};
error-severity: () -> (e: NUMBER) = {
on; e = ;
|| off; e = ;
|| allow; e = ;
|| disallow; e = ;
|| warning; e = ;
};
/*
* INTEGER LITERAL PRAGMAS
*
* These rules are concerned with those '#pragma' statements which are
* used to specify integer literal types.
*/
: () -> (:NUMBER);
: () -> (:NUMBER);
: () -> (:NUMBER);
: () -> (:NUMBER);
: () -> (:NUMBER);
: () -> (:NUMBER);
: () -> (:NUMBER);
: () -> (:NUMBER);
: () -> (:NUMBER);
: () -> ();
: (:NUMBER, :NUMBER) -> ();
: (:TYPE) -> ();
: (:IDENTIFIER, :STATE) -> ();
: (:STATE) -> ();
: () -> ();
: (:EXP) -> ();
: () -> ();
literal-base: () -> (b: NUMBER) = {
octal; b = ;
|| decimal; b = ;
|| hexadecimal; b = ;
};
literal-suffix: () -> (s: NUMBER) = {
s = ;
|| unsigned; s = ;
|| long; s = ;
|| unsigned; long; s = ;
|| long; long; s = ;
|| unsigned; long; long; s = ;
};
literal-item: () -> () = {
colon; t = ;
(t);
||
star; ;
{
a = allow-state;
|| a = ;
};
colon; ; id = any-identifier;
(id, a);
||
star; star; ;
{
a = allow-state;
|| a = ;
};
colon;
(a);
};
literal-item-list: () -> () = {
e = integer-literal; (e);
literal-item; or; literal-item-list;
||
question; ;
literal-item; or; literal-item-list;
||
star; ;
literal-item;
};
literal-rule: () -> () = {
integer; lit;
;
b = literal-base; s = literal-suffix;
(b, s);
;
literal-item-list;
};
/*
* KEYWORD PRAGMAS
*
* These rules are concerned with those '#pragma' statements which are
* used to introduce new keywords.
*/
: () -> (:LEX);
: () -> (:LEX);
: () -> (:LEX);
: () -> (:LEX);
: () -> (:LEX);
: () -> (:LEX);
: () -> (:LEX);
: () -> (:LEX);
: () -> (:LEX);
: () -> (:LEX);
: () -> (:LEX);