/* YACC INPUT TO GENERATE FIRST PASS OF RUSSELL PARSER */ /* Error recovery assumes modified parser. The parser variable yychar */ /* is referenced but not altered. */ /* The syntax tree is built during the parse. No other semantic */ /* actions are performed. */ /* Denotations are only incompletely parsed using the yacc parser. */ /* Mkappl is then called to refine the parse. */ /* Note: Nonterminals consisting only of lower case letters generate */ /* the empty string. They are introduced only to perform appropriate */ /* semantic actions. */ %{ import java.io.*; import java.lang.*; import java.util.*; %} %token CHARACTERS %token CONSTANTS %token DO %token ELSE %token ELSIF %token END %token ENUM %token EXPORT %token FI %token FIELD %token FUNC %token HIDE %token IF %token IN %token EXTEND %token LET %token NI %token OD %token READONLY %token RECORD %token THEN %token TYPE %token UNION %token USE %token VAL %token VAR %token WITH %token RIGHT_ARROW %token EQUALS_EQUALS %token EQUALS_EQUALS_EQUALS %token COLON %token WORDID %token OPID %token PROD %token QSTRING %token UQSTRING %token LEFT_ANGLE_BRACKET %token RIGHT_ANGLE_BRACKET %token EXTERN %token SIGNATURE %left COR %left CAND %% Program : { $$ = Globals.insrtptr; /* Remember original value */ } Denotation = { if (Globals.stxtree != null) { /* insert new syntax tree in standard prologue */ if ($1 != null) ; // HELP!!! chgfld(($1 . bld_den_seq),ListHeaderNode.mklist($2)); else yyperror("No insertion marker in standard prologue"); } else { Globals.stxtree = $2; } } | error { yyperror("Syntax error"); } | error { yyperror("Syntax error"); } Denotation.seq ; Parameters : Id.list Opt.Colon Signature = { Node p; if ($2 == null) { yyperror("Missing colon in parameter specification"); } if (first($1) . id_str_table_index() == Initids.indx_Boolean && (Initids.id_Boolean . id_last_definition() == null)) { $$ = new ParserVal (p = Node.split(Const.PARAMETER, $1.NodeCvt(), $3.NodeCvt(),null,null,null,null)); // HELP!!! chgfld ( (id_Boolean . id_last_definition()), first(p) ); /* this is the actual definition */ Initids. id_Boolean . set_id_def_found(true); if (!Globals. initflag) { yywarn ("No builtin type Boolean"); } } else if (first($1) . id_str_table_index() == Initids. indx_Void && (Initids. id_Void . id_last_definition() == null)) { $$ = new ParserVal( p = Node.split(Const.PARAMETER, $1.NodeCvt(), $3.NodeCvt(),null,null,null,null)); // HELP!!! chgfld ( (Initids. id_Void . id_last_definition()), first(p) ); Initids. id_Void . set_id_def_found(true); if (!Globals.initflag) { yywarn ("No builtin type Void"); } } else if (first($1) . id_str_table_index() == Initids.indx_Integer && (Initids.id_Integer . id_last_definition() == null)) { $$ = new ParserVal (p = Node.split(Const.PARAMETER, $1.NodeCvt(), $3.NodeCvt(),null,null,null,null)); // HELP!!! chgfld ( (Initids.id_Integer . id_last_definition()), first(p) ); Initids.id_Integer . set_id_def_found(true); if (!Globals.initflag) { yywarn ("No builtin type Integer"); } } else if (first($1) . id_str_table_index() == Initids.indx_Null && (Initids.id_Null . id_last_definition() == null)) { $$ = new ParserVal(p = Node.split(Const.PARAMETER, $1.NodeCvt(), $3.NodeCvt(),null,null,null,null)); // HELP!!! chgfld ( (Initids.id_Null . id_last_definition()), first(p) ); Initids.id_Null . set_id_def_found(true); if (!Globals.initflag) { yywarn ("No builtin constant Null"); } } else { $$ = new ParserVal(Node.split(Const.PARAMETER, $1.NodeCvt(), $3.NodeCvt(),null,null,null,null)); } // vfree($1); vfree($3); } | Signature = { $$ = new ParserVal(ListHeaderNode.mklist( new ParameterNode(Const.PARAMETER,null,$1.NodeCvt()))); } | error { int i = 0; int c; yyperror("Error in Parameter Specification"); for ( c = yychar; !in(c, paramstop); c = yylex() ) if ( ++i > maxskip ) break; yyclearin(); switch (c) { case VAL: case VAR: case FUNC: yyunlex(c); yyunlex(';'); break; case '{': yyunlex(c); yyunlex(WORDID); yyunlex(VAL); yyunlex(']'); break; case ';': case ']': yyunlex(c); break; case Lexer.EOF: System.exit(1); default: /* recover at outer level */ yyunlex(c); yyunlex(']'); } if ( yydebug ) rec_on(c); $$ = new ParserVal(ListHeaderNode.emptylist()); } ; Opt.Colon : COLON { $$ = new ParserVal(true); } | { $$ = new ParserVal(false); } ; Opt.Parameters : Parameters = { $$ = $1; } | = { $$ = new ParserVal(ListHeaderNode.emptylist()); } ; Opt.Parameter.list : Opt.Parameters = { $$ = $1; } | Opt.Parameter.list ';' Opt.Parameters = { $$ = ParserVal.conc($1,$3); } ; Id.list : ID = { $$ = new ParserVal(ListHeaderNode.mklist($1.NodeCvt())); } | Id.list ',' ID = { $$ = new ParserVal(ListHeaderNode.addright(ListHeaderNode.ListHeaderNodeCvt($1.NodeCvt()),ListHeaderNode.ListHeaderNodeCvt($3.NodeCvt()))); } ; Signature : ID { $$ = $1; } | ManifestSignature { $$ = $1; } ; ManifestSignature : SIGNATURE { $$ = new ParserVal(Initids.sig_Signature); } | VAR BasicDenotation = { $$ = new ParserVal(new VarSignature(Const.VARSIGNATURE,$2.NodeCvt())); } | VAL BasicDenotation = { $$ = new ParserVal(new ValSignature(Const.VALSIGNATURE,$2.NodeCvt())); } | FuncSignature = { $$ = $1; } | TYPE '(' Opt.Simple CONSTANTS QSTRING QSTRING QSTRING UQSTRING QSTRING ')' Opt.Id '{' Opt.TypeSignatureComponent.list '}' = { if (!Globals.initflag) { yywarn("Compiler directive outside initialization"); } $$ = new ParserVal(new TSignature(Const.TYPESIGNATURE,$11.NodeCvt(),$13,$5,$6.NodeCvt(),$7.NodeCvt(),$9.NodeCvt())); // HELP $$ . ts_string_max = atoi($8); // HELP $$ . ts_simple_type = (int)$3; } | TYPE '(' Opt.Simple CONSTANTS QSTRING QSTRING QSTRING UQSTRING ')' Opt.Id '{' Opt.TypeSignatureComponent.list '}' = { if (!Globals.initflag) { yywarn("Compiler directive outside initialization"); } $$ = new ParserVal(new TSignature(Const.TYPESIGNATURE,$10.NodeCvt(),$12,$5,$6.NodeCvt(),$7.NodeCvt(),null)); //HELP $$ . ts_string_max = atoi($8); // HELP $$ . ts_simple_type = (int)$3; } | TYPE '(' Opt.Simple CONSTANTS QSTRING QSTRING QSTRING ')' Opt.Id '{' Opt.TypeSignatureComponent.list '}' = { if (!Globals.initflag) { yywarn("Compiler directive outside initialization"); } $$ = new ParserVal(new TSignature(Const.TYPESIGNATURE,$9.NodeCvt(),$11,$5,$6.NodeCvt(),$7.NodeCvt(),null)); // HELP $$ . ts_string_max = -1; // HELP $$ . ts_simple_type = (int)$3; } | TYPE '(' Opt.Simple CONSTANTS QSTRING ')' Opt.Id '{' Opt.TypeSignatureComponent.list '}' = { if (!Globals.initflag) { yywarn("Compiler directive outside initialization"); } $$ = new ParserVal(new TSignature(Const.TYPESIGNATURE,$7.NodeCvt(),$9,$5,null,null,null)); // HELP $$ . ts_string_max = -1; // HELP $$ . ts_simple_type = (int)$3; } | TYPE '(' Opt.Simple ')' Opt.Id '{' Opt.TypeSignatureComponent.list '}' = { if (!Globals.initflag) { yywarn("Compiler directive outside initialization"); } $$ = new ParserVal(new TSignature(Const.TYPESIGNATURE,$5.NodeCvt(),$7,null,null,null,null)); //HELP $$ . ts_string_max = -1; // HELP $$ . ts_simple_type = (int)$3; } | TYPE Opt.Id '{' Opt.TypeSignatureComponent.list '}' = { $$ = new ParserVal(new TSignature(Const.TYPESIGNATURE,$2.NodeCvt(),$4,null,null,null,null)); // HELP $$ . ts_string_max = -1; // HELP $$ . ts_simple_type = false; } ; Opt.Simple : ID = { if ($1.NodeCvt() . id_str_table_index() == Initids.indx_simple) { $$ = new ParserVal(true); /* simple type, no pointers to activation records */ } else { yywarn("Compiler directive not understood"); $$ = new ParserVal(false); } // HELP vfree($1); } | = { $$ = new ParserVal(false); } ; Opt.InLine : '(' ID QSTRING ')' { if (!Globals.initflag) { yywarn("Compiler directive outside initialization"); } if ($2.NodeCvt() . id_str_table_index() == Initids.indx_inline) { // $$ = ((inline_cnvt)($3)); $$ = new ParserVal($3.NodeCvt()); } else { yywarn("Compiler directive not understood"); $$ = null; } // HELP vfree($2); } | = { $$ = null; } ; Special : '(' ID ID UQSTRING ')' { if (!Globals.initflag) { yywarn("Compiler directive outside initialization"); } if ($2.NodeCvt() . id_str_table_index() == Initids.indx_standard) { int num_arg = 1; // HELP atoi($4); if ($3 . NodeCvt() . id_str_table_index() == Initids.indx_New) { $$ = special(Const.STD_NEW, num_arg); } else if ($3 . NodeCvt(). id_str_table_index() == Initids.indx_ptr_New) { $$ = special(Const.PTR_NEW, num_arg); } else if ($3 . NodeCvt() . id_str_table_index() == Initids.indx_init_New) { $$ = special(Const.INIT_NEW, num_arg); } else if ($3 . NodeCvt() . id_str_table_index() == Initids.indx_ValueOf) { $$ = special(Const.STD_VALUEOF, num_arg); } else if ($3 . NodeCvt() . id_str_table_index() == Initids.indx_assign) { $$ = special(Const.STD_ASSIGN, num_arg); } else if ($3 . NodeCvt() . id_str_table_index() == Initids.indx_put) { $$ = special(Const.STD_PUT, num_arg); } else if ($3 . NodeCvt() . id_str_table_index() == Initids.indx_Callcc) { $$ = special(Const.STD_CALLCC, num_arg); } else if ($3 . NodeCvt() . id_str_table_index() == Initids.indx_Array) { $$ = special(Const.STD_ARRAY, num_arg); } else if ($3 . NodeCvt() . id_str_table_index() == Initids.indx_passign) { $$ = special(Const.STD_PASSIGN, num_arg); } else if ($3 . NodeCvt() . id_str_table_index() == Initids.indx_massign) { $$ = special(Const.STD_MASSIGN, num_arg); } else { yywarn("Bad standard directive"); // HELP $$ = 0; $$ = null; } } else { yywarn("Compiler directive not understood"); $$ = null; } // HELP vfree($2); vfree($3); } ; FuncSignature : FUNC Special Opt.InLine '[' Opt.Parameter.list ']' Signature = { $$ = new ParserVal(new FSignature(Const.FUNCSIGNATURE,$3.NodeCvt(),$5.NodelstCvt(),$7.NodeCvt())); // HELP $$ . fsig_special = (int)$2; } | FUNC Opt.InLine '[' Opt.Parameter.list ']' Signature = { $$ = new ParserVal(new FSignature(Const.FUNCSIGNATURE,$2.NodeCvt(),$4.NodelstCvt(),$6.NodeCvt())); if ($2 != null) { /* Remember that this is a primitive other than put or callcc */ //HELP $$ . fsig_special = special(OTHER_BUILTIN, 0); } } ; Opt.TypeSignatureComponents : TypeSignatureComponents = { $$ = $1; } | = { $$ = new ParserVal(ListHeaderNode.emptylist()); } ; Opt.TypeSignatureComponent.list : Opt.TypeSignatureComponents = { $$ = $1; } | Opt.TypeSignatureComponent.list ';' Opt.TypeSignatureComponents = { $$ = ParserVal.conc($1,$3); } ; Opt.Id : ID = { $$ = $1; } | = { $$ = null; } ; TypeSignatureComponents : Id.list Opt.Colon Signature = { if ($2 == null) { yyperror("Missing colon in type component"); } // lock($1); lock($3); if ($3.NodeCvt() . kind == Const.VARSIGNATURE) { yyperror("Variable as type signature component"); } $$ = new ParserVal(Node.split(Const.TSCOMPONENT, $1.NodeCvt(), $3.NodeCvt(),null,null,null,null)); // vfree(unlock($1)); vfree(unlock($3)); } | Id.list Opt.Colon Opt.Readonly FIELD BasicDenotation = { Node vl_field_sig; Node vr_field_sig; if ($2 == null) { yyperror("Missing colon in field specification"); } vl_field_sig = new FSignature(Const.FUNCSIGNATURE, null, /* in-line code */ new ParserVal(ListHeaderNode.mklist(new ParameterNode(Const.PARAMETER, null, new ValSignature(Const.VALSIGNATURE, new LetterId(Const.LETTERID,-1))) )).NodelstCvt(), new ValSignature(Const.VALSIGNATURE, $5.NodeCvt())); // lock($1); lock($5); if ( ParserVal.is_present($3) ) { $$ = new ParserVal(Node.split(Const.TSCOMPONENT,$1.NodeCvt(),Globals.vl_field_sig,null,null,null,null)); } else { vr_field_sig = new FSignature(Const.FUNCSIGNATURE, null, /* in-line code */ new ParserVal(ListHeaderNode.mklist(new ParameterNode(Const.PARAMETER, null, new VarSignature(Const.VARSIGNATURE, new LetterId(Const.LETTERID,-1))) )).NodelstCvt(), new VarSignature(Const.VARSIGNATURE, $5.NodeCvt())); $$ = ParserVal.conc(new ParserVal(Node.split(Const.TSCOMPONENT,$1.NodeCvt(),Globals.vl_field_sig,null,null,null,null)), new ParserVal(Node.split(Const.TSCOMPONENT,$1.NodeCvt(),Globals.vr_field_sig,null,null,null,null))); } // vfree(unlock($1)); vfree(unlock($5)); } | ID = { int i; Node result = null; switch ($1.NodeCvt() . kind) { case Const.OPRID: i = $1 . NodeCvt() . id_str_table_index(); if ( i == Initids.indx_assign ) result = new TSComponentNode(Const.TSCOMPONENT,$1.NodeCvt(),Initids.sig_assign); else if (i == Initids.indx_less || i == Initids.indx_le ) result = new TSComponentNode(Const.TSCOMPONENT,$1.NodeCvt(),Initids.sig_less); else if ( i == Initids.indx_greater || i == Initids.indx_ge ) result = new TSComponentNode(Const.TSCOMPONENT,$1.NodeCvt(),Initids.sig_greater); else if ( i == Initids.indx_equals || i == Initids.indx_ne ) result = new TSComponentNode(Const.TSCOMPONENT,$1.NodeCvt(),Initids.sig_equals); else if ( i == Initids.indx_sconc ) result = new TSComponentNode(Const.TSCOMPONENT,$1.NodeCvt(),Initids.sig_sconc); else if ( i == Initids.indx_pconc ) result = new TSComponentNode(Const.TSCOMPONENT,$1.NodeCvt(),Initids.sig_pconc); else yyperror("Missing signature"); break; case Const.LETTERID: i = $1.NodeCvt() . id_str_table_index(); if ( i == Initids.indx_New ) result = new TSComponentNode(Const.TSCOMPONENT,$1.NodeCvt(),Initids.sig_New); else if ( i == Initids.indx_ValueOf ) result = new TSComponentNode(Const.TSCOMPONENT,$1.NodeCvt(),Initids.sig_ValueOf); else if ( (Stt.getname(i)).equals("\'")) /* quoted id */ result = new TSComponentNode(Const.TSCOMPONENT,$1.NodeCvt(),Initids.sig_const); else yyperror("Missing signature"); break; default: Mine.russinfo("parser: incorrect id structure"); } $$ = new ParserVal(ListHeaderNode.mklist(result)); } | CHARACTERS = { /* return a singleton list containing a DEFCHARSIGS node with */ /* all bits corresponding to valid RUSSELL characters set. */ /* Note machine dependence. */ $$ = new ParserVal(ListHeaderNode.mklist(new DefCharSigNode(Const.DEFCHARSIGS, Const.RCS0, Const.RCS1, Const.RCS2, Const.RCS3))); } | error { yyperror("Error in type signature component"); $$ = new ParserVal(ListHeaderNode.emptylist()); } ; Opt.Readonly : READONLY = { $$ = new ParserVal(true); } | = { $$ = new ParserVal(false); } ; Denotation : ManifestSignature { $$ = $1; } | BasicDenotation ; BasicDenotation: Primary.list = { // if (BADflag) // flcheck(0,0); // else // flcheck(0,1); // lock($1); $$ = new ParserVal(Mkappl.mkappl($1.NodeCvt())); // lock($$); // vfree(unlock($1)); // unlock($$); // if (Globals.bADflag) // flcheck(0,0); // else // flcheck(0,1); } | '\002' /* STX (marks the insertion place in a compiler initialization */ /* run) */ = { if (!Globals.initflag) { yyperror("use of insertion character in non-initialization run"); } else { $$ = Globals.insrtptr = new ParserVal(new BlDenotationNode(Const.BLOCKDENOTATION,ListHeaderNode.emptylist(),null)); //HELP Globals.insrtptr . bld_precedence = INFINITE; } } ; Primary.list : Primary = { $$ = new ParserVal(ListHeaderNode.mklist($1.NodeCvt())); } | ArgList { $$ = new ParserVal(ListHeaderNode.mklist($1.NodeCvt())); } | Primary.list Primary { $$ = new ParserVal(ListHeaderNode.addright(ListHeaderNode.ListHeaderNodeCvt($1.NodeCvt()),ListHeaderNode.ListHeaderNodeCvt($2.NodeCvt()))); } | Primary.list ArgList { $$ = new ParserVal(ListHeaderNode.addright(ListHeaderNode.ListHeaderNodeCvt($1.NodeCvt()),ListHeaderNode.ListHeaderNodeCvt($2.NodeCvt()))); } ; Primary : FuncConstruction { $$ = $1; } | Selection { $$ = $1; } | CAND { $$ = new ParserVal(new WordCandNode(Const.WORDCAND)); } | COR { $$ = new ParserVal(new WordCorNode(Const.WORDCOR)); } | TypeConstruction { $$ = $1; } | Primary TypeModifier { $$ = new ParserVal(new ModPrimaryNode(Const.MODPRIMARY,$1.NodeCvt(),$2.NodeCvt(),null)); } | '(' Denotation.seq ')' { int prec; Node p; if ( is_empty($2.NodeCvt()) ) { Mine.russinfo("parser: empty denotation seq\n"); abort(); } if (first($2) == last($2)) { /* just return the single denotation in the sequence */ $$ = new ParserVal(p = last($2)); // lock(p); //vfree($2); //unlock(p); } else { prec = Precedence.precedence( last($2) ); $$ = new ParserVal(p = new BlDenotationNode(Const.BLOCKDENOTATION,ListHeaderNode.emptylist(),$2.NodeCvt())); p.set_precedence( prec); } } | IF GuardedDenotation.list FI = { $$ = new ParserVal( new GuardedListNode(Const.GUARDEDLIST,$2.NodeCvt())); } | DO GuardedDenotation.list OD = { $$ = new ParserVal(new LoopDenotationNode(Const.LOOPDENOTATION,$2.NodeCvt())); } | LET Opt.Declaration.list IN Denotation.seq NI = { int prec; Node p; prec = Precedence.precedence( last($4) ); $$ = new ParserVal( p = new BlDenotationNode(Const.BLOCKDENOTATION,$2.NodeCvt(),$4.NodeCvt())); p . set_precedence(prec); } | USE Opt.Denotation.list IN Denotation.seq NI = { int prec; Node p; prec = Precedence.precedence( last($4) ); $$ = new ParserVal( p = new UseListNode(Const.USELIST,$2.NodeCvt(),$4.NodeCvt())); p.set_precedence (prec); } | EXTERN '{' QSTRING '}' = { // HELP has_externs = true; // HELP $$ = mknode(REXTERNDEF, read_signature($3), $3); // HELP $$ . sig_done = SIG_DONE; } ; Denotation.seq : Denotation.seq ';' Opt.Denotation = { $$ = new ParserVal(ListHeaderNode.addright(ListHeaderNode.ListHeaderNodeCvt($1.NodeCvt()),ListHeaderNode.ListHeaderNodeCvt($3.NodeCvt()))); } | Denotation = { $$ = new ParserVal(ListHeaderNode.mklist($1.NodeCvt())); } | error { int c; yyperror("Error in Expression Sequence"); for (c = yychar; !in(c, Globals.denseqstop); c = yylex()); yyclearin(); switch(c) { case ';': case '#': case FI: case ELSIF: case ELSE: case OD: case ')': case NI: case '}': yyunlex(c); break; case IF: case DO: case LET: case FUNC: case '(': yyunlex(c); yyunlex(';'); break; case WITH: yyunlex(c); yyunlex(WORDID); yyunlex(';'); break; case IN: yyunlex(c); yyunlex(LET); yyunlex(';'); break; case Lexer.EOF: System.exit(1); default: yyunlex(c); } if (yydebug) rec_on(c); $$ = new ParserVal(ListHeaderNode.mklist(Initids.id_Integer)); /* fake it */ } ; Opt.Denotation : Denotation = { $$ = $1; } | = { $$ = null; } ; FuncConstruction : IncompleteFuncSignature '{' Denotation.seq '}' = { if (($3.NodeCvt().length()) == 1) { $$ = new ParserVal(new FConstruction(Const.FUNCCONSTR,$1.NodeCvt(),first($3))); } else { $$ = new ParserVal(new FConstruction(Const.FUNCCONSTR,$1.NodeCvt(), new BlDenotationNode(Const.BLOCKDENOTATION,ListHeaderNode.emptylist(),$3.NodeCvt()))); // HELP $$.fc_body.bld_precedence = Const.INFINITE; /* doesn't matter */ } // HELP $1 . fsig_construction = $$; if (Globals.initflag) { /* Make sure that global functions receive the same name */ /* in all compilations. */ Integer djdno = new Integer(Globals.global_fn_count++); Globals.global_fn_count_str = djdno.toString(); String name = new String("fn_global_" + Globals.global_fn_count_str); // HELP $$ . fc_code_label = name; } } | IncompleteFuncSignature '{' EXTERN QSTRING '}' = { if ($1.NodeCvt() . fsig_result_sig() == null) { yyperror("Must specify result signature for extern"); } $$ = new ParserVal(new FConstruction(Const.FUNCCONSTR, $1.NodeCvt(), new ExternDefNode(Const.EXTERNDEF, $4.NodeCvt()))); } ; IncompleteFuncSignature : FuncSignature = { $$ = $1; } | FUNC Special Opt.InLine '[' Opt.Parameter.list ']' = { $$ = new ParserVal(new FSignature(Const.FUNCSIGNATURE, $3.NodeCvt(), $5.NodelstCvt(), null)); // HELP!!! $$ . NodeCvt().set_fsig_special($2); } | FUNC Opt.InLine '[' Opt.Parameter.list ']' = { $$ = new ParserVal(new FSignature(Const.FUNCSIGNATURE, $2.NodeCvt(), $4.NodelstCvt(), null)); } ; Selection : Primary '$' ID Opt.SigClause = { // HELP initfld(($3.sel_type), $1); // HELP initfld(($3.signature), $4); $$ = $3; } | Primary '$' STRING = { //HELP initfld(($3.sel_type), $1); $$ = $3; } | ID Opt.SigClause = { // HELP initfld(($1.signature), $2); $$ = $1; } | STRING = { $$ = $1; } ; TypeConstruction : Enumeration = { $$ = $1; } | Record = { $$ = $1; } | Extension = { $$ = $1; } | Product = { $$ = $1; } | Union = { $$ = $1; } ; Guard : Denotation = { $$ = $1; } | ELSE = { $$ = new ParserVal(new WordElseNode(Const.WORDELSE)); } | error { yyperror("Error while trying to parse guard"); } ; ArgList : '[' Opt.Denotation.list ']' = { $$ = $2; } ; Opt.Denotation.list : Denotation = { $$ = new ParserVal(ListHeaderNode.mklist($1.NodeCvt())); } | Denotation ',' Opt.Denotation.list = { $$ = new ParserVal(ListHeaderNode.addleft(ListHeaderNode.ListHeaderNodeCvt($3.NodeCvt()),ListHeaderNode.ListHeaderNodeCvt($1.NodeCvt()))); } | = { $$ = new ParserVal(ListHeaderNode.emptylist()); } ; Opt.Declaration.list : Opt.Declarations = { $$ = $1; } | Opt.Declaration.list ';' Opt.Declarations = { $$ = ParserVal.conc($1,$3); } ; Opt.Declarations : Id.list Opt.ColonSignature EQUALS_EQUALS Denotation = { // lock($1); lock($2); lock($4); $$ = new ParserVal(Node.split(Const.DECLARATION,$1.NodeCvt(),$4.NodeCvt(),$2.NodeCvt(),null,null,null)); // vfree(unlock($1)); vfree(unlock($2)); vfree(unlock($4)); } | Id.list Opt.ColonSignature EQUALS_EQUALS_EQUALS Denotation = { Node q; // lock($1); lock($2); lock($4); $$ = new ParserVal(q = Node.split(Const.DECLARATION,$1.NodeCvt(),$4.NodeCvt(),$2.NodeCvt(),null,null,null)); // HELP!!! maplist(p, q, { // HELP!!! p . decl_sig_transp = true; // HELP!!!}); // vfree(unlock($1)); vfree(unlock($2)); vfree(unlock($4)); } | = { $$ = new ParserVal(ListHeaderNode.emptylist()); } | error { int c; int i = 0; yyperror("Error in declaration"); for ( c = yychar; !in(c, declstop); c = yylex() ) if ( ++i > maxskip ) break; yyclearin(); switch (c) { case EQUALS_EQUALS: yyunlex(c); yyunlex(WORDID); yyunlex(';'); break; case ';' : case '}' : case IN: yyunlex(c); break; case NI: yyunlex(c); yyunlex(WORDID); yyunlex(IN); break; case IF: case DO: case LET: case '(': yyunlex(c); yyunlex(EQUALS_EQUALS); yyunlex(WORDID); break; case Lexer.EOF: System.exit(1); default : yyunlex(c); yyunlex(NI); yyunlex(IN); } if (yydebug) rec_on(c); $$ = new ParserVal(ListHeaderNode.emptylist()); } ; Opt.ColonSignature : Opt.Colon Signature = { $$ = $2; } | = { $$ = null; } ; Enumeration : ENUM '{' Id.list '}' = { $$ = new ParserVal(new EnumerationNode(Const.ENUMERATION,$3.NodeCvt())); } ; Extension : EXTEND '{' Denotation '}' = { $$ = new ParserVal(new ExtensionNode(Const.EXTENSION,$3.NodeCvt())); } ; Product : PROD Opt.Id '{' Opt.Parameter.list '}' = { // HELP!!! maplist (s, $4, { // HELP!!! if (s . par_id == null) { // HELP!!! yyperror("Anonymous fields not allowed in product"); // HELP!!! } // HELP!!!}); $$ = new ParserVal(new ProductNode(Const.PRODCONSTRUCTION,$2.NodeCvt(),$4.NodeCvt())); } | PROD error { yyperror("Error in product construction"); } ; Record : RECORD '{' Opt.RecordElement.list '}' = { $$ = new ParserVal(new RecordConstructionNode(Const.RECORDCONSTRUCTION,$3.NodeCvt())); } | RECORD error { yyperror("Error in record construction"); } ; Union : UNION Opt.Id '{' Opt.Parameter.list '}' = { // HELP!!! maplist (s, $4, { // HELP!!! if (s . par_id == null) { // HELP!!! yyperror("Anonymous fields not allowed in union"); // HELP!!! } // HELP!!!}); $$ = new ParserVal(new UnionConstructionNode(Const.UNIONCONSTRUCTION,$2.NodeCvt(),$4.NodeCvt())); } | UNION error { yyperror("Error in union construction"); } ; Opt.RecordElement.list : Opt.RecordElements = { $$ = $1; } | Opt.RecordElement.list ';' Opt.RecordElements = { $$ = ParserVal.conc($1,$3); } ; Opt.RecordElements : RecordElements = { $$ = $1; } | = { $$ = new ParserVal(ListHeaderNode.emptylist()); } ; RecordElements : Id.list Opt.Colon Denotation = { if ($2.NodeCvt() != null) { yyperror("Missing colon in record element specification"); } // lock($1); lock($3); $$ = new ParserVal(Node.split(Const.RECORDELEMENT,$1.NodeCvt(),$3.NodeCvt(),null,null,null,null)); // vfree(unlock($1)); vfree(unlock($3)); } ; TypeModifier : WithList = { $$ = $1; } | ExportList = { $$ = $1; } ; WithList : WITH Opt.Id '{' Opt.Declaration.list '}' = { $$ = new ParserVal(new WithListNode(Const.WITHLIST,$2.NodeCvt(),$4.NodeCvt())); } | WITH error { yyperror("Error in \"with\" type modification"); } ; ExportList : Start.ExportList Opt.Id '{' ExportElement.list '}' = { // HELP $$ = mknode($1,$2,$4); } | EXPORT error { yyperror("Error in \"export\" type modification"); } | HIDE error { yyperror("Error in \"hide\" type modification"); } ; Start.ExportList : EXPORT = { // HELP $$ = EXPORTLIST; } | HIDE = { // HELP $$ = HIDELIST; } ; ExportElement.list : ExportElement = { // HELP $$ = ListHeaderNode.mklist($1.NodeCvt()); } | ExportElement ';' ExportElement.list = { $$ = new ParserVal(ListHeaderNode.addleft(ListHeaderNode.ListHeaderNodeCvt($3.NodeCvt()),ListHeaderNode.ListHeaderNodeCvt($1.NodeCvt()))); } | = { $$ = new ParserVal(ListHeaderNode.emptylist()); } ; ExportElement : ID Opt.SigClause Opt.ExportList = { $$ = new ParserVal(new ExportElementNode(Const.EXPORTELEMENT,$1.NodeCvt(),$2.NodeCvt(),$3.NodeCvt())); } | CONSTANTS = { $$ = new ParserVal(new AllConstantsNode(Const.ALLCONSTANTS)); } | error { yyperror("Error in \"export\"ed or hidden element specification"); } ; Opt.ExportList : ExportList = { $$ = $1; } | = { $$ = null; } ; Opt.SigClause : LEFT_ANGLE_BRACKET Signature RIGHT_ANGLE_BRACKET = { $$ = $2; } | = { $$ = null; } ; Opt.ElseList : ElseList { $$ = $1; } | { // Node appl_Null; $$ = new ParserVal(Initids.appl_Null); } ; ElseList : ELSE Denotation.seq { if (($2.NodeCvt().length()) == 1) { $$ = new ParserVal(first($2)); } else { Node p = new BlDenotationNode(Const.BLOCKDENOTATION,ListHeaderNode.emptylist(),$2.NodeCvt()); $$ = new ParserVal(p); // HELP p . bld_precedence = INFINITE; /* doesnt matter */ } } | ELSIF Denotation THEN Denotation.seq Opt.ElseList { Node ge1; /* First guarded element */ Node ge2; /* Second guarded element */ if (($4.NodeCvt().length()) == 1) { ge1 = new GuardedElementNode(Const.GUARDEDELEMENT,$2.NodeCvt(),first($4)); } else { ge1 = new GuardedElementNode(Const.GUARDEDELEMENT,$2.NodeCvt(), new BlDenotationNode(Const.BLOCKDENOTATION,ListHeaderNode.emptylist(),$4.NodeCvt())); // HELP ge1.ge_element.bld_precedence = INFINITE; /* doesn't matter */ } /* $5 is a denotation to be executed if orignal */ /* guard does not apply */ ge2 = new GuardedElementNode(Const.GUARDEDELEMENT, new WordElseNode(Const.WORDELSE), $5.NodeCvt()); // OLD (HELP) $$ = ParserVal(new GuardedElementNode(Const.GUARDEDLIST, ListHeaderNode.mklist(ge1, ge2))); $$ = new ParserVal(new GuardedElementNode(Const.GUARDEDLIST, ge1,ge2)); } ; GuardedDenotation.list : GuardedDenotation = { $$ = new ParserVal(ListHeaderNode.mklist($1.NodeCvt())); } | GuardedDenotation.list '#' GuardedDenotation = { $$ = new ParserVal(ListHeaderNode.addright(ListHeaderNode.ListHeaderNodeCvt($1.NodeCvt()),ListHeaderNode.ListHeaderNodeCvt($3.NodeCvt()))); } | Denotation THEN Denotation.seq Opt.ElseList { Node ge1; /* First guarded element */ Node ge2; /* Second guarded element */ if (($3.NodeCvt().length()) == 1) { ge1 = new GuardedElementNode(Const.GUARDEDELEMENT,$1.NodeCvt(),first($3)); } else { ge1 = new GuardedElementNode(Const.GUARDEDELEMENT,$1.NodeCvt(), new BlDenotationNode(Const.BLOCKDENOTATION,ListHeaderNode.emptylist(),$3.NodeCvt())); //HELP ge1.ge_element.bld_precedence = INFINITE; /* doesn't matter */ } /* $4 is a denotation to be executed if orignal */ /* guard does not apply */ ge2 = new GuardedElementNode(Const.GUARDEDELEMENT, new WordElseNode(Const.WORDELSE), $4.NodeCvt()); $$ = new ParserVal(ListHeaderNode.mklist(ge1, ge2)); } | error { int i = 0; int c; yyperror("Error in Loop or If"); for (c = yychar; !in(c,condstop); c = yylex() ) if ( ++i > maxskip ) break; yyclearin(); switch(c) { case '#' : case FI : case OD : yyunlex(c); break; case RIGHT_ARROW : case ELSE : case THEN : case ';' : yyunlex(RIGHT_ARROW); yyunlex(WORDID); yyunlex('#'); break; case LET : case '(' : case DO : case IF : yyunlex(c); yyunlex(RIGHT_ARROW); yyunlex(WORDID); yyunlex('#'); break; case Lexer.EOF: System.exit(1); default : yyunlex(c); yyunlex(END); } if (yydebug) rec_on(c); $$ = new ParserVal(ListHeaderNode.emptylist()); } ; GuardedDenotation : Guard RIGHT_ARROW Denotation.seq = { if (($3.NodeCvt().length()) == 1) { $$ = new ParserVal(new GuardedElementNode(Const.GUARDEDELEMENT,$1.NodeCvt(),first($3))); } else { Node p = new GuardedElementNode(Const.GUARDEDELEMENT,$1.NodeCvt(), new BlDenotationNode(Const.BLOCKDENOTATION,ListHeaderNode.emptylist(),$3.NodeCvt())); $$ = new ParserVal(p); //HELP p.ge_element.bld_precedence = INFINITE; /* doesn't matter */ } } ; ID : WORDID = { $$ = new ParserVal(new LetterId(Const.LETTERID,$1.NodeCvt())); } | OPID = { $$ = new ParserVal(new OpridNode(Const.OPRID,$1.NodeCvt())); } ; STRING : QSTRING = { $$ = new ParserVal(new QStrNode(Const.QSTR,$1.NodeCvt())); } | UQSTRING = { $$ = new ParserVal(new UQStrNode(Const.UQSTR,$1.NodeCvt())); } ; %% private static void abort() { Mine.russinfo("Parser: Aborting"); System.exit(0); } private static int yylex() { return Lexer.yylex(); } private static Node first(ParserVal l) { Object obj = l.obj; ListHeaderNode it = ListHeaderNode.class.cast(obj); Node it2 = Node.class.cast(it.lh_first()); // Node it = Node.class.cast(l.obj.lh_first.cn_hd_field); return it2; } private static Node last(ParserVal l) { Object obj = l.obj; ListHeaderNode it = ListHeaderNode.class.cast(obj); Node it2 = Node.class.cast(it.lh_last()); // Node it = Node.class.cast(l.obj.lh_first.cn_hd_field); return it2; } private boolean is_empty(Node it) { return (it == null); } private static int[] condstop = new int[] /* stop symbols for error recovery in various */ /* conditional constructs */ { Lexer.OD, Lexer.FI, Lexer.RIGHT_ARROW, '#', ';', Lexer.LET, Lexer.DO, Lexer.IF, Lexer.THEN, Lexer.ELSE, '(', Lexer.EOF, Lexer.LIST_END }; private static int[] declstop = new int[] /* stop symbols for error recovery in declarations */ { Lexer.EQUALS_EQUALS, Lexer.EQUALS_EQUALS_EQUALS, ';', '}', Lexer.IN, Lexer.NI, Lexer.IF, Lexer.DO, Lexer.LET, '(', Lexer.EOF, Lexer.LIST_END }; private static int[] paramstop = new int[] { ';', ']', '{', Lexer.VAR, Lexer.VAL, Lexer.FUNC, Lexer.TYPE, Lexer.SIGNATURE, Lexer.EOF, Lexer.LIST_END }; private static int maxskip = 8; private static void yywarn(String str) { Lexer.yywarn(str); } private static void yyerror(String str) { Lexer.yyerror(str); } private static void yyperror(String str) { Lexer.yyperror(str); } private static boolean in(int element,int list[]) { int i; int LIST_END = 0x7fff; i = 0; while (element != list[i] && list[i] != LIST_END) ++i; return (element == list[i]); } private static void rec_on(int c) { if ( c < 0400 ) { // Mine.russinfo ( "recovery attempted on %c\n", c); Mine.russinfo ( "recovery attempted on %c\n"); } else { // Mine.russinfo ( "recovery attempted on token number %d\n", c); Mine.russinfo ( "recovery attempted on token number %d\n"); } } public static void yyclearin() { } public static void yyunlex(int ch) { } public static ParserVal special(int a, int b) { ParserVal x; x = null; return x; }