%parse-param { void* scanner }
%lex-param { void* scanner }
%defines "parser.h"
%output "parser.c"
%locations
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parser.h"
#define TRACING 1
#ifdef TRACING
#define TRACE(_p) printf _p
#else
#define TRACE(_p)
#endif
//#define YYERROR_VERBOSE 1
//#define YYPARSE_PARAM scanner /* the same as default */
//#define YYLEX_PARAM scanner /* the same as default */
/* int yyerror(void*, const char*); */
int yyerror(YYLTYPE *, void*, const char*);
%}
%language "c"
%pure-parser
%union
{
char *string;
int integer;
};
%token <string> TIMESTAMP QUEUEID EMAIL IP4 NETNAME NUM
%token <string> SYMB_IN SYMB_OUT SYMB_COMPL
%token <string> DELIM NL
%token <string> LB RB LSB RSB LA RA
%token <string> COL SCOL AL
%token <string> SYMB_HELO HELO_NAME HELO_IPADDR
%token <string> SYMB_ROUTER SYMB_TRANSP
%token <string> SYMB_PROTO PROTO
%token <string> SYMB_IFACE
%token <string> SYMB_CIPH
%token <string> SYMB_CERTV
%token <string> SYMB_SIZE
%token <string> SYMB_MESID
%token <string> SYMB_FROM
%token <string> SYMB_FROM2 SYMB_FOR2
%token <string> SYMB_DNAME DN
%token <string> SYMB_CONF CONF
%token <string> SYMB_QT
%token <string> SYMB_AUTH
%token <string> SYMB_USER
%start record
%%
record:
NL
| in some
| out some
| compl
;
out:
TIMESTAMP DELIM QUEUEID DELIM SYMB_OUT DELIM EMAIL DELIM LB EMAIL RB DELIM LA EMAIL RA DELIM {
TRACE((" [TIMESTAMP:%s]\n", $1));
TRACE((" [QUEUEID:%s]\n", $3));
TRACE((" [OUTPUT]\n"));
TRACE((" [TO_ORIG:%s]\n", $7));
TRACE((" [TO_REAL:%s]\n", $9));
TRACE((" [TO_REAL2:%s]\n", $14));
}
/* a@b.com <abc> */
| TIMESTAMP DELIM QUEUEID DELIM SYMB_OUT DELIM EMAIL DELIM LA NETNAME RA DELIM {
TRACE((" [TIMESTAMP:%s]\n", $1));
TRACE((" [QUEUEID:%s]\n", $3));
TRACE((" [OUTPUT]\n"));
TRACE((" [USERNAME:%s]\n", $8));
TRACE((" [TO:%s]\n", $10));
}
/* abc <a@b.com> */
| TIMESTAMP DELIM QUEUEID DELIM SYMB_OUT DELIM NETNAME DELIM LA EMAIL RA DELIM {
TRACE((" [TIMESTAMP:%s]\n", $1));
TRACE((" [QUEUEID:%s]\n", $3));
TRACE((" [OUTPUT]\n"));
TRACE((" [USERNAME:%s]\n", $8));
TRACE((" [TO:%s]\n", $10));
}
/* => manager_suppliers@center.lazurit.com (kursk_buh@kur.lazurit.com) <kursk_buh@kur.lazurit.com> */
| TIMESTAMP DELIM QUEUEID DELIM SYMB_OUT DELIM LA EMAIL RA DELIM {
TRACE((" [TIMESTAMP:%s]\n", $1));
TRACE((" [QUEUEID:%s]\n", $3));
TRACE((" [OUTPUT]\n"));
TRACE((" [TO:%s]\n", $7));
}
/* a@b.com */
| TIMESTAMP DELIM QUEUEID DELIM SYMB_OUT DELIM EMAIL DELIM {
TRACE((" [TIMESTAMP:%s]\n", $1));
TRACE((" [QUEUEID:%s]\n", $3));
TRACE((" [OUTPUT]\n"));
TRACE((" [TO:%s]\n", $7));
}
;
in:
TIMESTAMP DELIM QUEUEID DELIM SYMB_IN DELIM EMAIL DELIM {
TRACE((" [TIMESTAMP:%s]\n", $1));
TRACE((" [QUEUEID:%s]\n", $3));
TRACE((" [INPUT]\n"));
TRACE((" [FROM:%s]\n", $7));
}
| TIMESTAMP DELIM QUEUEID DELIM SYMB_IN DELIM EMAIL LA NETNAME RA DELIM {
TRACE((" [TIMESTAMP:%s]\n", $1));
TRACE((" [QUEUEID:%s]\n", $3));
TRACE((" [INPUT]\n"));
TRACE((" [FROM:%s]\n", $7));
TRACE((" [FROM_REDIR:%s]\n", $9));
}
| TIMESTAMP DELIM QUEUEID DELIM SYMB_IN DELIM EMAIL LA EMAIL RA DELIM {
TRACE((" [TIMESTAMP:%s]\n", $1));
TRACE((" [QUEUEID:%s]\n", $3));
TRACE((" [INPUT]\n"));
TRACE((" [FROM:%s]\n", $7));
TRACE((" [FROM_REDIR:%s]\n", $9));
}
;
compl:
TIMESTAMP DELIM QUEUEID DELIM SYMB_COMPL NL {
TRACE((" [QUEUEID:%s]\n", $3));
TRACE((" [COMPL]\n"));
}
| TIMESTAMP DELIM QUEUEID DELIM SYMB_COMPL DELIM qt NL {
TRACE((" [QUEUEID:%s]\n", $3));
TRACE((" [COMPL]\n"));
}
;
qt:
SYMB_QT NETNAME {
TRACE((" [QT:%s]\n", $2));
}
;
some:
exp DELIM some
| exp some
| exp NL
| exp
| NL
;
exp:
/* empty */
| helo
| proto
| auth
| iface
| ciph
| certv
| size
| mesid
| from
| from2
| router
| trans
| dname
| conf
| user
;
helo:
SYMB_HELO LB NETNAME RB DELIM LSB IP4 RSB {
TRACE((" [HELO:%s]\n", $3));
TRACE((" [IP:%s]\n", $7));
}
| SYMB_HELO NETNAME DELIM LSB IP4 RSB {
TRACE((" [HELO:%s]\n", $2));
TRACE((" [IP:%s]\n", $5));
}
| SYMB_HELO LB LSB IP4 RSB RB DELIM LSB IP4 RSB {
TRACE((" [HELO:%s]\n", $4));
TRACE((" [IP:%s]\n", $9));
}
/* for strange hello H=mx1.lazurit.com (LAZURIT-SMTP-IN) [xxx.xxx.xxx.xxx] */
| SYMB_HELO NETNAME DELIM LB NETNAME RB DELIM LSB IP4 RSB {
TRACE((" [HELO:%s]\n", $2));
TRACE((" [IP:%s]\n", $9));
}
/* output "hello" */
| SYMB_HELO IP4 DELIM LSB IP4 RSB {
TRACE((" [HOST_IPADDR:%s]\n", $2));
TRACE((" [OUT_IP:%s]\n", $5));
}
;
proto:
SYMB_PROTO PROTO {
TRACE((" [PROTO:%s]\n", $2));
}
| SYMB_PROTO LA EMAIL RA {
TRACE((" [RETURN_PATH:%s]\n", $3));
}
;
auth:
SYMB_AUTH NETNAME COL EMAIL {
TRACE((" [AUTH_PROTO:%s]\n", $2));
TRACE((" [AUTH_NAME:%s]\n", $4));
}
| SYMB_AUTH NETNAME COL NETNAME {
TRACE((" [AUTH_PROTO:%s]\n", $2));
TRACE((" [AUTH_NAME:%s]\n", $4));
}
;
iface:
SYMB_IFACE LSB IP4 RSB COL NUM {
TRACE((" [IFACE:%s]\n", $3));
TRACE((" [IF_PORT:%s]\n", $6));
}
| SYMB_IFACE LSB IP4 RSB {
TRACE((" [IFACE:%s]\n", $3));
}
;
ciph:
SYMB_CIPH NETNAME COL NETNAME COL NUM {
TRACE((" [CIPHER:%s:%s:%s]\n", $2, $4, $6));
}
;
certv:
SYMB_CERTV NETNAME {
TRACE((" [CERTV:%s]\n", $2));
}
;
size:
SYMB_SIZE NUM {
TRACE((" [SIZE:%s]\n", $2));
}
;
mesid:
SYMB_MESID EMAIL {
TRACE((" [MESID:%s]\n", $2));
}
| SYMB_MESID NETNAME {
TRACE((" [MESID:%s]\n", $2));
}
| SYMB_MESID NETNAME AL NETNAME {
TRACE((" [MESID:%s@%s]\n", $2, $4));
}
;
from:
SYMB_FROM LA EMAIL RA {
TRACE((" [FROM:%s]\n", $3));
}
;
from2:
SYMB_FROM2 LA EMAIL RA DELIM SYMB_FOR2 email_list {
TRACE((" [FROM2:%s]\n", $3));
/* TRACE((" [FOR2:%s]\n", $7)); */
}
| SYMB_FROM2 EMAIL DELIM SYMB_FOR2 email_list {
TRACE((" [FROM2:%s]\n", $3));
/* TRACE((" [FOR2:%s]\n", $5)); */
}
;
email_list:
EMAIL DELIM email_list {
TRACE((" [FOR2:%s]\n", $1));
}
| EMAIL {
TRACE((" [FOR2:%s]\n", $1));
}
| NETNAME DELIM email_list {
TRACE((" [FOR2:%s]\n", $1));
}
| NETNAME {
TRACE((" [FOR2:%s]\n", $1));
}
;
router:
SYMB_ROUTER NETNAME {
TRACE((" [ROUTER:%s]\n", $2));
}
/* return mail */
| SYMB_ROUTER QUEUEID {
TRACE((" [RETURN:%s]\n", $2));
}
;
trans:
SYMB_TRANSP NETNAME {
TRACE((" [TRANSPORT:%s]\n", $2));
}
;
dname:
SYMB_DNAME DN {
TRACE((" [DNAME:%s]\n", $2));
}
;
conf:
SYMB_CONF CONF {
TRACE((" [CONFIRM:%s]\n", $2));
}
;
user:
SYMB_USER NETNAME {
TRACE((" [USER:%s]\n", $2));
}
;
%%
/*
some: elem
| some DELIM elem
;
*/
int yyerror(YYLTYPE *location, void* scanner, const char* msg) {
(void)location;
(void)scanner;
// TRACE(("%s\n",msg));
return 0;
}
/* EOF */