OSSP CVS Repository

ossp - ossp-pkg/l2/l2_spec_parse.y 1.1
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/l2/l2_spec_parse.y 1.1
%{
/*
**  L2 - OSSP Logging Library
**  Copyright (c) 2001 The OSSP Project (http://www.ossp.org/)
**  Copyright (c) 2001 Cable & Wireless Deutschland (http://www.cw.com/de/)
**
**  This file is part of OSSP L2, a flexible logging library which
**  can be found at http://www.ossp.org/pkg/l2/.
**
**  Permission to use, copy, modify, and distribute this software for
**  any purpose with or without fee is hereby granted, provided that
**  the above copyright notice and this permission notice appear in all
**  copies.
**
**  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
**  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
**  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
**  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
**  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
**  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
**  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
**  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
**  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
**  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
**  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
**  SUCH DAMAGE.
**
**  l2_spec_parse.y: GNU Bison (Yacc-style) parser specification
**
**  ATTENTION: This requires GNU Bison 1.30 or newer!
*/

#include "l2.h"      /* for l2_xxx() */
#include "l2_p.h"    /* for l2_channel_t and l2_env_t internals */
#include "l2_spec.h" /* for l2_spec_ctx_t */

/* make sure yyparse() accepts a context pointer and
   passes through its inlined scanner context to yylex() */
#define CTX           ((l2_spec_ctx_t *)ctx)
#define YYPARSE_PARAM ctx
#define YYLEX_PARAM   CTX->yyscan

/* provide an explicit prototype for the yylex() function */
extern int yylex(/*YYSTYPE*/ void *lvalp, 
                 /*YYLTYPE*/ void *llocp, l2_spec_ctx_t *ctx);

/* generate verbose error messages and remember them inside the context */
#undef  yyerror
#define yyerror(msg) \
    do { \
        l2_env_errorinfo(CTX->env, L2_ERR_ARG, "%s", msg); \
        CTX->rv = L2_ERR_ARG; \
    } while (0)
#define YYERROR_VERBOSE

#define YYDEBUG 1
%}

%pure_parser
%locations
%defines

%union {
    char         *cpValue;
    l2_channel_t *chChannel;
    unsigned int  nLevels;
}

%type  <chChannel> stream
%type  <chChannel> streams
%type  <chChannel> channel
%type  <chChannel> channel_spec
%type  <nLevels>   channel_mask
%type  <nLevels>   channel_levels

%token <cpValue>   T_ID
%token <cpValue>   T_STRING

%token             T_OP_ARROW
%left              T_OP_ARROW

%%

root           : stream
                 { CTX->ch = $1; }
               ; 

stream         : channel
                 { 
                     $$ = $1; 
                 }
               | channel T_OP_ARROW stream
                 { 
                     $$ = $1; 
                     if ((CTX->rv = l2_channel_link($1, L2_LINK_CHILD, $3, NULL)) != L2_OK) {
                         l2_env_errorinfo(CTX->env, CTX->rv, 
                                          "unable to link parent '%s' with child '%s'", 
                                          $1->handler.name, $3->handler.name);
                         YYERROR;
                     }
                 }
               | channel T_OP_ARROW '{' streams '}'
                 { 
                     $$ = $1; 
                     if ((CTX->rv = l2_channel_link($1, L2_LINK_CHILD, $4, NULL)) != L2_OK) {
                         l2_env_errorinfo(CTX->env, CTX->rv, 
                                          "unable to link parent '%s' with child list",
                                          $1->handler.name);
                         YYERROR;
                     }
                 }
               ;

streams        : stream 
                 { $$ = $1; }
               | stream ';' streams
                 { $$ = $1; l2_channel_link($1, L2_LINK_SIBLING, $3, NULL); }
               ;

channel        : channel_mask '/' channel_mask ':' channel_spec
                 { $$ = $5; l2_channel_levels($5, $1, $3); }
               | channel_mask ':' channel_spec
                 { $$ = $3; l2_channel_levels($3, $1, L2_LEVEL_NONE); }
               | channel_spec
                 { $$ = $1; }
               ;

channel_mask   : T_ID
                 { 
                     unsigned int levelmask;
                     if ((CTX->rv = l2_util_s2l($1, strlen($1), ',', &levelmask)) != L2_OK) {
                         l2_env_errorinfo(CTX->env, CTX->rv, "invalid level '%s'", $1);
                         YYERROR;
                     }
                     $$ = L2_LEVEL_UPTO(levelmask);
                 }
               | '(' channel_levels ')'
                 { $$ = $2; }
               ;

channel_levels : T_ID
                 { 
                     unsigned int levelmask;
                     if ((CTX->rv = l2_util_s2l($1, strlen($1), ',', &levelmask)) != L2_OK) {
                         l2_env_errorinfo(CTX->env, CTX->rv, "invalid level '%s'", $1);
                         YYERROR;
                     }
                     $$ = levelmask;
                 }
               | T_ID '|' channel_levels
                 { 
                     unsigned int levelmask;
                     if ((CTX->rv = l2_util_s2l($1, strlen($1), ',', &levelmask)) != L2_OK) {
                         l2_env_errorinfo(CTX->env, CTX->rv, "invalid level '%s'", $1);
                         YYERROR;
                     }
                     $$ = levelmask | $3; 
                 }
               ;

channel_spec   : T_ID
                 { 
                     l2_channel_t *ch;
                     if ((CTX->rv = l2_channel_create(&ch, CTX->env, $1)) != L2_OK) {
                         l2_env_errorinfo(CTX->env, CTX->rv, "failed to create channel '%s'", $1);
                         YYERROR;
                     }
                     $$ = ch;
                     /* provide channel to channel_param rule below
                        because it does not know where on the token stack
                        our $$ is because it is a sub-rule of the recursive
                        channel_param_list rule and hence cannot use
                        "$<chChannel>-n". */
                     CTX->chTmp = ch; 
                 }
                 channel_params
                 { 
                     $$ = $<chChannel>2;
                     CTX->chTmp = NULL;
                 }
               ;

channel_params : /* empty */
               | '(' channel_param_list ')'
               ;

channel_param_list : /* empty */
                   | channel_param
                   | channel_param ',' channel_param_list
                   ;
        
channel_param  : T_ID '=' T_STRING
                 { 
                     if ((CTX->rv = l2_channel_configure(CTX->chTmp, "%s=\"%s\"", $1, $3)) != L2_OK) {
                         l2_env_errorinfo(CTX->env, CTX->rv, "failed to configure channel with '%s=\"%s\"'", $1, $3);
                         YYERROR;
                     }
                 }
               ;
 
%%


CVSTrac 2.0.1