User Tools

Site Tools


Bison/Lex sample

parser.y
%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 */
lexer.l
%{
/* $Id: lexer.l,v 1.4 2016/08/14 22:43:12 root Exp root $ */
 
#include <stdio.h>
#include "parser.h"
 
//#define TRACING 
#ifdef TRACING
#define TRACE(_p)	printf _p
#else
#define TRACE(_p)
#endif
 
 
static char* _newstring(char* in_string);
%}
 
%option 8bit reentrant
%option bison-bridge bison-locations
%option outfile="lexer.c" header-file="lexer.h" 
%option nomain nounput noyy_top_state noyywrap nowarn
 
DELIM		[ ]+
NL		[\n]+
NUM		[0-9]+
IP4		[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
 
TIMESTAMP	[0-9]{4}-[0-9]{2}-[0-9]{2}[ ][0-9]{2}:[0-9]{2}:[0-9]{2}
QUEUEID		[a-zA-Z0-9]{6}-[a-zA-Z0-9]{6}-[a-zA-Z0-9]{2}
EMAIL		[A-Z0-9a-z_][A-Z0-9a-z._\-+=]+@[A-Za-z0-9\.\-]+\.[A-Za-z]{2,16}|<>
NETNAME		[A-Za-z0-9._\-]+
 
DN		[A-Z0-9a-z._\-(),\*\/= ]+
CONF		[A-Z0-9a-z._\-(),\*\/=+:\;\[\] ]+
PROTO		smtp|esmtp|esmtps|esmtpsa|esmtpa|local
COMPL		Completed
 
%x DNAME
%x CONFIRM
 
%%
 
{TIMESTAMP}			{ BEGIN(INITIAL); yyget_lval(yyscanner)->string = _newstring(yytext); return TIMESTAMP; }
{QUEUEID}			{ yyget_lval(yyscanner)->string = _newstring(yytext); return QUEUEID; }
{COMPL}				{ return SYMB_COMPL; }
{PROTO}				{ yyget_lval(yyscanner)->string = _newstring(yytext); 
				  TRACE(("<PROTO:%s>", yytext)); 
				  return PROTO;
				}
{IP4}				{ yyget_lval(yyscanner)->string = _newstring(yytext); return IP4; }
{EMAIL}				{ yyget_lval(yyscanner)->string = _newstring(yytext); 
				  TRACE((" <EMAIL:%s>", yytext));
				  return EMAIL; }
{NUM}				{ yyget_lval(yyscanner)->string = _newstring(yytext); return NUM; }
{NETNAME}			{ yyget_lval(yyscanner)->string = _newstring(yytext); 
				  TRACE((" <NETNAME:%s>", yytext));
				  return NETNAME; 
				}
 
"DN=\""				{ BEGIN(DNAME); return SYMB_DNAME; }
<DNAME>{DN}			{  yyget_lval(yyscanner)->string = _newstring(yytext); return DN; }
<DNAME>"\""			{ BEGIN(INITIAL); }
 
"C=\""				{ BEGIN(CONFIRM); return SYMB_CONF; }
<CONFIRM>{CONF}			{ yyget_lval(yyscanner)->string = _newstring(yytext);
				  TRACE((" <CONF:%s>", yytext));
				  return CONF; 
				}
<CONFIRM>"\""			{ TRACE((" <CONFIRM_END>")); BEGIN(INITIAL); }
 
" id="				{ return SYMB_MESID; }
"QT="				{ return SYMB_QT; }
"<="				{ return SYMB_IN; }
"=>"				{ return SYMB_OUT;}
"R="				{ return SYMB_ROUTER; }
"T="				{ return SYMB_TRANSP; }
"H="				{ return SYMB_HELO; }
"P="				{ return SYMB_PROTO; }
"I="				{ return SYMB_IFACE; }
"X="				{ return SYMB_CIPH; }
"CV="				{ return SYMB_CERTV; }
"S="				{ return SYMB_SIZE; }
"F="				{ return SYMB_FROM; }
"A="				{ return SYMB_AUTH; }
"U="				{ return SYMB_USER; }
"from "				{ return SYMB_FROM2; }
"for "				{ return SYMB_FOR2; }
 
"<"				{ return LA; }
">"				{ return RA; }
"["				{ return LSB; }
"]"				{ return RSB; }
"("				{ return LB; }
")"				{ return RB; }
":"				{ return COL; }
";"				{ return SCOL; }
"@"				{ return AL; }
 
{DELIM}				{ return DELIM; }
{NL}				{ return NL; }
 
.
 
%%
 
static char* _newstring(char* in_string) {
    char* out_string = (char*) malloc(strlen(in_string)+1);
    sprintf(out_string,"%s",in_string);
    return out_string;
}
/* EOF */