Blame | Last modification | View Log | RSS feed
/*
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.
*/
/*
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 ;
/* 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 ; 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 ; 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 ;
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.
*/
<parse_type> : () -> ( :TYPE ) ;
<parse_mem_type> : () -> ( :TYPE ) ;
<parse_func_type> : () -> ( :TYPE ) ;
<list_id_null> : () -> ( :LIST-ID ) ;
<list_id_cons> : ( :IDENTIFIER, :LIST-ID ) -> ( :LIST-ID ) ;
<token_param> : ( :TOKEN, :BOOL, :IDENTIFIER ) -> ( :IDENTIFIER ) ;
<token_exp_par> : ( :IDENTIFIER, :LIST-ID ) -> ( :IDENTIFIER ) ;
<token_stmt_par> : ( :IDENTIFIER, :LIST-ID ) -> ( :IDENTIFIER ) ;
<token_type_par> : ( :TYPE, :LIST-ID ) -> ( :IDENTIFIER ) ;
<token_member_par> : ( :TYPE, :IDENTIFIER, :LIST-ID ) -> ( :IDENTIFIER ) ;
<token_proc_par> : ( :IDENTIFIER, :LIST-ID ) -> ( :IDENTIFIER ) ;
<id_anon> : () -> ( :IDENTIFIER ) ;
<bool_true> : () -> ( :BOOL ) ;
<bool_false> : () -> ( :BOOL ) ;
<error_comma> : () -> () ;
token-introduction : () -> ( :TOKEN ) ;
tag-opt : () -> ( t : BOOL ) = {
tag-cap ; t = <bool_true> ;
|| t = <bool_false> ;
} ;
bound-tok-param : () -> ( id : IDENTIFIER ) = {
tok = token-introduction ;
t = tag-opt ; tid = any-identifier ;
id = <token_param> ( tok, t, tid ) ;
} ;
bound-tok-pars : () -> ( p : LIST-ID ) = {
id = bound-tok-param ;
{
comma ; q = bound-tok-pars ;
|| comma ; <error_comma> ; q = <list_id_null> ;
|| q = <list_id_null> ;
} ;
p = <list_id_cons> ( id, q ) ;
} ;
prog-tok-param : ( r : LIST-ID ) -> ( id : IDENTIFIER ) = {
exp-cap ; tid = any-identifier ;
id = <token_exp_par> ( tid, r ) ;
||
stmt-cap ; tid = any-identifier ;
id = <token_stmt_par> ( tid, r ) ;
||
type-cap ; t = <parse_type> ;
id = <token_type_par> ( t, r ) ;
||
member-cap ;
t = <parse_type> ; colon ; tid = any-identifier ;
id = <token_member_par> ( t, tid, r ) ;
||
proc-cap ; tid = any-identifier ;
id = <token_proc_par> ( tid, r ) ;
} ;
prog-tok-pars : ( r : LIST-ID ) -> ( p : LIST-ID ) = {
a = prog-tok-param ( r ) ;
{
comma ; q = prog-tok-pars ( r ) ;
|| comma ; <error_comma> ; q = <list_id_null> ;
|| q = <list_id_null> ;
} ;
p = <list_id_cons> ( a, q ) ;
} ;
simple-tok-param : () -> ( id : IDENTIFIER ) = {
tok = token-introduction ;
t = tag-opt ;
{
tid = any-identifier ;
|| tid = <id_anon> ;
} ;
id = <token_param> ( tok, t, tid ) ;
} ;
simple-tok-pars : () -> ( p : LIST-ID ) = {
id = simple-tok-param ;
{
comma ; q = simple-tok-pars ;
|| comma ; <error_comma> ; q = <list_id_null> ;
|| q = <list_id_null> ;
} ;
p = <list_id_cons> ( id, q ) ;
} ;
/*
TOKEN SYNTAX
These rules describe the '#pragma token' syntax.
*/
<rescan_id> : () -> () ;
<rescan_keyword> : () -> () ;
<rescan_tag_line> : () -> () ;
<token_nat> : () -> ( :TOKEN ) ;
<token_snat> : () -> ( :TOKEN ) ;
<token_stmt> : () -> ( :TOKEN ) ;
<token_type> : () -> ( :TOKEN ) ;
<token_variety> : () -> ( :TOKEN ) ;
<token_signed> : () -> ( :TOKEN ) ;
<token_unsigned> : () -> ( :TOKEN ) ;
<token_float> : () -> ( :TOKEN ) ;
<token_arith> : () -> ( :TOKEN ) ;
<token_class> : () -> ( :TOKEN ) ;
<token_scalar> : () -> ( :TOKEN ) ;
<token_struct> : () -> ( :TOKEN ) ;
<token_union> : () -> ( :TOKEN ) ;
<token_exp> : ( :BOOL, :BOOL, :TYPE ) -> ( :TOKEN ) ;
<token_member> : ( :ACCESS, :TYPE, :TYPE ) -> ( :TOKEN ) ;
<token_func> : ( :TYPE ) -> ( :TOKEN ) ;
<token_proc_begin> : () -> ( :TOKEN ) ;
<token_proc_simple> : ( :TOKEN, :LIST-ID ) -> ( :TOKEN ) ;
<token_proc_complex> : ( :TOKEN, :LIST-ID, :LIST-ID ) -> ( :TOKEN ) ;
<token_proc_end> : ( :TOKEN, :TOKEN ) -> ( :TOKEN ) ;
<token_decl> : ( :TOKEN, :BOOL, :IDENTIFIER, :IDENTIFIER ) -> () ;
<is_operator> : () -> ( :BOOL ) ;
<parse_operator> : () -> ( :IDENTIFIER ) ;
<access_private> : () -> ( :ACCESS ) ;
<access_protected> : () -> ( :ACCESS ) ;
<access_public> : () -> ( :ACCESS ) ;
exp-storage : () -> ( b : BOOL, c : BOOL ) = {
lvalue ; b = <bool_true> ; c = <bool_false> ;
|| rvalue ; b = <bool_false> ; c = <bool_false> ;
|| const ; b = <bool_false> ; c = <bool_true> ;
|| b = <bool_false> ; c = <bool_false> ;
} ;
access-specifier-opt : () -> ( a : ACCESS ) = {
private ; a = <access_private> ;
|| protected ; a = <access_protected> ;
|| public ; a = <access_public> ;
|| a = <access_public> ;
} ;
token-introduction : () -> ( tok : TOKEN ) = {
nat-cap ;
tok = <token_nat> ;
||
int-cap ;
tok = <token_snat> ;
||
stmt-cap ;
tok = <token_stmt> ;
||
type-cap ;
tok = <token_type> ;
||
variety-cap ;
tok = <token_variety> ;
||
variety-cap ; signed ;
tok = <token_signed> ;
||
variety-cap ; unsigned ;
tok = <token_unsigned> ;
||
float-cap ;
tok = <token_float> ;
||
arith-cap ;
tok = <token_arith> ;
||
class-cap ;
tok = <token_class> ;
||
scalar-cap ;
tok = <token_scalar> ;
||
struct-cap ;
tok = <token_struct> ;
||
union-cap ;
tok = <token_union> ;
||
exp-cap ; ( b, c ) = exp-storage ; colon ;
t = <parse_type> ; colon ;
tok = <token_exp> ( b, c, t ) ;
||
member-cap ; a = access-specifier-opt ;
t = <parse_mem_type> ; colon ; s = <parse_type> ; colon ;
tok = <token_member> ( a, t, s ) ;
||
func-cap ; t = <parse_func_type> ; colon ;
tok = <token_func> ( t ) ;
||
proc-cap ; open-brace ;
a = <token_proc_begin> ;
{
p0 = bound-tok-pars ;
|| p0 = <list_id_null> ;
} ;
p = p0 ;
or ;
{
q0 = prog-tok-pars ( p ) ;
|| q0 = <list_id_null> ;
} ;
q = q0 ;
close-brace ;
b = <token_proc_complex> ( a, p, q ) ;
r = token-introduction ;
tok = <token_proc_end> ( b, r ) ;
||
proc-cap ; open-round ;
a = <token_proc_begin> ;
{
p = simple-tok-pars ;
|| p = <list_id_null> ;
} ;
close-round ;
b = <token_proc_simple> ( a, p ) ;
r = token-introduction ;
tok = <token_proc_end> ( b, r ) ;
} ;
token-rule : () -> () = {
token ; tok = token-introduction ;
<rescan_tag_line> ;
{
t = tag-opt ; <rescan_id> ; a = any-identifier ;
||
? = <is_operator> ;
a = <parse_operator> ; t = <bool_false> ;
} ;
hash ; <rescan_id> ;
{
b = any-identifier ;
|| minus ; b = <id_anon> ;
|| b = a ;
} ;
<token_decl> ( tok, t, a, b ) ;
} ;
/*
TOKEN INTERFACE LISTS
These rules are concerned with the '#pragma interface' statements.
*/
<token_name> : ( :IDENTIFIER ) -> ( :IDENTIFIER ) ;
<token_tag> : ( :IDENTIFIER ) -> ( :IDENTIFIER ) ;
<token_selector> : ( :IDENTIFIER, :IDENTIFIER ) -> ( :IDENTIFIER ) ;
<token_extern> : ( :IDENTIFIER ) -> ( :IDENTIFIER ) ;
<token_interface> : ( :IDENTIFIER, :LEX ) -> () ;
<interface_define> : () -> ( :LEX ) ;
<interface_no_def> : () -> ( :LEX ) ;
<interface_ignore> : () -> ( :LEX ) ;
<interface_crt> : () -> ( :LEX ) ;
<interface_undef> : () -> ( :LEX ) ;
token-id : () -> ( id : IDENTIFIER ) = {
nm = any-identifier ;
id = <token_name> ( nm ) ;
||
tag-cap ; <rescan_id> ; nm = any-identifier ;
id = <token_tag> ( nm ) ;
||
? = <is_operator> ;
nm = <parse_operator> ;
id = <token_name> ( nm ) ;
||
nm = token-id ; dot ; <rescan_id> ; mem = any-identifier ;
id = <token_selector> ( nm, mem ) ;
||
hash ; <rescan_id> ; nm = any-identifier ;
id = <token_extern> ( nm ) ;
} ;
token-id-list : ( i : LEX ) -> () = {
id = token-id ;
<token_interface> ( id, i ) ;
<rescan_tag_line> ;
{
token-id-list ( i ) ;
|| $ ;
} ;
} ;
interface-command : () -> ( i : LEX ) = {
define ; i = <interface_define> ;
|| no-def ; i = <interface_no_def> ;
|| reject ; i = <interface_ignore> ;
|| interface ; i = <interface_crt> ;
|| undef ; token ; i = <interface_undef> ;
} ;
interface-rule : () -> () = {
i = interface-command ;
<rescan_tag_line> ;
{
token-id-list ( i ) ;
|| $ ;
} ;
} ;
/*
TOKEN DEFINITION PRAGMAS
These rules are concerned with those '#pragma' statements which are
concerned with token definitions.
*/
<tokdef_start> : () -> () ;
<tokdef_end> : () -> () ;
<token_member_def> : ( :TYPE, :IDENTIFIER ) -> () ;
tokdef-rule : () -> () = {
<tokdef_start> ;
member ; definition ;
t = <parse_type> ; colon ; id = any-identifier ;
<tokdef_end> ;
<token_member_def> ( t, id ) ;
} ;
/*
IDENTIFIER PRAGMAS
These rules are concerned with those '#pragma' statements which are
concerned with special identifiers.
*/
<rescan_line> : () -> () ;
<rescan_allow_line> : () -> () ;
<rescan_as_line> : () -> () ;
<id_conv> : ( :IDENTIFIER ) -> () ;
<id_init> : ( :IDENTIFIER ) -> () ;
<id_postpone> : ( :IDENTIFIER, :LEX ) -> () ;
<id_preserve> : ( :IDENTIFIER ) -> () ;
<id_preserve_all> : () -> () ;
<id_susp> : ( :IDENTIFIER ) -> () ;
<lex_postpone> : () -> ( :LEX ) ;
<lex_unpostpone> : () -> ( :LEX ) ;
conversion-list : () -> () = {
id = any-identifier ;
<id_conv> ( id ) ;
conversion-list ;
||
$ ;
} ;
postpone-list : ( a : LEX ) -> () = {
id = any-identifier ;
<id_postpone> ( id, a ) ;
postpone-list ( a ) ;
||
$ ;
} ;
preserve-list : () -> () = {
id = any-identifier ;
<id_preserve> ( id ) ;
preserve-list ;
||
$ ;
} ;
suspend-list : () -> () = {
id = any-identifier ;
<id_susp> ( id ) ;
suspend-list ;
||
$ ;
} ;
identifier-rule : () -> () = {
accept ; conversion ; <rescan_line> ; conversion-list ;
||
conversion ; <rescan_allow_line> ; conversion-list ; allow ;
||
initialization ; <rescan_id> ; id = any-identifier ; allow ;
<id_init> ( id ) ;
||
postpone ; <rescan_line> ;
a = <lex_postpone> ; postpone-list ( a ) ;
||
preserve ; <rescan_line> ; preserve-list ;
||
preserve ; star ;
<id_preserve_all> ;
||
suspend ; static ; <rescan_line> ; suspend-list ;
||
unpostpone ; <rescan_line> ;
a = <lex_unpostpone> ; postpone-list ( a ) ;
} ;
/*
ERROR STATES
These give the various error states which may be associated with an
option.
*/
<error_on> : () -> ( :STATE ) ;
<error_off> : () -> ( :STATE ) ;
<error_warning> : () -> ( :STATE ) ;
<opt_on> : () -> ( :NUMBER ) ;
<opt_off> : () -> ( :NUMBER ) ;
<opt_warning> : () -> ( :NUMBER ) ;
error-state : () -> ( e : STATE ) = {
on ; e = <error_on> ;
|| off ; e = <error_off> ;
|| warning ; e = <error_warning> ;
} ;
allow-state : () -> ( e : STATE ) = {
allow ; e = <error_off> ;
|| disallow ; e = <error_on> ;
|| warning ; e = <error_warning> ;
} ;
option-state : () -> ( e : STATE ) = {
on ; e = <error_on> ;
|| off ; e = <error_off> ;
|| allow ; e = <error_off> ;
|| disallow ; e = <error_on> ;
|| warning ; e = <error_warning> ;
} ;
warning-opt : () -> ( e : STATE ) = {
warning ; e = <error_warning> ;
|| e = <error_on> ;
} ;
error-severity : () -> ( e : NUMBER ) = {
on ; e = <opt_on> ;
|| off ; e = <opt_off> ;
|| allow ; e = <opt_off> ;
|| disallow ; e = <opt_on> ;
|| warning ; e = <opt_warning> ;
} ;
/*
INTEGER LITERAL PRAGMAS
These rules are concerned with those '#pragma' statements which are
used to specify integer literal types.
*/
<base_octal> : () -> ( :NUMBER ) ;
<base_decimal> : () -> ( :NUMBER ) ;
<base_hexadecimal> : () -> ( :NUMBER ) ;
<suffix_none> : () -> ( :NUMBER ) ;
<suffix_u> : () -> ( :NUMBER ) ;
<suffix_l> : () -> ( :NUMBER ) ;
<suffix_ul> : () -> ( :NUMBER ) ;
<suffix_ll> : () -> ( :NUMBER ) ;
<suffix_ull> : () -> ( :NUMBER ) ;
<literal_set> : () -> () ;
<literal_begin> : ( :NUMBER, :NUMBER ) -> () ;
<literal_type> : ( :TYPE ) -> () ;
<literal_token> : ( :IDENTIFIER, :STATE ) -> () ;
<literal_star> : ( :STATE ) -> () ;
<literal_infinity> : () -> () ;
<literal_integer> : ( :EXP ) -> () ;
<literal_range> : () -> () ;
literal-base : () -> ( b : NUMBER ) = {
octal ; b = <base_octal> ;
|| decimal ; b = <base_decimal> ;
|| hexadecimal ; b = <base_hexadecimal> ;
} ;
literal-suffix : () -> ( s : NUMBER ) = {
s = <suffix_none> ;
|| unsigned ; s = <suffix_u> ;
|| long ; s = <suffix_l> ;
|| unsigned ; long ; s = <suffix_ul> ;
|| long ; long ; s = <suffix_ll> ;
|| unsigned ; long ; long ; s = <suffix_ull> ;
} ;
literal-item : () -> () = {
colon ; t = <parse_type> ;
<literal_type> ( t ) ;
||
star ; <rescan_keyword> ;
{
a = allow-state ;
|| a = <error_off> ;
} ;
colon ; <rescan_id> ; id = any-identifier ;
<literal_token> ( id, a ) ;
||
star ; star ; <rescan_keyword> ;
{
a = allow-state ;
|| a = <error_on> ;
} ;
colon ;
<literal_star> ( a ) ;
} ;
literal-item-list : () -> () = {
e = integer-literal ; <literal_integer> ( e ) ;
literal-item ; or ; literal-item-list ;
||
question ; <literal_range> ;
literal-item ; or ; literal-item-list ;
||
star ; <literal_infinity> ;
literal-item ;
} ;
literal-rule : () -> () = {
integer ; lit ;
<literal_set> ;
b = literal-base ; s = literal-suffix ;
<literal_begin> ( b, s ) ;
<rescan_line> ;
literal-item-list ;
} ;
/*
KEYWORD PRAGMAS
These rules are concerned with those '#pragma' statements which are
used to introduce new keywords.
*/
<lex_asm> : () -> ( :LEX ) ;
<lex_discard> : () -> ( :LEX ) ;
<lex_exhaustive> : () -> ( :LEX ) ;
<lex_fall> : () -> ( :LEX ) ;
<lex_inline> : () -> ( :LEX ) ;
<lex_reachable> : () -> ( :LEX ) ;
<lex_representation> : () -> ( :LEX ) ;
<lex_set> : () -> ( :LEX ) ;
<lex_unreachable> : () -> ( :LEX ) ;
<lex_unused> : () -> ( :LEX ) ;
<lex_weak> : () -> ( :LEX ) ;
<lex_symbol> : () -> ( :LEX ) ;
<keyword_spec> : ( :IDENTIFIER ) -> ( :LEX ) ;
<keyword_define> : ( :IDENTIFIER, :LEX ) -> () ;
<keyword_undef> : ( :IDENTIFIER ) -> () ;
keyword-id : () -> ( id : IDENTIFIER ) = {
keyword ; <rescan_id> ; id = any-identifier ;
} ;
keyword-spec : () -> ( t : LEX ) = {
asm ; t = <lex_asm> ;
|| discard ; value ; t = <lex_discard> ;
|| discard ; variable ; t = <lex_unused> ;
|| exhaustive ; t = <lex_exhaustive> ;
|| fall ; into ; case ; t = <lex_fall> ;
|| inline ; t = <lex_inline> ;
|| set ; t = <lex_set> ;
|| set ; reachable ; t = <lex_reachable> ;
|| set ; unreachable ; t = <lex_unreachable> ;
|| type ; representation ; t = <lex_representation> ;
|| weak ; t = <lex_weak> ;
|| id = keyword-id ; t = <keyword_spec> ( id ) ;
|| operator ; t = <lex_symbol> ; plus ;
} ;
keyword-rule : () -> () = {
id = keyword-id ; for ; t = keyword-spec ;
<keyword_define> ( id, t ) ;
||
undef ; id = keyword-id ;
<keyword_undef> ( id ) ;
} ;
/*
TYPE PRAGMAS
These rules are concerned with those '#pragma' statements which are
used to introduce special types.
*/
<type_argument> : ( :TYPE, :TYPE ) -> () ;
<type_ellipsis> : ( :TYPE ) -> () ;
<type_char_sign> : ( :BTYPE ) -> () ;
<type_char_lit> : ( :TYPE ) -> () ;
<type_long_long> : ( :BOOL ) -> () ;
<type_string_lit> : ( :CV ) -> () ;
<type_compatible> : ( :TYPE, :TYPE, :STATE ) -> () ;
<type_compute> : ( :IDENTIFIER ) -> () ;
<type_promote> : ( :TYPE, :TYPE ) -> () ;
<type_builtin> : ( :BTYPE, :TYPE ) -> () ;
<type_special> : ( :IDENTIFIER, :TYPE ) -> () ;
<type_bottom> : () -> ( :TYPE ) ;
<type_printf> : () -> ( :TYPE ) ;
<type_scanf> : () -> ( :TYPE ) ;
<type_wprintf> : () -> ( :TYPE ) ;
<type_wscanf> : () -> ( :TYPE ) ;
<type_ptrdiff_t> : () -> ( :TYPE ) ;
<type_size_t> : () -> ( :TYPE ) ;
<type_wchar_t> : () -> ( :TYPE ) ;
<nspace_std> : ( :IDENTIFIER ) -> () ;
<id_none> : () -> ( :IDENTIFIER ) ;
<declarator_start> : () -> () ;
<btype_none> : () -> ( :BTYPE ) ;
<btype_signed> : () -> ( :BTYPE ) ;
<btype_unsigned> : () -> ( :BTYPE ) ;
<btype_ptrdiff_t> : () -> ( :BTYPE ) ;
<btype_size_t> : () -> ( :BTYPE ) ;
<btype_wchar_t> : () -> ( :BTYPE ) ;
<cv_none> : () -> ( :CV ) ;
<cv_const> : () -> ( :CV ) ;
type-spec : () -> () = {
argument ; <rescan_as_line> ;
t = <parse_type> ; as ; s = <parse_type> ;
<type_argument> ( t, s ) ;
||
argument ; <rescan_as_line> ;
t = <parse_type> ; as ; ellipsis-aux ;
<type_ellipsis> ( t ) ;
||
bottom ; <rescan_id> ;
<declarator_start> ;
id = any-identifier ;
t = <type_bottom> ;
<type_special> ( id, t ) ;
||
character ;
{
signed ; bt = <btype_signed> ;
|| unsigned ; bt = <btype_unsigned> ;
|| either ; bt = <btype_none> ;
} ;
<type_char_sign> ( bt ) ;
||
compatible ; type ; colon ; <rescan_line> ;
t = <parse_type> ; eq ; s = <parse_type> ; colon ;
<rescan_keyword> ; e = allow-state ;
<type_compatible> ( t, s, e ) ;
||
compute ; promote ; <rescan_id> ;
id = any-identifier ;
<type_compute> ( id ) ;
||
promoted ; <rescan_line> ;
t = <parse_type> ; colon ; s = <parse_type> ;
<type_promote> ( t, s ) ;
||
set ;
{
ptrdiff-t ; bt = <btype_ptrdiff_t> ;
|| size-t ; bt = <btype_size_t> ;
|| wchar-t ; bt = <btype_wchar_t> ;
} ;
colon ; <rescan_line> ; t = <parse_type> ;
<type_builtin> ( bt, t ) ;
||
set ; character ; lit ;
colon ; <rescan_line> ; t = <parse_type> ;
<type_char_lit> ( t ) ;
||
set ; longlong ; type ; colon ; long ;
{
long ; b = <bool_true> ;
|| b = <bool_false> ;
} ;
<type_long_long> ( b ) ;
||
set ; string ; lit ; colon ;
{
cv = <cv_const> ;
|| no ; cv = <cv_none> ;
} ;
const ;
<type_string_lit> ( cv ) ;
||
set ; std ; namespace ; colon ; <rescan_id> ;
{
id = any-identifier ;
|| colon-colon ; id = <id_none> ;
} ;
<nspace_std> ( id ) ;
||
type ; <rescan_id> ;
<declarator_start> ;
id = any-identifier ; for ;
{
bottom ; t = <type_bottom> ;
|| ellipsis-aux ; printf ; t = <type_printf> ;
|| ellipsis-aux ; scanf ; t = <type_scanf> ;
|| ellipsis-aux ; wchar-t ; printf ; t = <type_wprintf> ;
|| ellipsis-aux ; wchar-t ; scanf ; t = <type_wscanf> ;
|| ptrdiff-t ; t = <type_ptrdiff_t> ;
|| size-t ; t = <type_size_t> ;
|| wchar-t ; t = <type_wchar_t> ;
} ;
<type_special> ( id, t ) ;
} ;
/*
OPTION DECLARATIONS
Each option is associated with a numerical value. These actions
gives this mapping.
*/
<opt_bitf_overflow> : () -> ( :NUMBER ) ;
<opt_bitf_type> : () -> ( :NUMBER ) ;
<opt_bool_assign> : () -> ( :NUMBER ) ;
<opt_case_fall> : () -> ( :NUMBER ) ;
<opt_cast_explicit> : () -> ( :NUMBER ) ;
<opt_comma_extra> : () -> ( :NUMBER ) ;
<opt_complete_struct> : () -> ( :NUMBER ) ;
<opt_concat_string> : () -> ( :NUMBER ) ;
<opt_cond_lvalue> : () -> ( :NUMBER ) ;
<opt_const_cond> : () -> ( :NUMBER ) ;
<opt_const_internal> : () -> ( :NUMBER ) ;
<opt_const_string> : () -> ( :NUMBER ) ;
<opt_conv> : () -> ( :NUMBER ) ;
<opt_conv_int_enum> : () -> ( :NUMBER ) ;
<opt_conv_int_int> : () -> ( :NUMBER ) ;
<opt_conv_int_int_expl> : () -> ( :NUMBER ) ;
<opt_conv_int_int_impl> : () -> ( :NUMBER ) ;
<opt_conv_int_ptr> : () -> ( :NUMBER ) ;
<opt_conv_int_ptr_expl> : () -> ( :NUMBER ) ;
<opt_conv_int_ptr_impl> : () -> ( :NUMBER ) ;
<opt_conv_ptr_func> : () -> ( :NUMBER ) ;
<opt_conv_ptr_ptr> : () -> ( :NUMBER ) ;
<opt_conv_ptr_ptr_expl> : () -> ( :NUMBER ) ;
<opt_conv_ptr_ptr_impl> : () -> ( :NUMBER ) ;
<opt_conv_ptr_ptr_void> : () -> ( :NUMBER ) ;
<opt_conv_ptr_void_ptr> : () -> ( :NUMBER ) ;
<opt_decl_cond> : () -> ( :NUMBER ) ;
<opt_decl_hide> : () -> ( :NUMBER ) ;
<opt_decl_none> : () -> ( :NUMBER ) ;
<opt_decl_struct_anon> : () -> ( :NUMBER ) ;
<opt_decl_unify> : () -> ( :NUMBER ) ;
<opt_decl_volatile> : () -> ( :NUMBER ) ;
<opt_discard> : () -> ( :NUMBER ) ;
<opt_discard_func> : () -> ( :NUMBER ) ;
<opt_discard_static> : () -> ( :NUMBER ) ;
<opt_discard_value> : () -> ( :NUMBER ) ;
<opt_dollar_ident> : () -> ( :NUMBER ) ;
<opt_dspec_none> : () -> ( :NUMBER ) ;
<opt_dspec_none_func> : () -> ( :NUMBER ) ;
<opt_ellipsis_extra> : () -> ( :NUMBER ) ;
<opt_ellipsis_ident> : () -> ( :NUMBER ) ;
<opt_empty_body> : () -> ( :NUMBER ) ;
<opt_enum_decl> : () -> ( :NUMBER ) ;
<opt_enum_switch> : () -> ( :NUMBER ) ;
<opt_eof_nline> : () -> ( :NUMBER ) ;
<opt_escape_overflow> : () -> ( :NUMBER ) ;
<opt_escape_unknown> : () -> ( :NUMBER ) ;
<opt_for_scope> : () -> ( :NUMBER ) ;
<opt_func_block> : () -> ( :NUMBER ) ;
<opt_func_impl> : () -> ( :NUMBER ) ;
<opt_func_incompat> : () -> ( :NUMBER ) ;
<opt_func_linkage> : () -> ( :NUMBER ) ;
<opt_func_proto> : () -> ( :NUMBER ) ;
<opt_func_ret_void> : () -> ( :NUMBER ) ;
<opt_func_token_undef> : () -> ( :NUMBER ) ;
<opt_func_weak> : () -> ( :NUMBER ) ;
<opt_hash_ident> : () -> ( :NUMBER ) ;
<opt_include_full> : () -> ( :NUMBER ) ;
<opt_infer_int> : () -> ( :NUMBER ) ;
<opt_infer_int_cv> : () -> ( :NUMBER ) ;
<opt_init_aggregate> : () -> ( :NUMBER ) ;
<opt_init_dynamic> : () -> ( :NUMBER ) ;
<opt_init_struct> : () -> ( :NUMBER ) ;
<opt_inline_internal> : () -> ( :NUMBER ) ;
<opt_interf_incompat> : () -> ( :NUMBER ) ;
<opt_int_operator> : () -> ( :NUMBER ) ;
<opt_int_overflow> : () -> ( :NUMBER ) ;
<opt_link_incompat> : () -> ( :NUMBER ) ;
<opt_link_internal> : () -> ( :NUMBER ) ;
<opt_link_resolve> : () -> ( :NUMBER ) ;
<opt_longlong> : () -> ( :NUMBER ) ;
<opt_macro_arg_dir> : () -> ( :NUMBER ) ;
<opt_macro_redef> : () -> ( :NUMBER ) ;
<opt_macro_weak> : () -> ( :NUMBER ) ;
<opt_member_incompat> : () -> ( :NUMBER ) ;
<opt_name_limit> : () -> ( :NUMBER ) ;
<opt_nest_comment> : () -> ( :NUMBER ) ;
<opt_overload_ambig> : () -> ( :NUMBER ) ;
<opt_overload_dep> : () -> ( :NUMBER ) ;
<opt_overload_res> : () -> ( :NUMBER ) ;
<opt_overload_strict> : () -> ( :NUMBER ) ;
<opt_param_impl> : () -> ( :NUMBER ) ;
<opt_paren> : () -> ( :NUMBER ) ;
<opt_ppdir_assert> : () -> ( :NUMBER, :NUMBER ) ;
<opt_ppdir_file> : () -> ( :NUMBER, :NUMBER ) ;
<opt_ppdir_id> : () -> ( :NUMBER ) ;
<opt_ppdir_ident> : () -> ( :NUMBER, :NUMBER ) ;
<opt_ppdir_import> : () -> ( :NUMBER, :NUMBER ) ;
<opt_ppdir_indent> : () -> ( :NUMBER ) ;
<opt_ppdir_indent_dir> : () -> ( :NUMBER ) ;
<opt_ppdir_text> : () -> ( :NUMBER ) ;
<opt_ppdir_unassert> : () -> ( :NUMBER, :NUMBER ) ;
<opt_ppdir_unknown> : () -> ( :NUMBER ) ;
<opt_ppdir_warning> : () -> ( :NUMBER, :NUMBER ) ;
<opt_ppdir_weak> : () -> ( :NUMBER, :NUMBER ) ;
<opt_pragma_unknown> : () -> ( :NUMBER ) ;
<opt_ptr_operator> : () -> ( :NUMBER ) ;
<opt_reached> : () -> ( :NUMBER ) ;
<opt_semicolon_extra> : () -> ( :NUMBER ) ;
<opt_templ_export> : () -> ( :NUMBER ) ;
<opt_this_lvalue> : () -> ( :NUMBER ) ;
<opt_throw_bad> : () -> ( :NUMBER ) ;
<opt_token_const> : () -> ( :NUMBER ) ;
<opt_token_redef> : () -> ( :NUMBER ) ;
<opt_token_undef> : () -> ( :NUMBER ) ;
<opt_type_obj_incompl> : () -> ( :NUMBER ) ;
<opt_type_qual_incompat> : () -> ( :NUMBER ) ;
<opt_type_redef> : () -> ( :NUMBER ) ;
<opt_type_tag_ignore> : () -> ( :NUMBER ) ;
<opt_unmatched> : () -> ( :NUMBER ) ;
<opt_variable> : () -> ( :NUMBER ) ;
<opt_wall> : () -> ( :NUMBER ) ;
<opt_weak> : () -> ( :NUMBER ) ;
<opt_val_cast_explicit> : () -> ( :NUMBER ) ;
<opt_val_include_depth> : () -> ( :NUMBER ) ;
<opt_val_maximum_error> : () -> ( :NUMBER ) ;
<opt_val_name_limit> : () -> ( :NUMBER ) ;
/*
ANALYSIS PRAGMAS
These rules are concerned with those '#pragma' statements which are
used to set analysis options.
*/
conversion-spec : () -> ( n : NUMBER ) = {
n = <opt_conv> ;
||
open-round ; int ; minus ; int ; close-round ;
n = <opt_conv_int_int> ;
||
open-round ; int ; minus ; int ; explicit ; close-round ;
n = <opt_conv_int_int_expl> ;
||
open-round ; int ; minus ; int ; implicit ; close-round ;
n = <opt_conv_int_int_impl> ;
||
open-round ; int ; minus ; enum ; implicit ; close-round ;
n = <opt_conv_int_enum> ;
||
open-round ; int ; minus ; pointer ; close-round ;
n = <opt_conv_int_ptr> ;
||
open-round ; int ; minus ; pointer ; explicit ; close-round ;
n = <opt_conv_int_ptr_expl> ;
||
open-round ; int ; minus ; pointer ; implicit ; close-round ;
n = <opt_conv_int_ptr_impl> ;
||
open-round ; pointer ; minus ; int ; close-round ;
n = <opt_conv_int_ptr> ;
||
open-round ; pointer ; minus ; int ; explicit ; close-round ;
n = <opt_conv_int_ptr_expl> ;
||
open-round ; pointer ; minus ; int ; implicit ; close-round ;
n = <opt_conv_int_ptr_impl> ;
||
open-round ; pointer ; minus ; pointer ; close-round ;
n = <opt_conv_ptr_ptr> ;
||
open-round ; pointer ; minus ; pointer ; explicit ; close-round ;
n = <opt_conv_ptr_ptr_expl> ;
||
open-round ; pointer ; minus ; pointer ; implicit ; close-round ;
n = <opt_conv_ptr_ptr_impl> ;
||
open-round ; void ; star ; minus ; pointer ; implicit ; close-round ;
n = <opt_conv_ptr_void_ptr> ;
||
open-round ; pointer ; minus ; void ; star ; implicit ; close-round ;
n = <opt_conv_ptr_ptr_void> ;
} ;
discard-spec : () -> ( n : NUMBER ) = {
n = <opt_discard> ;
||
open-round ; function ; return ; close-round ;
n = <opt_discard_func> ;
||
open-round ; static ; close-round ;
n = <opt_discard_static> ;
||
open-round ; value ; close-round ;
n = <opt_discard_value> ;
} ;
analysis-spec : () -> ( n : NUMBER ) = {
complete ; initialization ; analysis ;
n = <opt_init_aggregate> ;
||
complete ; struct ; div ; union ; analysis ;
n = <opt_complete_struct> ;
||
conversion ; analysis ;
n = conversion-spec ;
||
discard ; analysis ;
n = discard-spec ;
||
enum ; switch ; analysis ;
n = <opt_enum_switch> ;
||
external ; function ; linkage ;
n = <opt_func_linkage> ;
||
for ; initialization ; block ;
n = <opt_for_scope> ;
||
ignore ; struct ; div ; union ; div ; enum ; tag ;
n = <opt_type_tag_ignore> ;
||
implicit ; export ; template ;
n = <opt_templ_export> ;
||
implicit ; function ; decl ;
n = <opt_func_impl> ;
||
integer ; operator ; analysis ;
n = <opt_int_operator> ;
||
integer ; overflow ; analysis ;
n = <opt_int_overflow> ;
||
nested ; comment ; analysis ;
n = <opt_nest_comment> ;
||
operator ; precedence ; analysis ;
n = <opt_paren> ;
||
pointer ; operator ; analysis ;
n = <opt_ptr_operator> ;
||
throw ; analysis ;
n = <opt_throw_bad> ;
||
unify ; external ; linkage ;
n = <opt_decl_unify> ;
||
variable ; analysis ;
n = <opt_variable> ;
||
variable ; hiding ; analysis ;
n = <opt_decl_hide> ;
||
weak ; prototype ; analysis ;
n = <opt_weak> ;
} ;
/*
IMPLICIT INT PRAGMAS
This rule is concerned with those '#pragma' statements which are
used to set the treatment of implicit integral types.
*/
implicit-spec : () -> ( n : NUMBER ) = {
for ; external ; decl ;
n = <opt_dspec_none> ;
||
for ; function ; argument ;
n = <opt_param_impl> ;
||
for ; function ; return ;
n = <opt_dspec_none_func> ;
||
for ; const ; div ; volatile ;
n = <opt_infer_int_cv> ;
||
n = <opt_infer_int> ;
} ;
/*
CHECKING PRAGMAS
These rules are concerned with those '#pragma' statements which are
used to set checking options.
*/
check-spec : () -> ( n : NUMBER ) = {
ambiguous ; overload ; resolution ;
n = <opt_overload_ambig> ;
||
assignment ; as ; bool ;
n = <opt_bool_assign> ;
||
bitfield ; overflow ;
n = <opt_bitf_overflow> ;
||
block ; function ; static ;
n = <opt_func_block> ;
||
catch ; all ;
n = <opt_wall> ;
||
character ; escape ; overflow ;
n = <opt_escape_overflow> ;
||
compatible ; token ;
n = <opt_token_redef> ;
||
complete ; file ; includes ;
n = <opt_include_full> ;
||
conditional ; decl ;
n = <opt_decl_cond> ;
||
conditional ; lvalue ;
n = <opt_cond_lvalue> ;
||
const ; conditional ;
n = <opt_const_cond> ;
||
directive ; as ; macro ; argument ;
n = <opt_macro_arg_dir> ;
||
dollar ; as ; ident ;
n = <opt_dollar_ident> ;
||
extra ; comma ;
n = <opt_comma_extra> ;
||
extra ; ellipsis-aux ;
n = <opt_ellipsis_extra> ;
||
extra ; semicolon ;
n = <opt_semicolon_extra> ;
||
extra ; semicolon ; after ; conditional ;
n = <opt_empty_body> ;
||
extra ; bitfield ; int ; type ;
n = <opt_bitf_type> ;
||
extra ; macro ; definition ;
n = <opt_macro_redef> ;
||
extra ; type ; definition ;
n = <opt_type_redef> ;
||
fall ; into ; case ;
n = <opt_case_fall> ;
||
forward ; enum ; decl ;
n = <opt_enum_decl> ;
||
function ; pointer ; as ; pointer ;
n = <opt_conv_ptr_func> ;
||
ident ; ellipsis-aux ;
n = <opt_ellipsis_ident> ;
||
ident ; as ; ellipsis-aux ;
n = <opt_ellipsis_ident> ;
||
implicit ; int ; type ;
n = implicit-spec ;
||
implicit ; token ; definition ;
n = <opt_func_token_undef> ;
||
incompatible ; interface ; decl ;
n = <opt_interf_incompat> ;
||
incompatible ; linkage ;
n = <opt_link_incompat> ;
||
incompatible ; member ; decl ;
n = <opt_member_incompat> ;
||
incompatible ; promoted ; function ; argument ;
n = <opt_func_incompat> ;
||
incompatible ; type ; qualifier ;
n = <opt_type_qual_incompat> ;
||
incompatible ; void ; return ;
n = <opt_func_ret_void> ;
||
incomplete ; type ; as ; object ; type ;
n = <opt_type_obj_incompl> ;
||
indented ; hash ; directive ;
n = <opt_ppdir_indent> ;
||
indented ; directive ; after ; hash ;
n = <opt_ppdir_indent_dir> ;
||
initialization ; of ; struct ; div ; union ;
open-round ; auto ; close-round ;
n = <opt_init_struct> ;
||
longlong ; type ;
n = <opt_longlong> ;
||
no ; directive ; div ; nline ; after ; ident ;
n = <opt_ppdir_id> ;
||
no ; external ; decl ;
n = <opt_decl_none> ;
||
no ; ident ; after ; hash ;
n = <opt_hash_ident> ;
||
no ; nline ; after ; file ; end ;
n = <opt_eof_nline> ;
||
no ; token ; definition ;
n = <opt_token_undef> ;
||
overload ; resolution ;
n = <opt_overload_res> ;
||
prototype ;
n = <opt_func_proto> ;
||
prototype ; open-round ; weak ; close-round ;
n = <opt_func_weak> ;
||
rvalue ; token ; as ; const ;
n = <opt_token_const> ;
||
text ; after ; directive ;
n = <opt_ppdir_text> ;
||
this ; lvalue ;
n = <opt_this_lvalue> ;
||
unify ; incompatible ; string ; lit ;
n = <opt_concat_string> ;
||
un-known ; directive ;
n = <opt_ppdir_unknown> ;
||
un-known ; escape ;
n = <opt_escape_unknown> ;
||
un-known ; pragma ;
n = <opt_pragma_unknown> ;
||
un-known ; struct ; div ; union ;
n = <opt_decl_struct_anon> ;
||
unmatched ; quote ;
n = <opt_unmatched> ;
||
unreachable ; code ;
n = <opt_reached> ;
||
variable ; initialization ;
n = <opt_init_dynamic> ;
||
weak ; macro ; equality ;
n = <opt_macro_weak> ;
||
writeable ; string ; lit ;
n = <opt_const_string> ;
} ;
/*
DIRECTIVE PRAGMAS
These rules are concerned with those '#pragma' statements which are
used to switch preprocessing directives on and off.
*/
directive-spec : () -> ( n : NUMBER, m : NUMBER ) = {
assert ; ( n, m ) = <opt_ppdir_assert> ;
|| file ; ( n, m ) = <opt_ppdir_file> ;
|| ident ; ( n, m ) = <opt_ppdir_ident> ;
|| import ; ( n, m ) = <opt_ppdir_import> ;
|| include-next ; ( n, m ) = <opt_ppdir_import> ;
|| unassert ; ( n, m ) = <opt_ppdir_unassert> ;
|| warning ; ( n, m ) = <opt_ppdir_warning> ;
|| weak ; ( n, m ) = <opt_ppdir_weak> ;
} ;
directive-state : () -> ( e : STATE, i : STATE ) = {
disallow ;
e = <error_on> ;
i = <error_on> ;
||
{
open-round ; ignore ; close-round ; a = <error_on> ;
|| a = <error_off> ;
} ;
{
allow ; b = <error_off> ;
|| warning ; b = <error_warning> ;
} ;
e = b ;
i = a ;
} ;
/*
LINKAGE PRAGMAS
This rule is concerned with the '#pragma' statement used to determine
the linkage resolution to be used.
*/
linkage-descr : () -> ( i : STATE ) = {
internal ; i = <error_on> ;
|| external ; i = <error_off> ;
} ;
linkage-state : () -> ( e : STATE, i : STATE ) = {
off ;
e = <error_off> ;
i = <error_off> ;
||
open-round ;
i = linkage-descr ;
close-round ;
{
on ; b = <error_off> ;
|| warning ; b = <error_warning> ;
} ;
e = b ;
} ;
/*
COMPLETE STATE PRAGMAS
This rule is concerned with those '#pragma' statements which give
the option between complete and incomplete analysis.
*/
complete-state : () -> ( i : STATE ) = {
i = <error_on> ;
|| open-round ; complete ; close-round ; i = <error_on> ;
|| open-round ; incomplete ; close-round ; i = <error_off> ;
} ;
/*
EXPLICIT CAST PRAGMAS
These rules gives the various interpretations of explicit cast
expressions.
*/
<cast_static> : () -> ( :VALUE ) ;
<cast_reinterp> : () -> ( :VALUE ) ;
<cast_const> : () -> ( :VALUE ) ;
<cast_explicit> : () -> ( :VALUE ) ;
<cast_join> : ( :VALUE, :VALUE ) -> ( :VALUE ) ;
cast-command : () -> ( c : VALUE ) = {
static-cast ; c = <cast_static> ;
|| reinterpret-cast ; c = <cast_reinterp> ;
|| const-cast ; c = <cast_const> ;
} ;
cast-state : () -> ( c : VALUE ) = {
c = cast-command ;
||
a = cast-command ; or ; b = cast-state ;
c = <cast_join> ( a, b ) ;
} ;
/*
OPTION PRAGMAS
These rules are concerned with those '#pragma' statements which are
used to set option values.
*/
<option_number> : ( :EXP ) -> ( :NUMBER ) ;
<linkage_string> : ( :EXP ) -> ( :LINKAGE ) ;
<analysis_exp> : ( :NUMBER, :EXP ) -> () ;
<analysis_state> : ( :NUMBER, :STATE ) -> () ;
<analysis_value> : ( :NUMBER, :VALUE ) -> () ;
<analysis_linkage> : ( :LINKAGE ) -> () ;
option-number : () -> ( n : NUMBER ) = {
option ; s = string-literal ;
n = <option_number> ( s ) ;
} ;
option-rule : () -> () = {
n = option-number ; e = option-state ;
<analysis_state> ( n, e ) ;
||
n = analysis-spec ; e = error-state ;
<analysis_state> ( n, e ) ;
||
n = check-spec ; e = allow-state ;
<analysis_state> ( n, e ) ;
||
conditional ; overload ; resolution ;
i = complete-state ; e = allow-state ;
n = <opt_overload_dep> ;
m = <opt_overload_strict> ;
<analysis_state> ( n, e ) ;
<analysis_state> ( m, i ) ;
||
directive ; ( n, m ) = directive-spec ; ( e, i ) = directive-state ;
<analysis_state> ( n, e ) ;
<analysis_state> ( m, i ) ;
||
explicit ; cast ;
{
as ; c = cast-state ;
|| c = <cast_explicit> ;
} ;
e = allow-state ;
n = <opt_cast_explicit> ;
m = <opt_val_cast_explicit> ;
<analysis_state> ( n, e ) ;
<analysis_value> ( m, c ) ;
||
set ; name ; limit ;
e = integer-literal ;
i = warning-opt ;
n = <opt_val_name_limit> ;
m = <opt_name_limit> ;
<analysis_exp> ( n, e ) ;
<analysis_state> ( m, i ) ;
||
linkage ; resolution ; colon ; ( e, i ) = linkage-state ;
n = <opt_link_resolve> ;
m = <opt_link_internal> ;
<analysis_state> ( n, e ) ;
<analysis_state> ( m, i ) ;
||
external ; linkage ; e = string-literal ;
a = <linkage_string> ( e ) ;
<analysis_linkage> ( a ) ;
||
external ;
{
volatile ;
|| volatile-t ;
} ;
n = <opt_decl_volatile> ;
e = <error_on> ;
<analysis_state> ( n, e ) ;
||
inline ; linkage ; e = linkage-descr ;
n = <opt_inline_internal> ;
<analysis_state> ( n, e ) ;
||
const ; linkage ; e = linkage-descr ;
n = <opt_const_internal> ;
<analysis_state> ( n, e ) ;
||
accept ; ellipsis-aux ; identif ;
n = <opt_ellipsis_ident> ;
e = <error_off> ;
<analysis_state> ( n, e ) ;
} ;
/*
VALUE PRAGMAS
These rules are concerned with those '#pragma' statements which are
used to set compiler values.
*/
<option_value_number> : ( :EXP ) -> ( :NUMBER ) ;
option-value-number : () -> ( n : NUMBER ) = {
option ; value ; s = string-literal ;
n = <option_value_number> ( s ) ;
} ;
value-spec : () -> ( n : NUMBER ) = {
includes ; depth ;
n = <opt_val_include_depth> ;
||
set ; error ; limit ;
n = <opt_val_maximum_error> ;
} ;
value-rule : () -> () = {
n = option-value-number ; e = integer-literal ;
<analysis_exp> ( n, e ) ;
||
n = value-spec ; e = integer-literal ;
<analysis_exp> ( n, e ) ;
} ;
/*
CHARACTER PRAGMAS
These rules are concerned with those '#pragma' statements which are
used to define character set information.
*/
<char_set> : ( :EXP, :EXP ) -> () ;
<escape_set> : ( :EXP, :EXP ) -> () ;
<exp_none> : () -> ( :EXP ) ;
character-rule : () -> () = {
character ;
{
a = character-literal ;
|| a = string-literal ;
} ;
{
as ; b = character-literal ;
<char_set> ( a, b ) ;
allow ;
||
disallow ; b = <exp_none> ;
<char_set> ( a, b ) ;
} ;
||
escape ; a = character-literal ;
{
as ; b = character-literal ; allow ;
|| disallow ; b = <exp_none> ;
} ;
<escape_set> ( a, b ) ;
} ;
/*
ERROR PRAGMAS
These rules are concerned with those '#pragma' statements which are
used to define error messages.
*/
<error_number> : ( :EXP ) -> ( :NUMBER ) ;
<error_state> : ( :NUMBER, :NUMBER ) -> () ;
<error_use> : ( :NUMBER ) -> () ;
error-number : () -> ( n : NUMBER ) = {
error ; s = string-literal ;
n = <error_number> ( s ) ;
} ;
error-rule : () -> () = {
n = error-number ; e = error-severity ;
<error_state> ( n, e ) ;
||
n = error-number ; as ; e = option-number ;
<error_state> ( n, e ) ;
||
use ; n = error-number ;
<error_use> ( n ) ;
} ;
/*
SCOPE PRAGMAS
These rules are concerned with those '#pragma' statements which are
used to define checking and declaration scopes.
*/
<check_begin> : ( :IDENTIFIER ) -> () ;
<check_end> : () -> () ;
<check_directory> : ( :IDENTIFIER, :IDENTIFIER ) -> () ;
<check_use> : ( :IDENTIFIER, :STATE ) -> () ;
<decl_block_begin> : ( :IDENTIFIER ) -> () ;
<decl_block_end> : () -> () ;
scope-rule : () -> () = {
begin ; id = <id_none> ;
<check_begin> ( id ) ;
||
begin ; name ; environment ; <rescan_id> ; id = any-identifier ;
<check_begin> ( id ) ;
||
directory ; <rescan_id> ; dir = any-identifier ;
use ; environment ; <rescan_id> ; id = any-identifier ;
<check_directory> ( dir, id ) ;
||
use ; environment ; <rescan_id> ; id = any-identifier ;
{
reset ; e = allow-state ;
|| e = <error_on> ;
} ;
<check_use> ( id, e ) ;
||
end ;
<check_end> ;
||
decl ; block ; <rescan_id> ; id = any-identifier ; begin ;
<decl_block_begin> ( id ) ;
||
decl ; block ; end ;
<decl_block_end> ;
} ;
/*
PRAGMA TENDRA DIRECTIVES
These rules describe the '#pragma TenDRA' directives.
*/
<lex_none> : () -> ( :LEX ) ;
<lex_pragma> : () -> ( :LEX ) ;
<error_syntax> : () -> () ;
pragma-rule : () -> () = {
scope-rule ;
|| error-rule ;
|| keyword-rule ;
|| option-rule ;
|| value-rule ;
|| character-rule ;
|| semicolon ;
} ;
pragma-tendra-rule : () -> () = {
token-rule ;
|| interface-rule ;
|| tokdef-rule ;
|| literal-rule ;
|| identifier-rule ;
|| pragma-rule ;
|| type-spec ;
} ;
pragma-tendra : () -> ( t : LEX ) = {
pragma-tendra-rule ;
t = <lex_pragma> ;
||
exhaustive ;
t = <lex_exhaustive> ;
||
discard ;
t = <lex_unused> ;
||
set ;
t = <lex_set> ;
##
<error_syntax> ;
t = <lex_pragma> ;
} ;
pragma-preproc : () -> ( t : LEX ) = {
pragma-rule ;
t = <lex_none> ;
##
t = <lex_pragma> ;
} ;
/*
ENTRY POINTS
There are two entry points into the grammar, pragma-tendra, which is
the normal entry point, and pragma-preproc, which is used during
preprocessing.
*/
%entry% pragma-tendra, pragma-preproc ;