Path: utzoo!utgpu!cs.utexas.edu!uunet!crdgw1!barnett From: barnett@grymoire.crd.ge.com (Bruce Barnett) Newsgroups: alt.sources Subject: Ease 3.0: High Level Language for Sendmail (Part 4 of 6) Message-ID: Date: 23 Feb 91 07:17:20 GMT Sender: news@crdgw1.crd.ge.com Reply-To: barnett@crdgw1.ge.com Distribution: alt Organization: GE Corp. R & D, Schenectady, NY Lines: 1178 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh src/parser.y <<'END_OF_src/parser.y' X%{ X#ifdef FLUKE X# ifndef LINT X static char RCSid[] = "@(#)FLUKE $Header: /tmp_mnt/home/kreskin/u0/barnett/Src/Ease/ease/src/RCS/parser.y,v 3.0 1991/02/22 18:50:27 barnett Exp $"; X# endif LINT X#endif FLUKE X X/* X * parser.y -- EASE parser. X * X * Contains code for yacc(1) which produces a parser (y.tab.c) X * for Ease, a specification format for sendmail configuration X * files. X * X * author -- James S. Schoner, Purdue University Computing Center, X * West Lafayette, Indiana 47907 X * X * date -- July 2, 1985 X * X * Copyright (c) 1985 by Purdue Research Foundation X * X * All rights reserved. X * X * $Log: parser.y,v $ X * Revision 3.0 1991/02/22 18:50:27 barnett X * Added support for HP/UX and IDA sendmail. X * X * Revision 2.1 1990/01/30 15:48:35 jeff X * Added SunOS/Ultrix/IDA extensions Jan 24, 1989 Bruce Barnett X * X * Version 2.0 90/01/30 15:44:34 jeff X * Baseline release for netwide posting. X * X */ X X#include "fixstrings.h" X#include X#include "symtab.h" X#include Xextern void BindID (); Xextern void EmitDef (); Xextern char *ListAppend (); Xextern char *MakeCond (); Xextern char *MakeRStr (); Xextern char *ConvOpt (); Xextern char *ConvFlg (); Xextern char *MacScan (); Xextern char *ConvMat (); Xextern void StartRuleset (); Xextern char *MakePosTok (); Xextern char *GetField (); Xextern char *Bracket (); Xextern char *MakeRSCall (); Xextern char *CheckMailer (); Xextern char *CheckRS (); Xextern char *MakeField (); Xextern char MakeMac (); Xextern void AssignType (); Xextern void RemoveSymbol (); Xextern void yyerror (); X Xextern short RMatch; /* ruleset match flag */ X Xchar *Cbuf = " "; /* character buffer */ Xchar *Mbuf = "$ "; /* macro buffer */ Xchar *Tsb; /* pointer to temporary string buffer */ Xchar *Tsb1; /* pointer to another temporary string buffer */ Xchar *Flaglist; /* pointer to header flag list */ X X#define DIM(x) (sizeof x/sizeof x[0]) Xextern int yychar; Xextern int yydebug; X Xstatic char * Xyydisplay(ch) X register int ch; X{ X static char buf[15]; X static char * token[] = { X#include "y.tok.h" X 0 }; X X switch (ch) { X case 0: X return "[end of file]"; X/* YYERRCODE is 256. See below */ X/* case YYERRCODE: X return "[error]"; */ X case '\b': X return "'\\b'"; X case '\f': X return "'\\f'"; X case '\n': X return "'\\n'"; X case '\r': X return "'\\r'"; X case '\t': X return "'\\t'"; X } X /* I should use YYERRCODE - but it hasn't been defined yet */ X /* when /usr/lib/yaccpar is added to this file, it will be defined */ X if (ch == 256 ) return ("[error]"); X if (ch > 256 && ch < 256 + DIM(token)) X return token[ch - 257]; X if (isascii(ch) && isprint(ch)) X sprintf(buf, "'%c'",ch); X else if (ch < 256) X sprintf(buf, "Char %o4.3o", ch); X else X sprintf(buf, "token %d", ch); X return buf; X} Xstatic yyyylex() X{ X if (yychar < 0) { X /* don't make this match =yylex - because sed changes X =yylex to =yyyylex in the Makefile. X the pieces it changes is in /usr/lib/yaccparr and I don't X want to modify THAT! - bgb */ X X if ((yychar = yylex ()) < 0) /* call yylex, not yyyylex */ X yychar = 0; X#ifdef YYDEBUG X if (yydebug) X printf("[yydebug] reading %s\n", X yydisplay(yychar)); X#endif X return yychar; X } X} X X X%} X X%union { /* value stack element type */ X int ival; /* integer token */ X char *psb; /* string token */ X struct he *phe; /* pointer to hash entry */ X enum opts optval; /* sendmail options */ X enum flgs flgval; /* mailer flags */ X enum mats mpval; /* mailer attribute parameters */ X} X X%start config X X%token IDENT X%token SCONST X%token ICONST SEPCHAR X%token BIND CANON CLASS CONCAT FOR HEADER HOST HOSTNUM IF IFSET IN X%token MACRO MAILER MAP MARGV MATCH MEOL MFLAGS MMAXSIZE MPATH X%token MRECIPIENT MSENDER NEXT OPTIONS PRECEDENCE READCLASS RESOLVE X%token RETRY RETURN RULESET TRUSTED USER X%token YPALIAS YPMAP YPPASSWD EVAL RESOLVED QUOTE ASM PROGRAM DEFAULT ALIAS X X%token ASGN COLON COMMA DEFINE DOLLAR FIELD LBRACE LPAREN RBRACE X%token RPAREN SEMI STAR SLASH X X%token AAOPT AOPT BBOPT CCOPT COPT DDOPT DOPT DOPTB DOPTI DOPTQ EOPT X%token EOPTE EOPTM EOPTP EOPTW EOPTZ FFOPT FOPT GOPT HHOPT IOPT LLOPT X%token MOPT NNOPT NOPT OOPT PPOPT QOPT QQOPT ROPT SOPT SSOPT TOPT TTOPT X%token UOPT VOPT WWOPT XOPT XXOPT YOPT YYOPT ZOPT ZZOPT X%token RROPT BOPT SLOPT HOPT IIOPT X X%token AAFLAG CCFLAG DDFLAG EEFLAG EFLAG FFFLAG FFLAG HFLAG IIFLAG LFLAG X%token LLFLAG MFLAG MMFLAG NFLAG PFLAG PPFLAG RFLAG RRFLAG SFLAG SSFLAG X%token UFLAG UUFLAG XFLAG XXFLAG X%token HHFLAG VVFLAG BBFLAG X X%type mval strval ifcon conval ifres elseres nameset namelist X%type doptid eoptid idlist fcond dlist mflags route mdefs X%type matchaddr matchtok action actionstmt mailerspec mtdef X%type rwaddr rwtok ftype reftok rword cantok resolution X%type userspec hword hostid dheader mdefine X%type catstring catstringlist canval canvaltok X%type anychar X%type cdef X%type optid X%type flagid X%type mvar X X%left COMMA X%left LPAREN RPAREN X%nonassoc SCONST X X%% Xconfig : /* empty */ X | config blockdef X | error blockdef X ; X Xblockdef : BIND bindings X | MACRO macdefs X | CLASS classdefs X | OPTIONS optdefs X | PRECEDENCE precdefs X | TRUSTED tlist X | HEADER hdefs X | MAILER mlist X | RULESET rdef X | FIELD fdefs X ; X Xbindings : /* empty */ X | bindings IDENT ASGN RULESET ICONST SEMI { X BindID ($2, $5, ID_RULESET); X } X | error SEMI { X yyerrok; X } X ; X Xmacdefs : /* empty */ X | macdefs IDENT ASGN mdefine SEMI { X EmitDef (def_macro, $2, $4, (char *) NULL); X } X | error SEMI { X yyerrok; X } X ; X X/* macro value X * can be string X * or ifset() X * or concat X */ Xmdefine : mval { X $$ = $1; X } X | IFSET LPAREN IDENT COMMA ifres RPAREN { X $$ = MakeCond ($3, MacScan($5)); X } X ; Xmval : strval %prec COMMA { X $$ = $1; X } X | CONCAT LPAREN conval RPAREN { X $$ = $3; X } X ; X Xstrval : SCONST { X $$ = $1; X } X | strval SCONST { X $$ = ListAppend ($1, $2, (char *) NULL); X free ($1); X } X ; X X/* conval specifies what can be in a concat() function */ Xconval : strval COMMA ifcon { X $$ = ListAppend ($1, $3, (char *) NULL); X free ($1); X free ($3); X } X | ifcon COMMA strval { X $$ = ListAppend ($1, $3, (char *) NULL); X free ($1); X free ($3); X } X | ifcon { X $$ = $1; X } X | error { X $$ = NULL; X } X ; X Xifcon : IFSET LPAREN IDENT COMMA ifres RPAREN { X $$ = MakeCond ($3, MacScan($5)); X } X ; X Xifres : mval elseres { X if ($2 != NULL) { X $$ = ListAppend ($1, $2, "$|"); X free ($1); X free ($2); X } else X $$ = $1; X } X | error { X $$ = NULL; X } X ; X Xelseres : /* empty */ { X $$ = NULL; X } X | COMMA mval { X $$ = $2; X } X ; X Xclassdefs : /* empty */ X | classdefs IDENT ASGN nameset { X EmitDef (def_class, $2, $4, (char *) NULL); X } X | classdefs ASM LPAREN SCONST RPAREN SEMI { X printf("%s\n",$4); X } X | error X ; X Xnameset : LBRACE namelist RBRACE SEMI { X $$ = $2; X } X | LBRACE RBRACE SEMI { X $$ = NULL; X } X | LBRACE error RBRACE SEMI { X $$ = NULL; X } X | READCLASS LPAREN strval RPAREN SEMI { X $$ = MakeRStr ($3, (char *) NULL); X } X | READCLASS LPAREN strval COMMA strval RPAREN SEMI { X $$ = MakeRStr ($3, $5); X } X | READCLASS LPAREN error RPAREN SEMI { X $$ = NULL; X } X | error SEMI { X $$ = NULL; X yyerrok; X } X ; X Xnamelist : IDENT { X $$ = ListAppend ($1->psb, (char *) NULL, (char *) NULL); X RemoveSymbol ($1); X } X | strval { X $$ = $1; X } X | namelist COMMA IDENT { X $$ = ListAppend ($1, $3->psb, " "); X free ($1); X RemoveSymbol ($3); X } X | namelist COMMA strval { X $$ = ListAppend ($1, $3, " "); X free ($1); X free ($3); X } X ; X Xoptdefs : /* empty */ X | optdefs optid ASGN strval SEMI { X EmitDef (def_option, (struct he *) NULL, ConvOpt ($2), $4); X } X | optdefs DOPT ASGN doptid SEMI { X EmitDef (def_option, (struct he *) NULL, ConvOpt (opt_d), $4); X } X | optdefs EOPT ASGN eoptid SEMI { X EmitDef (def_option, (struct he *) NULL, ConvOpt (opt_e), $4); X } X | optdefs ASM LPAREN SCONST RPAREN SEMI { X printf("%s\n",$4); X } X | error SEMI { X yyerrok; X } X ; X Xoptid : AAOPT { X $$ = opt_A; X } X | AOPT { X $$ = opt_a; X } X | BBOPT { X $$ = opt_B; X } X | BOPT { X $$ = opt_b; X } X | CCOPT { X $$ = opt_C; X } X | COPT { X $$ = opt_c; X } X | DDOPT { X $$ = opt_D; X } X | FFOPT { X $$ = opt_F; X } X | FOPT { X $$ = opt_f; X } X | GOPT { X $$ = opt_g; X } X | HOPT { X $$ = opt_h; X } X | HHOPT { X $$ = opt_H; X } X | IOPT { X $$ = opt_i; X } X | IIOPT { X $$ = opt_I; X } X | LLOPT { X $$ = opt_L; X } X | MOPT { X $$ = opt_m; X } X | NNOPT { X $$ = opt_N; X } X | NOPT { X $$ = opt_n; X } X | PPOPT { X $$ = opt_P; X } X | OOPT { X $$ = opt_o; X } X | QQOPT { X $$ = opt_Q; X } X | QOPT { X $$ = opt_q; X } X | ROPT { X $$ = opt_r; X } X | RROPT { X $$ = opt_R; X } X | SSOPT { X $$ = opt_S; X } X | SOPT { X $$ = opt_s; X } X | TTOPT { X $$ = opt_T; X } X | TOPT { X $$ = opt_t; X } X | UOPT { X $$ = opt_u; X } X | VOPT { X $$ = opt_v; X } X | WWOPT { X $$ = opt_W; X } X | XOPT { X $$ = opt_x; X } X | XXOPT { X $$ = opt_X; X } X | YOPT { X $$ = opt_y; X } X | YYOPT { X $$ = opt_Y; X } X | ZOPT { X $$ = opt_z; X } X | ZZOPT { X $$ = opt_Z; X } X | SLOPT { X $$ = opt_SL; /* SLASH .e.g. O/ in IDA */ X } X ; X Xdoptid : DOPTI { X $$ = ConvOpt (d_opt_i); X } X | DOPTB { X $$ = ConvOpt (d_opt_b); X } X | DOPTQ { X $$ = ConvOpt (d_opt_q); X } X ; X Xeoptid : EOPTP { X $$ = ConvOpt (e_opt_p); X } X | EOPTE { X $$ = ConvOpt (e_opt_e); X } X | EOPTM { X $$ = ConvOpt (e_opt_m); X } X | EOPTW { X $$ = ConvOpt (e_opt_w); X } X | EOPTZ { X $$ = ConvOpt (e_opt_z); X } X ; X Xprecdefs : /* empty */ X | precdefs IDENT ASGN ICONST SEMI { X BindID ($2, $4, ID_PREC); X EmitDef (def_prec, $2, (char *) NULL, (char *) NULL); X } X ; X Xtlist : /* empty */ X | tlist LBRACE IDENT idlist RBRACE SEMI { X EmitDef (def_trusted, (struct he *) NULL, X ListAppend ($3->psb, $4, " "), (char *) NULL); X free ($4); X RemoveSymbol ($3); X } X | tlist LBRACE RBRACE SEMI X | error SEMI { X yyerrok; X } X ; X Xhdefs : /* empty */ X | hdefs FOR fcond dheader SEMI { X EmitDef (def_header, (struct he *) NULL, $3, $4); X } X | hdefs FOR fcond LBRACE { Flaglist = $3; } X dheaders RBRACE SEMI X | hdefs DEFINE dlist SEMI { X EmitDef (def_header, (struct he *) NULL, (char *) NULL, $3); X } X | error SEMI { X yyerrok; X } X ; X Xfcond : LPAREN RPAREN { X $$ = NULL; X } X | LPAREN mflags RPAREN { X $$ = $2; X } X | LPAREN error RPAREN { X $$ = NULL; X } X ; X Xmflags : flagid { X $$ = ListAppend (ConvFlg ($1), (char *) NULL, (char *) NULL); X } X | mflags COMMA flagid { X $$ = ListAppend ($1, ConvFlg($3), (char *) NULL); X free ($1); X } X ; X Xflagid : FFLAG { X $$ = flg_f; X } X | RFLAG { X $$ = flg_r; X } X | SSFLAG { X $$ = flg_S; X } X | NFLAG { X $$ = flg_n; X } X | LFLAG { X $$ = flg_l; X } X | SFLAG { X $$ = flg_s; X } X | MFLAG { X $$ = flg_m; X } X | FFFLAG { X $$ = flg_F; X } X | DDFLAG { X $$ = flg_D; X } X | MMFLAG { X $$ = flg_M; X } X | XFLAG { X $$ = flg_x; X } X | PPFLAG { X $$ = flg_P; X } X | UFLAG { X $$ = flg_u; X } X | HFLAG { X $$ = flg_h; X } X | AAFLAG { X $$ = flg_A; X } X | BBFLAG { X $$ = flg_B; X } X | UUFLAG { X $$ = flg_U; X } X | EFLAG { X $$ = flg_e; X } X | XXFLAG { X $$ = flg_X; X } X | LLFLAG { X $$ = flg_L; X } X | PFLAG { X $$ = flg_p; X } X | IIFLAG { X $$ = flg_I; X } X | CCFLAG { X $$ = flg_C; X } X | EEFLAG { X $$ = flg_E; X } X | RRFLAG { X $$ = flg_R; X } X | HHFLAG { X $$ = flg_H; X } X | VVFLAG { X $$ = flg_V; X } X ; X Xdheader : /* empty */ { X $$ = NULL; X } X | DEFINE dlist { X $$ = $2; X } X | error { X $$ = NULL; X } X ; X Xdheaders : /* empty */ X | dheaders DEFINE dlist SEMI { X EmitDef (def_header, (struct he *) NULL, Flaglist, $3); X } X | dheaders ASM LPAREN SCONST RPAREN SEMI { X printf("%s\n",$4); X } X | error X ; X Xdlist : LPAREN strval COMMA catstringlist RPAREN { X $$ = ListAppend ($2, MacScan ($4), " "); X free ($2); X free ($4); X } X | LPAREN error RPAREN { X $$ = NULL; X } X ; X Xcatstringlist : catstring { X $$ = $1; X } X | catstring COMMA catstringlist { X $$ = ListAppend( $1, $3, (char *) NULL); X free($1); X } Xcatstring : SCONST { X $$ = $1; X } X | CONCAT LPAREN conval RPAREN { X $$ = $3; X } X | ifcon { X $$ = $1; X } X ; X Xmlist : /* empty */ X | mlist IDENT LBRACE mdefs RBRACE SEMI { X EmitDef (def_mailer, $2, $4, (char *) NULL); X } X | mlist IDENT LBRACE RBRACE SEMI { X EmitDef (def_mailer, $2, (char *) NULL, (char *) NULL); X } X | error SEMI { X yyerrok; X } X ; X Xmdefs : mtdef { X $$ = $1; X } X | mdefs COMMA mtdef { X $$ = ListAppend ($1, $3, ", "); X free ($1); X free ($3); X } X ; X Xmtdef : mvar ASGN mval { X $$ = ListAppend (ConvMat ($1), MacScan ($3), "="); X free ($3); X } X | MFLAGS ASGN LBRACE mflags RBRACE { X $$ = ListAppend (ConvMat (mat_flags), $4, "="); X } X | MSENDER ASGN IDENT { X $$ = ListAppend (ConvMat (mat_sender), CheckRS ($3), "="); X } X | MSENDER ASGN IDENT SLASH IDENT { X $$ = ListAppend( X Tsb = ListAppend (ConvMat(mat_sender), CheckRS ($3), "="), X Tsb1 = ListAppend ("/", CheckRS ($5), (char *) NULL), X (char *) NULL); X free (Tsb); X free (Tsb1); X } X | MRECIPIENT ASGN IDENT { X $$ = ListAppend (ConvMat (mat_recipient), CheckRS ($3), "="); X } X | MRECIPIENT ASGN IDENT SLASH IDENT { X $$ = ListAppend( X Tsb = ListAppend (ConvMat(mat_recipient), CheckRS ($3), "="), X Tsb1 = ListAppend ("/", CheckRS ($5), (char *) NULL), X (char *) NULL); X free (Tsb); X free (Tsb1); X } X | error { X $$ = NULL; X } X ; X Xmvar : MPATH { X $$ = mat_path; X } X | MARGV { X $$ = mat_argv; X } X | MEOL { X $$ = mat_eol; X } X | MMAXSIZE { X $$ = mat_maxsize; X } X ; X Xrdef : /* empty */ X | rdef IDENT { StartRuleset ($2); } rulelist X ; X Xrulelist : LBRACE ruledefs RBRACE { X RMatch = FALSE; X } X | error { X RMatch = FALSE; X } X ; X Xruledefs : /* empty */ { X RMatch = TRUE; X } X | ruledefs IF LPAREN matchaddr RPAREN actionstmt { X EmitDef (def_ruleset, (struct he *) NULL, X ListAppend ($4, $6, "\t"), (char *) NULL); X free ($4); X free ($6); X } X | ruledefs ASM LPAREN SCONST RPAREN SEMI { X printf("%s\n",$4); X } X | error SEMI { X yyerrok; X } X ; X Xmatchaddr : /* empty */ { X $$ = NULL; X } X | matchaddr matchtok { X $$ = ListAppend ($1, $2, (char *) NULL); X free ($1); X } X | error { X $$ = NULL; X } X ; X Xmatchtok : IDENT { X $$ = GetField ($1); X } X | anychar { X *Cbuf = $1; X $$ = ListAppend (Cbuf, (char *) NULL, (char *) NULL); X } X | mval { X $$ = MacScan ($1); X } X | DOLLAR IDENT { X Mbuf[1] = MakeMac ($2, ID_MACRO); X $$ = ListAppend (Mbuf, (char *) NULL, (char *) NULL); X } X | YPALIAS LPAREN matchtok RPAREN { X $$ = ListAppend("${",$3,(char *) NULL); X/* free ($3); */ X } X | YPPASSWD LPAREN matchtok RPAREN { X $$ = ListAppend("$\"",$3,(char *) NULL); X } X | RESOLVED LPAREN matchtok RPAREN { X $$ = ListAppend("$#",$3,(char *) NULL); X } X ; X Xactionstmt : action LPAREN rwaddr RPAREN SEMI { X $$ = ListAppend ($1, $3, (char *) NULL); X free ($3); X } X | RESOLVE LPAREN resolution RPAREN SEMI { X $$ = $3; X } X | error SEMI { X $$ = NULL; X yyerrok; X } X ; X Xaction : RETRY { X $$ = NULL; X } X | NEXT { X $$ = "$:"; X } X | RETURN { X $$ = "$@"; X } X ; X Xrwaddr : /* empty */ { X $$ = NULL; X } X | rwaddr rwtok { X $$ = ListAppend ($1, $2, (char *) NULL); X free ($1); X } X | rwaddr IDENT LPAREN rwaddr RPAREN { X $$ = ListAppend ($1, (Tsb = MakeRSCall ($2, $4)), (char *) NULL); X free ($1); X free ($4); X free (Tsb); X } X | error { X $$ = NULL; X } X ; X Xrwtok : anychar { X *Cbuf = $1; X $$ = ListAppend (Cbuf, (char *) NULL, (char *) NULL); X } X | mval { X $$ = MacScan ($1); X } X | cantok { X $$ = $1; X } X | ALIAS LPAREN reftok RPAREN { X $$ = ListAppend("$(@", $3, "$:$)"); X } X | ALIAS LPAREN reftok DEFAULT LPAREN rwaddr RPAREN RPAREN { X $$ = ListAppend(Tsb = X ListAppend ( "$(@", X $3, X (char *)NULL), X Tsb1 = ListAppend("$:", $6, "$)" ), X (char *) NULL); X free (Tsb); X free (Tsb1); X free ($3); X free ($6); X } X | reftok { X $$ = $1; X } X | ifcon { X $$ = $1; X } X | YPMAP LPAREN IDENT COMMA rwaddr RPAREN { X *Cbuf = MakeMac ($3, ID_MACRO); X $$ = ListAppend(Tsb = ListAppend ("${", (char *)Cbuf, (char *)NULL), X Tsb1 = ListAppend ($5, "$}", (char *) NULL), X (char *) NULL); X free (Tsb); X free (Tsb1); X free ($5); X } X X | PROGRAM LPAREN IDENT COMMA rwaddr RPAREN { X *Cbuf = MakeMac ($3, ID_MACRO); X $$ = ListAppend(Tsb = ListAppend ("$<", (char *)Cbuf, (char *)NULL), X Tsb1 = ListAppend ($5, "", (char *) NULL), X (char *) NULL); X free (Tsb); X free (Tsb1); X free ($5); X } X X | action LPAREN rwaddr RPAREN { X $$ = ListAppend ($1, $3, (char *) NULL); X free ($3); X } X ; X X Xcantok : CANON LPAREN canval RPAREN { X $$ = Bracket ($3, TRUE); X free ($3); X } X X ; Xcanval : canvaltok { X $$ = $1; X } X | canval canvaltok { X $$ = ListAppend ($1, $2, (char *) NULL); X free ($1); X free ($2); X } X ; X Xcanvaltok : IDENT { X $$ = ListAppend ($1->psb, (char *) NULL, (char *) NULL); X RemoveSymbol ($1); X } X | SCONST { X $$ = ListAppend (MacScan ($1), (char *) NULL, (char *) NULL); X free ($1); X } X | NEXT LPAREN RPAREN { /* I Used next earlier, but now use default - because it is clearer syntax */ X $$ = "$:"; X } X | NEXT LPAREN canval RPAREN { X $$ = ListAppend("$:", $3, (char *)NULL); X } X | DEFAULT LPAREN RPAREN { X $$ = "$:"; X } X | DEFAULT LPAREN canval RPAREN { X $$ = ListAppend("$:", $3, (char *)NULL); X } X | reftok { X $$ = $1; X } X | SEPCHAR { X *Cbuf = $1; X $$ = ListAppend (Cbuf, (char *) NULL, (char *) NULL); X } X | HOSTNUM LPAREN reftok RPAREN { X $$ = Bracket ($3, FALSE); X free ($3); X } X ; X Xreftok : DOLLAR IDENT { X Mbuf[1] = MakeMac ($2, ID_MACRO); X $$ = ListAppend (Mbuf, (char *) NULL, (char *) NULL); X } X | DOLLAR ICONST { X $$ = ListAppend (MakePosTok ($2), (char *) NULL, (char *) NULL); X } X | EVAL LPAREN IDENT RPAREN { X *Cbuf = MakeMac ($3, ID_MACRO); X $$ = ListAppend("$&", (char *)Cbuf, (char *)NULL); X } X ; X Xanychar : SEPCHAR { X $$ = $1; X } X | COLON { X $$ = ':'; X } X | STAR { X $$ = '*'; X } X | SEMI { X $$ = ';'; X } X | LBRACE { X $$ = '{'; X } X | RBRACE { X $$ = '}'; X } X | COMMA { X $$ = ','; X } X | SLASH { X $$ = '/'; X } X | ASGN { X $$ = '='; X } X ; X Xresolution : mailerspec COMMA route { X $$ = ListAppend ($1, $3, (char *) NULL); X free ($1); X free ($3); X } X | mailerspec { X $$ = $1; X } X | error { X $$ = NULL; X } X ; X Xmailerspec : MAILER LPAREN rword RPAREN { X $$ = ListAppend ("$#", $3, (char *) NULL); X } X ; X Xroute : HOST LPAREN hword RPAREN COMMA userspec { X $$ = ListAppend (Tsb = ListAppend ("$@", $3, (char *) NULL), X $6, (char *) NULL); X free (Tsb); X X X free ($6); X } X | userspec { X $$ = $1; X } X ; X Xhword : hostid { X $$ = $1; X } X | HOSTNUM LPAREN reftok RPAREN { X $$ = Bracket ($3, FALSE); X free ($3); X } X ; X Xhostid : /* empty */ { X $$ = NULL; X } X | hostid IDENT { X $$ = ListAppend ($1, $2->psb, (char *) NULL); X RemoveSymbol ($2); X free ($1); X } X | hostid rwtok { X $$ = ListAppend ($1, $2, (char *) NULL); X free ($1); X } X ; X Xuserspec : USER LPAREN rwaddr RPAREN { X $$ = ListAppend ("$:", $3, (char *) NULL); X free ($3); X } X ; X Xrword : IDENT { X $$ = CheckMailer ($1); X } X | reftok { X $$ = $1; X } X ; X Xfdefs : /* empty */ X | fdefs IDENT idlist COLON ftype SEMI { X AssignType (ListAppend ($2->psb, $3, " "), $5); X free ($3); X } X | error SEMI { X yyerrok; X } X ; X Xidlist : /* empty */ { X $$ = NULL; X } X | idlist COMMA IDENT { X $$ = ListAppend ($1, $3->psb, " "); X free ($1); X } X ; X Xftype : MATCH LPAREN ICONST RPAREN cdef { X $$ = ListAppend (MakeField ($3, $5, FALSE, FALSE), X (char *) NULL, (char *) NULL); X } X | MATCH LPAREN ICONST RPAREN MAP IDENT { X $$ = ListAppend (MakeField ($3, $6, FALSE, TRUE), X (char *) NULL, (char *) NULL); X } X | MATCH HOST { X $$ = ListAppend ("$%y", X (char *) NULL, (char *) NULL); X } X | MATCH LPAREN ICONST STAR RPAREN { X $$ = ListAppend (MakeField ($3, (struct he *) NULL, TRUE, FALSE), X (char *) NULL, (char *) NULL); X } X | error { X $$ = NULL; X } X ; X Xcdef : /* empty */ { X $$ = NULL; X } X | IN IDENT { X $$ = $2; X } X ; END_OF_src/parser.y if test 21605 -ne `wc -c