Net2/usr/src/contrib/isode/pepsy/yacc.y.gnrc

/* yacc.y - yacc ASN.1 parser */
/* %WARNING% */

%{
#ifndef	lint
static char *rcsid = "$Header: /f/osi/pepsy/RCS/yacc.y.gnrc,v 7.7 91/02/22 09:50:19 mrose Interim $";
#endif

/* 
 * $Header: /f/osi/pepsy/RCS/yacc.y.gnrc,v 7.7 91/02/22 09:50:19 mrose Interim $
 *
 *
 * $Log:	yacc.y.gnrc,v $
 * Revision 7.7  91/02/22  09:50:19  mrose
 * Interim 6.8
 * 
 * Revision 7.6  91/01/09  11:17:59  mrose
 * pow
 * 
 * Revision 7.5  91/01/08  12:51:06  mrose
 * update
 * 
 * Revision 7.4  90/12/23  18:42:15  mrose
 * update
 * 
 * Revision 7.3  90/12/11  10:41:16  mrose
 * sync
 * 
 * Revision 7.2  90/11/11  10:54:24  mrose
 * update
 * 
 * Revision 7.1  90/11/04  19:17:31  mrose
 * update
 * 
 * Revision 7.0  90/11/03  21:18:17  mrose
 * *** empty log message ***
 * 
 */

/*
 *				  NOTICE
 *
 *    Acquisition, use, and distribution of this module and related
 *    materials are subject to the restrictions of a license agreement.
 *    Consult the Preface in the User's Manual for the full terms of
 *    this agreement.
 *
 */


#include <stdio.h>
#include <ctype.h>
%BEGIN(PEPSY)%
#include "pepsydefs.h"
%END(PEPSY)%
%BEGIN(PEPY)%
#include "pepy.h"
%END(PEPY)%
%BEGIN(ROSY)%
#include "rosy-defs.h"
%END(ROSY)%
%BEGIN(MOSY)%
#include "mosy-defs.h"
%END(MOSY)%

#define	YYSTYPE	YYSTKTYPE


#define	YYDEBUG	1

extern int pepydebug;
extern int doexternals;

int	tagcontrol = TAG_UNKNOWN;
static int	tagdefault;
static int	listtype;
static OID	modid;

static int	yyporting = 0;

typedef struct ypa {
    char   *ya_text;
    int	    ya_lineno;
}		ypa, *YA;
#define	NULLYA	((YA) 0)
extern double pow ();

%BEGIN(PEPSY)%
/* encoding/decoding/printing/freeing functions */
static	char	*efn, *dfn, *pfn, *ffn;

/*
 * clear the ?fn variables for the next coding functions
 */
clrfn()
{
    if (efn) {
	efn = NULLCP;
    }
    if (dfn) {
	dfn = NULLCP;
    }
    if (pfn) {
	pfn = NULLCP;
    }
    if (ffn) {
	ffn = NULLCP;
    }
}

%END(PEPSY)%

static YA  new_action (text, lineno)
char   *text;
int	lineno;
{
    register YA	    ya;

    if ((ya = (YA) calloc (1, sizeof *ya)) == NULLYA)
	yyerror ("out of memory");

    ya -> ya_text = text;
    ya -> ya_lineno = lineno;

    return ya;
}
#define	free_action(ya)	(void) free ((char *) (ya))

typedef struct	{
    char *ys_structname;
    char *ys_ptrname;
} ysa, *YS;
#define NULLYS ((YS) 0)

static YS new_ys (str)
char	*str;
{
    register YS	ys;
    register char *p, *q;
    char c;

    if((ys = (YS) malloc (sizeof *ys)) == NULLYS)
	yyerror ("out of memory");
    q = str;
    while (isspace (*q)) q++;
    for (p = q; isalnum(*p) || *p == '_'; p++)
	continue;
    if (*p != '\0') {
	c = *p;
	*p = '\0';
	ys -> ys_structname = new_string (q);
	*p = c;
    }
    else {
	ys -> ys_structname = new_string (q);
	ys -> ys_ptrname = NULLCP;
	free (str);
	return ys;
    }
    for (q = p; *q != '$'; q++)
	if (! *q) {
	    free (str);
	    ys -> ys_ptrname = NULLCP;
	    return ys;
	}
    q++;
    while (isspace (*q)) q++;
    for (p = q; isalnum(*p) || *p == '_'; p++)
	continue;
    *p = '\0';
    ys -> ys_ptrname = new_string (q);
    free (str);
    return ys;
}
#define	free_ys(ys) (void) free ((char *) (ys))

static int  final_actions = 0;
static int  start_actions = 0;

extern char	*malloc();

char	*
hex2bin (s, pi)
register char   *s;
int	*pi;
{
    register char *d;
    char	*start;
    register int    c,
		    i;


    if ((d = malloc(strlen(s)/2 + 2)) == NULLCP)
	yyerror ("out of memory");
    start = d;
    for (i = 0; *s; i++) {
	if ((c = *s++) >= 'a' && c <= 'f')
	    c -= 'a' - 0x0a;
	else
	    if (c >= 'A' && c <= 'F')
		c -= 'A' - 0x0a;
	    else
		if (c >= '0' && c <= '9')
		    c -= '0';
		else
		    c = 0;

	if (i & 1)
	    *d++ |= c & 0xf;
	else
	    *d = (c & 0xf) << 4;
    }

    *pi = i;	/* We use number semi-octets ! */
    return start;
}

char	*
bit2bin (s, pi)
register char   *s;
int	*pi;
{
    register char *d;
    char	*start;
    register int    c,
		    shft,
		    i;


    if ((d = malloc(strlen(s)/8 + 2)) == NULLCP)
	yyerror ("out of memory");
    start = d;
    *d = 0;
    for (i = 0; *s; i++) {
	if ((c = *s++) == '1')
	    c = 1;
	else if (c == '0')
	    c = 0;
	else
	    break;	/* ?? */

	shft = 7 - i % 8;	/* shift to get to its bit */
	*d |= c << shft;
	if (shft == 0)	/* last bit in this octet so goto next octet */
	    *++d = 0;	/* initialise it to zero */
    }

    *pi = i;
    return start;
}

bin2hex (s, d, len)
register    u_char *s;
register char  *d;
int     len;
{
    register int    i,
		    g;

    for (i = 0; i < len; i++) {
	g = s[i >> 1];
	if ((i & 1) == 0)
	    g >>= 4;
	g &= 0xf;

	if (g < 0x0a)
	    *d++ = g + '0';
	else
	    *d++ = g + 'a' - 0x0a;
    }

    *d = NULL;

    return len;
}

int
hex2int(s)
register char	*s;
{
    register int	sum = 0;
    register int		i;

    while (*s) {
	if (!isxdigit(*s))
	    break;
	if (isdigit(*s))
	    i = *s - '0';
	else
	    i = tolower(*s) - 'a' + 10;
	sum = sum << 4 + i;
	s++;
    }

    return (sum);
}

int
bit2int(s)
register char	*s;
{
    register int	sum = 0;
    register int		i;

    while (*s) {
	if (*s != '0' && *s != '1')
	    break;
	if (*s == '1')
	    sum <<= 1;
	else
	    sum = sum << 1 + 1;
	s++;
    }
    return (sum);
}

%}

%start	ModuleDefinition


%union	{
    int	    yy_number;
    char   *yy_string;
    YP	    yy_type;
    YV	    yy_value;
    YT	    yy_tag;
    YA	    yy_action;
    OID	    yy_oid;
    YS	    yy_sctrl;
    double  yy_real;
%BEGIN(PEPSY)%
    YFN     yy_yfn;
    YAL     yy_yal;
%END(PEPSY)%
}


%token  ABSENT ACTION ANY APPLICATION BAR BGIN BIT BITSTRING BOOLEAN
	BSTRING BY CCE CHOICE COMMA COMPONENT COMPONENTS COMPONENTSOF
	CONTROL DEC_FN DECODER DEFAULT DEFINED DEFINITIONS DOT DOTDOT
	DOTDOTDOT ENC_FN ENCODER ENCRYPTED END ENUMERATED EXPORTS
	EXPLICIT FALSE FRE_FN FROM HSTRING ID IDENTIFIER IMPLICIT
	IMPORTS INCLUDES INTEGER LANGLE LBRACE LBRACKET LITNUMBER
	LITSTRING LPAREN MIN MINUS MAX NAME NIL OBJECT OCTET
	OCTETSTRING OF OPTIONAL PARAMETERTYPE PLUS PREFIXES PRESENT
	PRINTER PRIVATE PRT_FN RBRACE RBRACKET REAL RPAREN STAR
	SECTIONS SEMICOLON SEQUENCE SEQUENCEOF SET SETOF SIZE STRING
	TAGS TRUE UNIVERSAL VALA VALB VALI VALS VALP VALO VALOID VALR
	VALT VALTYPE VALQ VALX VLENGTH WITH SCTRL PLUSINFINITY
	MINUSINFINITY
%BEGIN(ROSY)%
        OPERATION ARGUMENT RESULT ERRORS LINKED ERROR PARAMETER
/* new stuff */
	ABSTRACT OPERATIONS CONSUMER SUPPLIER INVOKES PORT PORTS
	OBJECTCONSUMER OBJECTSUPPLIER REFINE AS RECURRING VISIBLE
	PAIRED BIND UNBIND
/* end new stuff */
%END(ROSY)%
%BEGIN(MOSY)%
	OBJECTYPE SYNTAX ACCESS STATUS
%END(MOSY)%
%BEGIN(PEPSY)%
	EACTION DACTION PACTION ECHOICE DCHOICE PCHOICE
%END(PEPSY)%

%type	<yy_number>	LITNUMBER 
%type	<yy_number>	ABSENT ANY BGIN APPLICATION BIT BITSTRING
			BOOLEAN CHOICE COMPONENT COMPONENTS COMPONENTSOF
			DECODER DEFAULT DEFINED DEFINITIONS ENCODER 
			ENCRYPTED END ENUMERATED EXPLICIT EXPORTS
			FALSE FROM IDENTIFIER IMPLICIT IMPORTS INCLUDES
			INTEGER MIN MAX NIL OBJECT OCTET OCTETSTRING
			OF OPTIONAL PREFIXES PRESENT PRINTER PRIVATE REAL
			SECTIONS SEQUENCE SEQUENCEOF SET STRING TAGS
			TRUE UNIVERSAL WITH PLUSINFINITY MINUSINFINITY
			AnyType
%type	<yy_real>	RealValue NumericRealValue SpecialRealValue
%type   <yy_string>     DEC_FN ENC_FN PRT_FN FRE_FN ID NAME LITSTRING
			BSTRING HSTRING VALA VALB VALI VALS VALP VALQ
			VALR VALT VALTYPE VALO VALX VLENGTH VALOID
			CONTROL PARAMETERTYPE ParameterType Control
			ValParameter String PassInt PassBool PassOid
			PassAny PassReal ModuleIdentifier Symbol
			SymbolList SCTRL
%type   <yy_type>       Type BuiltinType DefinedType PassValue PassBit
			PassString NullPass ElementTypes
			OptionalTypeList OptionalType NamedType
			ComponentsOf AlternativeTypeList MemberTypes
			SubType Valtype
%BEGIN(ROSY)%
			Argument Result Parameter
%END(ROSY)%
%type   <yy_value>      NamedNumberList NamedNumber
NumericValue
			Value BuiltinValue DefinedValue IdentifierList
			Values NamedValueList NamedValue NNlist
%BEGIN(ROSY)%
			Errors ErrorNames LinkedOperations
			LinkedOperationNames
%END(ROSY)%
%BEGIN(MOSY)%
			ObjectID ObjectIDComponentList ObjectSubID
%END(MOSY)%
%BEGIN(PEPSY)%
%type   <yy_yfn>        CodingFn
%type   <yy_yal>        UAction CAction
%type   <yy_action> 	EACTION DACTION PACTION ECHOICE DCHOICE PCHOICE
%END(PEPSY)%
%type   <yy_tag>        Tag Class
%type   <yy_action>     ACTION
%type   <yy_oid>        ObjIdComponentList ObjectIdentifierValue
			ObjIdComponent NumberForm NameAndNumberForm
%type   <yy_sctrl>      Sctrl
%%

ModuleDefinition:	ModuleIdentifier DEFINITIONS TagDefault CCE
				{
    				    mymodule = $1;
				    mymoduleid = modid;
				    pass1 ();
				}
			ModuleActions ModulePrefixes { start_actions++; }
			BGIN ModuleBody END
			ModuleActions { pass2 (); final_actions++; }
	;

TagDefault:		EXPLICIT TAGS { 
			    tagdefault = 0;
			    tagcontrol = TAG_EXPLICIT;
			}
	|		IMPLICIT TAGS {
			    tagdefault = YP_IMPLICIT;
			    tagcontrol = TAG_IMPLICIT;
			}
	|		empty {
			    tagdefault = 0;
			    tagcontrol = TAG_UNKNOWN;
			}
	;

ModuleIdentifier:	ID AssignedIdentifier { $$ = $1; }
	;

AssignedIdentifier:	ObjectIdentifierValue { modid = $1; }
	|		empty
	;

ModuleActions:		ACTION {
%BEGIN(PEPSY)%
				{ Action a;

				    if (start_actions) {
					a = final_action = new_action_t();
				    } else {
					a = start_action = new_action_t();
				    }
				    a->a_data = $1->ya_text;
				    a->a_line = $1->ya_lineno;
				    free_action ($1);
				    break;
				    /*NOTREACHED*/
				}
%END(PEPSY)%
			/*
%BEGIN(PEPY)%
			    if (bflag) {
				if (final_actions) 
				    init_new_file ();
				else {
				    module_actions = $1 -> ya_text;
				    free_action ($1);
				    break;
				}
			    }
%END(PEPY)%
			    if (!dflag) {
				if (Cflag > 0) {
				    if (!Pflag && *sysin)
					(void) printf ("# line %d \"%s\"\n",
						$1 -> ya_lineno, sysin);
				    fputs ($1 -> ya_text, stdout);
				}
				else {
				    (void) printf ("%%{\n#include \"%s-types.h\"\n",
					    mymodule);
				    (void) printf ("%s%%}\n", $1 -> ya_text);
				    Cflag = -1;
				}
			    }
			    free_action ($1);
%BEGIN(PEPY)%
			    if (bflag)
				end_file ();
%END(PEPY)%
		    */
			}
	|		empty
	;
ModulePrefixes:
			PREFIXES String String String
			{
			    yyencdflt = $2;
			    yydecdflt = $3;
			    yyprfdflt = $4;
			}
	|		empty
	;
ModuleBody:		Exports Imports AssignmentList
	;

Exports:		EXPORTS  { listtype = TBL_EXPORT; doexternals = 0;
				   yyporting = 1; }
				 SymbolsExported SEMICOLON {
			    yyporting = 0;
			    if (mymoduleid == NULLOID)
				warning ("EXPORTS but no ModuleIdentifier");
				
			}
	|		empty
	;

SymbolsExported:	SymbolList
	|		empty
	;

Imports:		IMPORTS  { listtype = TBL_IMPORT; yyporting = 1; }
				 SymbolsImported SEMICOLON {
			    yyporting = 0;
			    if (mymoduleid == NULLOID)
				warning ("IMPORTS but no ModuleIdentifier");
			}

	|		empty
	;

SymbolsImported:	SymbolsFromModuleList
	|		empty
	;

SymbolsFromModuleList:	SymbolsFromModuleList SymbolsFromModule
	|		SymbolsFromModule
	;

SymbolsFromModule:	SymbolList FROM ModuleIdentifier
				{
				    addtableref ($3, modid, listtype);
				}
	;

SymbolList:		SymbolList COMMA Symbol {
			    addtable($3, listtype, ER_UNKNOWN);
			}
	|		Symbol { addtable ($1, listtype, ER_UNKNOWN); }

	|		SymbolList COMMA MINUS Symbol {
			    addtable($4, listtype, ER_NORMAL);
			}
	|		MINUS Symbol { addtable ($2, listtype, ER_NORMAL); }

	|		SymbolList COMMA PLUS Symbol {
			    addtable($4, listtype, ER_EXPLICIT);
			}
	|		PLUS Symbol { addtable ($2, listtype, ER_EXPLICIT); }
	;

Symbol:			ID
	|		NAME
	;

AssignmentList:		AssignmentList Section Assignment
	|		empty
	;

Section:		ENCODER String
			{ yysection = YP_ENCODER; yyencpref = $2;
			  yyprint (NULLCP, 0, 1); }
	|		DECODER String
			{ yysection = YP_DECODER; yydecpref = $2;
			  yyprint (NULLCP, 0, 1); }
	|		PRINTER String
			{ yysection = YP_PRINTER; yyprfpref = $2;
			  yyprint (NULLCP, 0, 1); }
	|		SECTIONS String String String
			{
			    yysection = NULL;
			    if (strcmp (yyencpref = $2, "none"))
				yysection |= YP_ENCODER;
			    if (strcmp (yydecpref = $3, "none"))
				yysection |= YP_DECODER;
			    if (strcmp (yyprfpref = $4, "none"))
				yysection |= YP_PRINTER;
			    yyprint (NULLCP, 0, 1); 
			}
	|		empty
	;

String:			ID { $$ = $1; }
	|		NAME { $$ = $1; }
	;

Assignment:		Typeassignment
%BEGIN(ROSY)%
	|		OperationDefinition
	|		ErrorDefinition
/* new stuff */
	|		PortDefinition
	|		ObjectDefinition
/*	|		RefineDefinition	-- impossible!!!! (JPO) */
/*	|		BindDefinition		-- lacking defs... */
/*	|		UnBindDefinition	-- ditto */
/* end new stuff */
%END(ROSY)%
%BEGIN(MOSY)%
	|		ObjectTypeDefinition
	|		ObjectIDefinition
%END(MOSY)%
	|		Valueassignment
	;

%BEGIN(ROSY)%
OperationDefinition:	NAME OPERATION Argument Result Errors LinkedOperations
			CCE LITNUMBER {
			    pass1_op (mymodule, $1, $3, $4, $5, $6, $8);
			}
	;

Argument:		ARGUMENT NamedType { $$ = $2; }
	|		empty { $$ = NULLYP; }
	;

Result:			RESULT NamedType { $$ = $2; }
	|		empty { $$ = NULLYP; }
	;

Errors:			ERRORS LBRACE ErrorNames RBRACE { $$ = $3; }
	|		empty { $$ = NULLYV; }

LinkedOperations:	LINKED LBRACE LinkedOperationNames RBRACE { $$ = $3; }
	|		empty { $$ = NULLYV; }
    

ErrorNames:		NamedValueList {
			    $$ = new_value (YV_VALIST);
			    $$ -> yv_idlist = $1;
			}
	|		empty { $$ = NULLYV; }


LinkedOperationNames:	NamedValueList {
			    $$ = new_value (YV_VALIST);
			    $$ -> yv_idlist = $1;
			}
	|		empty { $$ = NULLYV; }


ErrorDefinition:	NAME ERROR Parameter CCE LITNUMBER {
			    pass1_err (mymodule, $1, $3, $5);
			}
	;

Parameter:		PARAMETER NamedType { $$ = $2; }
	|		empty { $$ = NULLYP; }
	;

/* new stuff start */
PortDefinition:		NAME PORT PortOperations CCE PortValue
	;

PortValue:		ObjectIdentifierValue
	|		NAME
	;

PortOperations:		PortSymmetrical
	|		PortAsymetrical
	|		empty

PortSymmetrical:	ABSTRACT OPERATIONS LBRACE PortOperationList RBRACE
	;

PortAsymetrical:	PortOneSided
	|		PortTwoSided
	;

PortOneSided:		PortConsumer
	|		PortSupplier
	;

PortTwoSided:		PortConsumer PortSupplier
	|		PortSupplier PortConsumer
	;

PortConsumer:		CONSUMER INVOKES LBRACE PortOperationList RBRACE
	;

PortSupplier:		SUPPLIER INVOKES LBRACE PortOperationList RBRACE
	;

PortOperationList:	OperationValue
	|		OperationValue COMMA PortOperationList
	;

OperationValue:		NAME
	|		ID
	|		LITNUMBER
	|		ObjectIdentifierValue
	;

ObjectDefinition:	NAME OBJECT ObjectType CCE PortValue
	;

ObjectType:		PORTS LBRACE ObjectPortList RBRACE
	|		empty
	;

ObjectPortList:		ObjectPort COMMA ObjectPortList
	|		ObjectPort
	;

ObjectPort:		PortValue ObjectPortType
	;

ObjectPortType:		ObjectSymetric
	|		ObjectAsymetric
	;

ObjectSymetric:		empty
	;

ObjectAsymetric:	OBJECTCONSUMER
	|		OBJECTSUPPLIER
	;

/* New stuff end */
%END(ROSY)%

%BEGIN(MOSY)%
ObjectTypeDefinition:	NAME OBJECTYPE SYNTAX NamedType ACCESS NAME
			STATUS NAME CCE ObjectID {
			    pass1_obj (mymodule, $1, $4, $10, $6, $8);
			}
	;

ObjectIDefinition:	NAME OBJECT IDENTIFIER CCE ObjectID {
			    pass1_oid (mymodule, $1, $5);
			}
	;

ObjectID:		NAME {
			    $$ = new_value (YV_OIDLIST);
			    $$ -> yv_idlist = new_value (YV_IDEFINED);
			    $$ -> yv_idlist -> yv_identifier = $1;
			    $$ -> yv_idlist -> yv_flags |= YV_BOUND;
			}
	|		LBRACE ObjectIDComponentList RBRACE {
			    $$ = new_value (YV_OIDLIST);
			    $$ -> yv_idlist = $2;
			}
	;
ObjectIDComponentList:	ObjectSubID { $$ = $1; }
	|		ObjectIDComponentList ObjectSubID {
			    $$ = add_value ($1, $2);
			}
	;
ObjectSubID:		LITNUMBER {
			    $$ = new_value (YV_NUMBER);
			    $$ -> yv_number = $1;
			}
	|		NAME {
			    $$ = new_value (YV_IDEFINED);
			    $$ -> yv_identifier = $1;
			    $$ -> yv_flags |= YV_BOUND;
			}
	|		NAME LPAREN LITNUMBER RPAREN {
			    $$ = new_value (YV_NUMBER);
			    $$ -> yv_number = $3;
			    $$ -> yv_named = $1;
			    $$ -> yv_flags |= YV_NAMED;
			}
	;
%END(MOSY)%
%BEGIN(PEPSY)%
UAction:		UAction EACTION {
			    if ($1 == NULLYAL)
				$$ = new_yal();
			    else
				$$ = $1;
			    if ($$->yal_enc)
				yyerror("multiple encoding actions at the one place\n");
			    $$->yal_enc = new_action_t($2->ya_text,
				$2->ya_lineno, e_actions++);
			}
	| 		UAction DACTION {
			    if ($1 == NULLYAL)
				$$ = new_yal();
			    else
				$$ = $1;
			    if ($$->yal_dec)
				yyerror("multiple decoding actions at the one place\n");
			    $$->yal_dec = new_action_t($2->ya_text, $2->ya_lineno, d_actions++);
			}
	| 		UAction PACTION {
			    if ($1 == NULLYAL)
				$$ = new_yal();
			    else
				$$ = $1;
			    if ($$->yal_prn)
				yyerror("multiple printing actions at the one place\n");
			    $$->yal_prn = new_action_t($2->ya_text, $2->ya_lineno, p_actions++);
			}
	| 		empty
			{ $$ = NULLYAL; }
	;

CAction:		CAction ECHOICE {
			    if ($1 == NULLYAL)
				$$ = new_yal();
			    else
				$$ = $1;
			    if ($$->yal_enc)
				yyerror("multiple choice encoding actions at the one place\n");
			    $$->yal_enc = new_action_t($2->ya_text,
				$2->ya_lineno, e_actions++);
			}
	|		CAction DCHOICE {
			    if ($1 == NULLYAL)
				$$ = new_yal();
			    else
				$$ = $1;
			    if ($$->yal_dec)
				yyerror("multiple choice decoding actions at the one place\n");
			    $$->yal_dec = new_action_t($2->ya_text, $2->ya_lineno, d_actions ++);
			}
	|		CAction PCHOICE {
			    if ($1 == NULLYAL)
				$$ = new_yal();
			    else
				$$ = $1;
			    if ($$->yal_prn)
				yyerror("multiple choice printing actions at the one place\n");
			    $$->yal_prn = new_action_t($2->ya_text, $2->ya_lineno, 0);
			}
	|		empty
			{ $$ = NULLYAL; }
	;

%END(PEPSY)%

Typeassignment:		ID ParameterType CCE UAction Type {
			    if ($2)
			        $5 -> yp_param_type = $2;
			    if ($4)
				$5->yp_bef_alist=yal_join($4, $5->yp_bef_alist);
			    pass1_type (yyencpref, yydecpref, yyprfpref,
				    mymodule, $1, $5);
			} ;

Type:			BuiltinType CodingFn UAction {
			    $$ = $1;
			    $$ -> yp_direction = yysection;
			    if ($2)
				$$->yp_yfn = join_yfn($$->yp_yfn, $2);
			    if ($3)
				$$->yp_aft_alist=yal_join($3, $$->yp_aft_alist);
			}
	|		DefinedType CodingFn UAction {
			    $$ = $1;
			    $$ -> yp_direction = yysection;
			    if ($2)
				$$->yp_yfn = join_yfn($$->yp_yfn, $2);
			    if ($3)
				$$->yp_aft_alist=yal_join($3, $$->yp_aft_alist);
			}
	|		SubType CodingFn UAction {
			    $$ = $1;
			    $$ -> yp_direction = yysection;
			    if ($2)
				$$->yp_yfn = join_yfn($$->yp_yfn, $2);
			    if ($3)
				$$->yp_aft_alist=yal_join($3, $$->yp_aft_alist);
			}
	;


Control:		CONTROL
	|		empty { $$ = NULLCP; }
	;

ParameterType:		PARAMETERTYPE
	|		empty { $$ = NULLCP; }
	;

Valtype:		VALTYPE {
			    $$ = new_type(YP_UNDF, -1);
			    if (setvaltype($$, $1) == 0)
				yyerror("syntax error in [[ T ... ]]");
			    free($1);
			}
	|		empty { $$ = new_type(YP_UNDF, -1); }
	;

BuiltinType:		BOOLEAN PassBool {
			    $$ = new_type (YP_BOOL, $1);
			    $$ -> yp_intexp = $2;
			}
	|		INTEGER PassInt NNlist {
			    $$ = new_type ($3 ? YP_INTLIST : YP_INT, $1);
			    $$ -> yp_intexp = $2;
			    if ($3)
				    $$ -> yp_value = $3;
	    		}
	|		ENUMERATED PassInt LBRACE NamedNumberList
			    RBRACE {
			    $$ = new_type (YP_ENUMLIST, $1);
			    $$ -> yp_intexp = $2;
			    $$ -> yp_value = $4;
			}

	|		Bitstring PassBit NNlist {
			    $$ = $2;
	    		    $$ -> yp_code = $3 ? YP_BITLIST: YP_BIT;
			    if ($3)
				$$ -> yp_value = $3;
			}
	|		Octetstring PassString {
			    $$ = $2;
			    $$ -> yp_code = YP_OCT;
			}
	|		NIL {
			    $$ = new_type (YP_NULL, $1);
			}
	|		SEQUENCE Sctrl PassAny {
			    $$ = new_type (YP_SEQ, $1);
			    $$ -> yp_strexp = $3;
			}
	|		SequenceOf Sctrl Valtype Control UAction Type {
			    $$ = $3;
			    $$->yp_code = YP_SEQTYPE;
			    $$ -> yp_type = $6;
			    if ($2) {
				$$ -> yp_structname = $2 -> ys_structname;
				$$ -> yp_ptrname = $2 -> ys_ptrname;
				free_ys ($2);
			    }
			    if ($4) {
				$$ -> yp_control = $4;
				$$ -> yp_flags |= YP_CONTROLLED;
			    }
			    if ($5)
				$6->yp_bef_alist=yal_join($5, $6->yp_bef_alist);
			}
	|	SEQUENCE Sctrl Valtype LBRACE UAction ElementTypes RBRACE {
			    $$ = $3;
			    $$->yp_code = YP_SEQLIST;
			    $$ -> yp_type = $6;
			    if ($2) {
                                $$ -> yp_structname = $2 -> ys_structname;
                                $$ -> yp_ptrname = $2 -> ys_ptrname;
                                free_ys ($2);
                            }
			    if ($6 && $5)
				$6->yp_bef_alist=yal_join($5, $6->yp_bef_alist);
	    		}
	|		SET Sctrl PassAny {
			    $$ = new_type (YP_SET, $1);
			    $$ -> yp_strexp = $3;
			}
	|		SetOf Sctrl Valtype Control UAction Type {
			    $$ = $3;
			    $$->yp_code = YP_SETTYPE;
			    $$ -> yp_type = $6;
			    if ($2) {
				$$ -> yp_structname = $2 -> ys_structname;
				$$ -> yp_ptrname = $2 -> ys_ptrname;
				free_ys ($2);
			    }
			    if ($4) {
				$$ -> yp_control = $4;
				$$ -> yp_flags |= YP_CONTROLLED;
			    }
			    if ($5)
				$6->yp_bef_alist=yal_join($5, $6->yp_bef_alist);
			}

	| 		SET Sctrl Valtype LBRACE UAction MemberTypes RBRACE {
			    $$ = $3;
			    $$->yp_code = YP_SETLIST;
			    $$ -> yp_type = $6;
			    if ($2) {
				$$ -> yp_structname = $2 -> ys_structname;
				$$ -> yp_ptrname = $2 -> ys_ptrname;
				free_ys ($2);
			    }
			    if ($6 && $5)
				$6->yp_bef_alist=yal_join($5, $6->yp_bef_alist);
	    		}
	|		Tag UAction IMPLICIT Type {
			    $$ = $4;
			    $$ -> yp_tag = $1;
			    $$ -> yp_flags |= (YP_IMPLICIT | YP_TAG);
			    if ($2)
				$$->yp_bef_alist=yal_join($2, $$->yp_bef_alist);
			}
	|		Tag UAction EXPLICIT Type {
			    $$ = $4;
			    $$ -> yp_tag = $1;
			    $$ -> yp_flags |= YP_TAG;
			    if ($2)
				$$->yp_bef_alist=yal_join($2, $$->yp_bef_alist);
			}
	|		Tag UAction Type {
			    $$ = $3;
			    $$ -> yp_tag = $1;
			    $$ -> yp_flags |= (YP_TAG| tagdefault);
			    if ($2)
				$$->yp_bef_alist=yal_join($2, $$->yp_bef_alist);
			}
	|		CHOICE Sctrl Valtype Control CAction LBRACE UAction
					AlternativeTypeList RBRACE {
			    $$ = $3;
			    $$->yp_code = YP_CHOICE;
			    $$ -> yp_type = $8;
			    if ($2) {
				$$ -> yp_structname = $2 -> ys_structname;
				$$ -> yp_ptrname = $2 -> ys_ptrname;
				free_ys ($2);
			    }
			    if ($4) {
				$$ -> yp_control = $4;
				$$ -> yp_flags |= YP_CONTROLLED;
			    }
			    if ($5)
				$$ -> yp_control_act = $5;
			    if ($8 && $7)
				$8->yp_bef_alist=yal_join($7, $8->yp_bef_alist);
			}
	|		NAME LANGLE Type {
			    $$ = $3;
			    $$ -> yp_bound = $1;
			    $$ -> yp_flags |= YP_BOUND;
			}
	|		AnyType PassAny {
			    $$ = new_type (YP_ANY, $1);
			    $$ -> yp_strexp = $2;
			}
	|		STAR AnyType PassAny {
			    $$ = new_type (YP_ANY, $2);
			    $$ -> yp_strexp = $3;
			    $$ -> yp_flags |= YP_WANTIMPLICIT;
			}
	|		OBJECT IDENTIFIER PassOid {
			    $$ = new_type (YP_OID, $1);
			    $$ -> yp_strexp = $3;
			}
	|		ENCRYPTED Type {
			    $$ = $2;
			    $$ -> yp_tag = new_tag (PE_CLASS_UNIV);
			    $$ -> yp_tag -> yt_value = new_value(YV_NUMBER);
			    $$ -> yp_tag -> yt_value -> yv_number = PE_PRIM_ENCR;
			    $$ -> yp_flags |=
			    	(YP_ENCRYPTED | YP_TAG | YP_IMPLICIT);
			}
	|		REAL PassReal {
			    $$ = new_type(YP_REAL, $1);
			    $$ -> yp_strexp = $2;
			}
	;

NNlist:			LBRACE NamedNumberList RBRACE { $$ = $2; }
	|		empty {	$$ = NULL; }
	;
DefinedType:		ID PassValue ValParameter {
			    $$ = $2;
			    $$ -> yp_code = YP_IDEFINED;
			    $$ -> yp_identifier = $1;
			    if ($3) {
				$$ -> yp_parm = $3;
				$$ -> yp_flags |= YP_PARMVAL;
			    }
%BEGIN(ROSY)%
#ifndef	lint
%END(ROSY)%
			    check_impexp ($$);
%BEGIN(ROSY)%
#endif
%END(ROSY)%
			}
	|		ID DOT ID PassValue ValParameter {
			    $$ = $4;
			    $$ -> yp_code = YP_IDEFINED;
			    $$ -> yp_identifier = $3;
			    $$ -> yp_module = $1;
			    if ($5) {
				$$ -> yp_parm = $5;
				$$ -> yp_flags |= YP_PARMVAL;
			    }
			}
	;

PassValue:		VALA {
			    $$ = new_type (YP_UNDF, -1);
			    $$ -> yp_intexp = NULLCP;
			    $$ -> yp_strexp = $1;
			    $$ -> yp_prfexp = 'a';
			}
	|		VALB {
			    $$ = new_type (YP_UNDF, -1);
			    $$ -> yp_intexp = $1;
			    $$ -> yp_strexp = NULLCP;
			    $$ -> yp_prfexp = 'b';
			}
	|		VALI {
			    $$ = new_type (YP_UNDF, -1);
			    $$ -> yp_intexp = $1;
			    $$ -> yp_strexp = NULLCP;
			    $$ -> yp_prfexp = 'i';
			}
	|		VALX VLENGTH {
			    $$ = new_type (YP_UNDF, -1);
			    $$ -> yp_intexp = $2;
			    $$ -> yp_strexp = $1;
			    $$ -> yp_prfexp = 'x';
			}
	|		VALOID {
			    $$ = new_type (YP_UNDF, -1);
			    $$ -> yp_intexp = NULLCP;
			    $$ -> yp_strexp = $1;
			    $$ -> yp_prfexp = 'O';
			}
	|		VALR  {
			    $$ = new_type (YP_UNDF, -1);
			    $$ -> yp_intexp = NULLCP;
			    $$ -> yp_strexp = $1;
			    $$ -> yp_prfexp = 'r';
			}
	|		VALT  {
			    $$ = new_type (YP_UNDF, -1);
			    $$ -> yp_intexp = $1;
			    $$ -> yp_prfexp = 't';
			}
	|		PassString
	;

AnyType:		ANY
	|		ANY DEFINED BY NAME
	;
			
PassOid:		VALOID
	|		empty { $$ = NULLCP; }
	;

PassAny:		VALA
	|		empty { $$ = NULLCP; }
	;

PassBool:		VALB
	|		empty { $$ = NULLCP; }
	;

PassInt:		VALI
	|		empty { $$ = NULLCP; }
	;

PassBit:		VALX VLENGTH {
			    $$ = new_type (YP_UNDF, -1);
			    $$ -> yp_intexp = $2;
			    $$ -> yp_strexp = $1;
			}
	|		VALT {
			    $$ = new_type (YP_UNDF, -1);
			    $$ -> yp_intexp = $1;
			    $$ -> yp_strexp = NULLCP;
			}
	|		NullPass
	;

PassString:		VALS {
			    $$ = new_type (YP_UNDF, -1);
			    $$ -> yp_intexp = NULLCP;
			    $$ -> yp_strexp = $1;
			    $$ -> yp_prfexp = 's';
			}
	|		VALO VLENGTH {
			    $$ = new_type (YP_UNDF, -1);
			    $$ -> yp_intexp = $2;
			    $$ -> yp_strexp = $1;
			    $$ -> yp_prfexp = 'o';
			}
	|		VALQ {
			    $$ = new_type (YP_UNDF, -1);
			    $$ -> yp_intexp = NULLCP;
			    $$ -> yp_strexp = $1;
			    $$ -> yp_prfexp = 'q';
			}
	|		NullPass
	;

PassReal:		VALR 
	|		empty { $$ = NULLCP; }
	;

NullPass:		empty {
			    $$ = new_type (YP_UNDF, -1);
			    $$ -> yp_intexp = NULLCP;
			    $$ -> yp_strexp = NULLCP;
			}
	;

CodingFn:		fnlist {
			    $$ = new_yfn(efn, dfn, pfn, ffn);
			    clrfn();
			}
	|		{ $$ = NULLYFN; }
	;

fn:		ENC_FN	{
		    if (efn)
			myyerror("extra encoding function %s ignored\n", $1);
		    else
			efn = $1;
		}
	|	DEC_FN {
		    if (dfn)
			myyerror("extra decoding function %s ignored\n", $1);
		    else
			dfn = $1;
		}
	|	PRT_FN {
		    if (pfn)
			myyerror("extra printing function %s ignored\n", $1);
		    else
			pfn = $1;
		}
	|	FRE_FN {
		    if (ffn)
			myyerror("extra freeing function %s ignored\n", $1);
		    else
			ffn = $1;
		}
	;

fnlist:		fn
	|	fnlist fn

ValParameter:		VALP
	|		empty { $$ = NULLCP; }
	;

NamedNumberList:	NamedNumber { $$ = $1; }
	|		NamedNumberList COMMA NamedNumber {
			    $$ = add_value ($1, $3);
			}
	;
NamedNumber:		NAME LPAREN NumericValue RPAREN {
			    $$ = $3;
			    $$ -> yv_named = $1;
			    $$ -> yv_flags |= YV_NAMED;
			}
	;
NumericValue:		LITNUMBER {
			    $$ = new_value (YV_NUMBER);
			    $$ -> yv_number = $1;
			}
	|		DefinedValue
	;

ElementTypes:		OptionalTypeList { $$ = $1; }
	|		empty { $$ = NULLYP; }
	;
MemberTypes:		OptionalTypeList { $$ = $1; }

	|		empty { $$ = NULLYP; }
	;
OptionalTypeList:	OptionalType { $$ = $1; }
	|		OptionalTypeList COMMA UAction OptionalType {
			    if ($3)
				$4->yp_bef_alist=yal_join($3, $4->yp_bef_alist);
			    $$ = add_type ($1, $4);
			}
	;
OptionalType:		NamedType { $$ = $1; }
	|		NamedType OPTIONAL Control {
			    $$ = $1;
			    $$ -> yp_flags |= YP_OPTIONAL;
			    if ($3) {
				$$ -> yp_optcontrol = $3;
				$$ -> yp_flags |= YP_OPTCONTROL;
			    }
			}
	|		NamedType OPTIONAL CAction {
			    $$ = $1;
			    $$ -> yp_flags |= YP_OPTIONAL;
			    if ($3) {
				$$ -> yp_flags |= YP_OPTCONTROL;
				$$ -> yp_optional_act = $3;
			    }
			}
	|		NamedType DEFAULT Value Control {
			    $$ = $1;
			    $$ -> yp_default = $3;
			    $$ -> yp_flags |= YP_DEFAULT;
			    if ($4) {
				$$ -> yp_optcontrol = $4;
				$$ -> yp_flags |= YP_OPTCONTROL;
			    }
			}
	|		ComponentsOf { $$ = $1; }
	|		NAME ComponentsOf { $$ = $2; $$->yp_id = $1; }
	;
NamedType:		NAME Type {
			    $$ = $2;
			    $$ -> yp_id = $1;
			    $$ -> yp_flags |= YP_ID;
			}
	|		Type { $$ = $1; }
	;
ComponentsOf:		Components Type {
			    $$ = $2;
			    $$ -> yp_flags |= YP_COMPONENTS;
			}
	;
AlternativeTypeList:	NamedType { $$ = $1; }
	|		AlternativeTypeList COMMA UAction NamedType {
			    if ($3)
				$4->yp_bef_alist=yal_join($3, $4->yp_bef_alist);
			    $$ = add_type ($1, $4);
			}
	;

Tag:			LBRACKET Class NumericValue RBRACKET {
			    $$ = $2;
			    $$ -> yt_value = $3;
			}
	;
Class:			UNIVERSAL { $$ = new_tag (PE_CLASS_UNIV); }
	| 		APPLICATION { $$ = new_tag (PE_CLASS_APPL); }
	|		PRIVATE { $$ = new_tag (PE_CLASS_PRIV); }
	|		empty { $$ = new_tag (PE_CLASS_CONT); }
	;


Valueassignment:	NAME Type CCE Value
	;

Value:			BuiltinValue
	|		DefinedValue
	;
BuiltinValue:		TRUE {
			    $$ = new_value (YV_BOOL);
			    $$ -> yv_number = 1;
			}
	|		FALSE {
			    $$ = new_value (YV_BOOL);
			    $$ -> yv_number = 0;
			}
	|		LITNUMBER {
			    $$ = new_value (YV_NUMBER);
			    $$ -> yv_number = $1;
			}
	|		BSTRING {
			    $$ = new_value (YV_BSTRING);
			    $$ -> yv_xstring = bit2bin($1, &$$->yv_xlength);
			    free($1);
			}
	|		HSTRING {
			    $$ = new_value (YV_HSTRING);
			    $$ -> yv_xstring = hex2bin($1, &$$->yv_xlength);
			    free($1);
			}
	|		LBRACE ID IdentifierList RBRACE {
			    $$ = new_value (YV_IDLIST);
			    $$ -> yv_idlist = new_value (YV_IDEFINED);
			    $$ -> yv_idlist -> yv_identifier = $2;
			    if ($3)
			        $$ = add_value ($$, $3);
			}
	|		LITSTRING {
			    $$ = new_value (YV_STRING);
			    $$ -> yv_string = $1;
			}
	|		NIL { $$ = new_value (YV_NULL); }
	|		LBRACE Values RBRACE {
			    $$ = new_value (YV_VALIST);
			    $$ -> yv_idlist = $2;
			}
	|		NAME Value {
			    $$ = $2;
			    $$ -> yv_id = $1;
			    $$ -> yv_flags |= YV_ID;
			}
	|		Type Value {
			    $$ = $2;
			    $$ -> yv_type = $1;
			    $$ -> yv_flags |= YV_TYPE;
			}
	|		RealValue {
			    $$ = new_value (YV_REAL);
			    $$ -> yv_real = $1;
			}
	;

RealValue: 		NumericRealValue
	|		SpecialRealValue
	;

SpecialRealValue:	PLUSINFINITY { $$ = PE_REAL_INFINITY;} 
	|		MINUSINFINITY { $$ = - PE_REAL_INFINITY; }
	;

NumericRealValue:	LBRACE LITNUMBER COMMA LITNUMBER COMMA
				 LITNUMBER RBRACE {
				if ($4 != 2 && $4 != 10)
					myyerror ("Illegal base value %d", $4);
				$$ = $2 * pow ((double)$4, (double)$6);
			}
	;

DefinedValue:		ID {
			    $$ = new_value (YV_IDEFINED);
			    $$ -> yv_identifier = $1;
			}
	|		NAME {	/* XXX */
			    $$ = new_value (YV_IDEFINED);
			    $$ -> yv_identifier = $1;
			    $$ -> yv_flags |= YV_BOUND;
			}
	|		ID DOT ID {
			    $$ = new_value (YV_IDEFINED);
			    $$ -> yv_identifier = $3;
			    $$ -> yv_module = $1;
			}
	;

IdentifierList:		IdentifierList COMMA ID {
			    $$ = new_value (YV_IDEFINED);
			    $$ -> yv_identifier = $3;
			    if ($1)
			        $$ = add_value ($1, $$);
			}
	|		empty { $$ = NULLYV; }
	;

Values:			NamedValueList { $$ = $1; }
	|		empty { $$ = NULLYV; }
	;
NamedValueList:		NamedValue { $$ = $1; }
	|		NamedValueList COMMA NamedValue {
			    $$ = add_value ($1, $3);
			}
	;
NamedValue:		Value { $$ = $1; }
	;

empty:	;

Octetstring:		OCTET STRING
	|		OCTETSTRING
	;

Bitstring:		BITSTRING
	|		BIT STRING
	;

SequenceOf:		SEQUENCEOF
	|		SEQUENCE OF
	;
SetOf:			SETOF
	|		SET OF
	;
Components:		COMPONENTSOF
	|		COMPONENTS OF
	;

ObjectIdentifierValue:	LBRACE ObjIdComponentList RBRACE
			{ $$ = $2; }
	;

ObjIdComponentList:	ObjIdComponent
	|		ObjIdComponentList ObjIdComponent
			{
				$$ = addoid($1, $2);
				oid_free ($1);
				oid_free ($2);
			}
	;

ObjIdComponent:		NumberForm
	|		NameAndNumberForm
	;

NumberForm:		LITNUMBER { $$ = int2oid ($1); }
	|		DefinedValue {
				$$ = oidlookup($1->yv_identifier);
				free((char *)$1);
			}
	;

NameAndNumberForm:	NAME LPAREN NumberForm RPAREN {
				free ($1);
				$$ = $3;
			}
	;

SubType:		Type SubtypeSpec
	|		SET SizeConstraint OF Sctrl UAction Control Type {
			    $$ = new_type (YP_SETTYPE, $1);
			    $$ -> yp_type = $7;
			    if ($4) {
				$$ -> yp_structname = $4 -> ys_structname;
				$$ -> yp_ptrname = $4 -> ys_ptrname;
				free_ys ($4);
			    }
			    if ($6) {
			    	$$ -> yp_control = $6;
				$$ -> yp_flags |= YP_CONTROLLED;
			    }
			    if ($5)
				$7->yp_bef_alist=yal_join($5, $7->yp_bef_alist);
	    		}

	|		SEQUENCE SizeConstraint OF Sctrl UAction Control Type {
			    $$ = new_type (YP_SEQTYPE, $1);
			    $$ -> yp_type = $7;
			    if ($4) {
				$$ -> yp_structname = $4 -> ys_structname;
				$$ -> yp_ptrname = $4 -> ys_ptrname;
				free_ys ($4);
			    }
			    if ($6) {
				$$ -> yp_control = $6;
				$$ -> yp_flags |= YP_CONTROLLED;
			    }
			    if ($5)
				$7->yp_bef_alist=yal_join($5, $7->yp_bef_alist);
			}
	;

SubtypeSpec:		LPAREN SubtypeAlternative SubtypeAlternativeList RPAREN
	;

SubtypeAlternative:	SubtypeValueSet
	|		SubtypeConstraint
	;

SubtypeAlternativeList:	BAR SubtypeAlternative SubtypeAlternativeList
	|		empty
	;

SubtypeValueSet:	Value
	|		ContainedSubType
	|		ValueRange
	|		PermittedAlphabet
	;

SubtypeConstraint:	SizeConstraint
	|		InnerTypeConstraint
	;

ContainedSubType:	INCLUDES Type	;

ValueRange:		LowerEndPoint DOTDOT UpperEndpoint
	;

LowerEndPoint:		LowerEndValue
	|		LowerEndValue LANGLE
	;

UpperEndpoint:		UpperEndValue
	|		LANGLE UpperEndValue
	;

LowerEndValue:		Value
	|		MIN
	;

UpperEndValue:		Value
	|		MAX
	;

SizeConstraint:		SIZE SubtypeSpec
	;

PermittedAlphabet:	FROM SubtypeSpec
	;

InnerTypeConstraint:	WITH COMPONENT SingleTypeConstraint
	|		WITH COMPONENTS MultipleTypeConstraints
	;

SingleTypeConstraint:	SubtypeSpec
	;

MultipleTypeConstraints:FullSpecification
	|		PartialSpecification
	;

FullSpecification:	LBRACE TypeConstraints RBRACE
	;

PartialSpecification:	LBRACE DOTDOTDOT COMMA TypeConstraints RBRACE
	;

TypeConstraints:	NamedConstraint
	|		NamedConstraint COMMA TypeConstraints
	;

NamedConstraint:	NAME Constraint
	|		Constraint
	;

Constraint:		ValueConstraint
	|		PresenceConstraint
	|		empty
	;

ValueConstraint:	SubtypeSpec
	;

PresenceConstraint:	PRESENT
	|		ABSENT
	;

Sctrl:			SCTRL { $$ = new_ys ($1); }
	|		empty { $$ = NULLYS; }
	;
%%

#ifdef	HPUX
#define	uchar	Uchar
#endif
#include "lex.c"